分类 其它 下的文章

前段时间给 StarRocks 的物化视图新增了一个
特性
,那也是我第一次接触 StarRocks,因为完全不熟悉这个数据库,所以很多东西都是从头开始了解概念。

为了能顺利的新增这个特性(具体内容可以见后文),我需要把整个物化视图的流程串联一遍,于是便有了这篇文章。

在开始之前简单了解下物化视图的基本概念:

image.png

简单来说,视图和 MySQL 这类传统数据库的概念类似,也是用于解决大量消耗性能的 SQL 的,可以提前将这些数据查询好然后放在一张单独的表中,这样再查询的时候性能消耗就比较低了。

刷新条件

为了保证视图数据的实时性,还需要在数据发生变化的时候能够及时刷新视图里的数据,目前有这几个地方会触发视图刷新:
image.png

  • 手动刷新视图,使用
    REFRESH MATERIALIZED VIEW order_mv;
    语句
  • 将视图设置为 active 状态:
    ALTER MATERIALIZED VIEW order_mv ACTIVE;
  • 基表数据发生变化时触发刷新。
    • image.png
  • truncate 基表时触发刷新:
    truncate table trunc_db.t1;
  • drop partition 时触发:
    ALTER TABLE <tbl_name> DROP PARTITION(S) p0, p1 [, ...];

这里的 truncate table 和 drop partition 目前的版本还存在 bug:当基表和物化视图不在一个数据库时不会触发自动刷新,目前已经修复了。

image.png

刷新流程

image.png

如图所示,当触发一次刷新之后主要就是需要计算出需要刷新的分区。

第一次触发刷新的时候是不会带上周期(比如时间范围),然后根据过滤计算出来的周期,默认情况下只会使用第一个周期(我们可以通过
partition_refresh_number
参数来调整单次刷新的分区数量)。

然后如果还有其余的周期,会将这些周期重新触发一次刷新任务(会带上刚才剩余的周期数据),这样进行递归执行。

通过日志会看到返回的分区数据。

新增优化参数

我们在使用物化视图的时候,碰到一个场景:

CREATE TABLE IF NOT EXISTS test.par_tbl1
(
    datekey DATETIME,
    k1      INT,
    item_id STRING,
    v2      INT
)PRIMARY KEY (`datekey`,`k1`)
 PARTITION BY date_trunc('day', `datekey`);

 CREATE TABLE IF NOT EXISTS test.par_tbl2
(
    datekey DATETIME,
    k1      INT,
    item_id STRING,
    v2      INT
)PRIMARY KEY (`datekey`,`k1`)
 PARTITION BY date_trunc('day', `datekey`);

 CREATE TABLE IF NOT EXISTS test.par_tbl3
(
    datekey DATETIME,
    k1      INT,
    item_id STRING,
    v2      INT
)
 PRIMARY KEY (`datekey`,`k1`);

但我们有三张基表,其中 1 和 2 都是分区表,但是 3 是非分区表。

此时基于他们新建了一个物化视图:

CREATE
MATERIALIZED VIEW test.mv_test
REFRESH ASYNC
PARTITION BY a_time
PROPERTIES (
"excluded_trigger_tables" = "par_tbl3"
)
AS
select date_trunc("day", a.datekey) as a_time, date_trunc("day", b.datekey) as b_time,date_trunc("day", c.datekey) as c_time
from test.par_tbl1 a
         left join test.par_tbl2 b on a.datekey = b.datekey and a.k1 = b.k1
         left join test.par_tbl3 c on a.k1 = c.k1;

当我同时更新了分区表和非分区表的数据时:

UPDATE `par_tbl1` SET `v2` = 2 WHERE `datekey` = '2024-08-05 01:00:00' AND `k1` = 3;
UPDATE `par_tbl3` SET `item_id` = '3' WHERE `datekey` = '2024-10-01 01:00:00' AND `k1` = 3;

预期的结果是只有
par_tbl1
表里修改的数据会被同步到视图(
"excluded_trigger_tables" = "par_tbl3"
已经被设置为不会触发视图刷新),但实际情况是
par_tbl1

par_tbl2
表里所有的数据都会被刷新到物化视图中。

我们可以使用这个 SQL 查询无刷视图任务的运行状态:

SELECT * FROM information_schema.task_runs order by create_time desc;

这样就会造成资源损耗,如果这两张基表的数据非常大,本次刷新会非常耗时。

所以我们的需求是在这样的场景下也只刷新修改的数据。

因此我们在新建物化视图的时候新增了一个参数:

CREATE
MATERIALIZED VIEW test.mv_test
REFRESH ASYNC
PARTITION BY a_time
PROPERTIES (
"excluded_trigger_tables" = "par_tbl3",
"excluded_refresh_tables"="par_tbl3"
)
AS
select date_trunc("day", a.datekey) as a_time, date_trunc("day", b.datekey) as b_time,date_trunc("day", c.datekey) as c_time
from test.par_tbl1 a
         left join test.par_tbl2 b on a.datekey = b.datekey and a.k1 = b.k1
         left join test.par_tbl3 c on a.k1 = c.k1;

这样当在刷新数据的时候,会判断
excluded_refresh_tables
配置的表是否有发生数据变化,如果有的话则不能将当前计算出来的分区(1,2 两张表的全量数据)全部刷新,而是继续求一个交集,只计算基表发生变化的数据。

这样就可以避免 par_tbl1、par_tbl2 的数据全量刷新,而只刷新修改的数据。

这样的场景通常是在关联的基表中有一张字典表,通常数据量不大,所以也不需要分区的场景。

这样在创建物化视图的时候就可以使用这两个参数
excluded_trigger_tables,excluded_refresh_tables
将它排除掉了。

整体的刷新逻辑并不复杂,主要就是几个不同的刷新入口以及刷新过程中计算分区的逻辑。

参考链接:

前一篇:《人工智能模型训练技术:随机失活,丢弃法,Dropout》

序言:
让人工智能模型变得更“聪明”的方法之一,就是减少“过拟合”(读死书)的问题,从而提升模型的“泛化能力”,也就是它面对新问题时的适应能力。在前面,我们讲解了最常用的“随机丢弃”法,本节将带大家了解另一种重要的方法——“正则化”。

那么,正则化主要做什么呢?用现实生活中的案例来比喻,正则化的作用就像学校里的老师,目的是引导学生往正确的方向走,而不是死记硬背课本,或者因为某些考试题目熟悉而侥幸得高分。老师会通过约束学生的行为,比如规范学习方法、减少偏科等,让学生学到的是通用的规律和解决问题的能力,而不是偏离正常轨道或者学到无用的信息。同样,正则化在人工智能中通过约束模型的权重等机制,帮助模型避免过拟合,提升它面对新数据的表现能力。

使用正则化

正则化是一种通过减少权重的极端化(polarization)来防止过拟合的技术。如果某些神经元的权重过大,正则化会对它们进行“惩罚”。总体来说,正则化有两种主要类型:L1 和 L2。

• L1 正则化 通常被称为套索正则化(lasso,最小绝对收缩和选择算子)。它的作用是帮助我们忽略权重为零或接近零的值,当计算层的结果时,这些权重会被有效地“抛弃”。

• L2 正则化 通常被称为岭回归(ridge regression),因为它通过计算权重的平方,将非零值和零值(或接近零的值)之间的差异放大,从而产生一种“山脊效应”。

这两种方法还可以结合起来,形成一种叫做弹性正则化(elastic regularization)的技术。

对于像我们当前这种自然语言处理问题,L2 正则化 是最常用的。你可以通过 kernel_regularizer 属性将它添加到 Dense 层中,这个属性接受一个浮点值作为正则化因子。这是另一个可以用来优化模型的超参数,值得尝试!

以下是一个示例代码:

model = tf.keras.Sequential([

tf.keras.layers.Embedding(vocab_size, embedding_dim),

tf.keras.layers.GlobalAveragePooling1D(),

tf.keras.layers.Dense(8, activation='relu',

kernel_regularizer=tf.keras.regularizers.l2(0.01)),

tf.keras.layers.Dense(1, activation='sigmoid')

])

在像这样的简单模型中,添加正则化的影响并不会特别大,但它确实让训练损失和验证损失的曲线变得更加平滑了一些。在这种场景下可能有点“用力过猛”,但和 Dropout 一样,了解如何使用正则化来防止模型过度专注(overspecialized)是一个非常重要的技能。

其他优化的考虑

虽然我们已经通过之前的修改得到了一个过拟合更少、性能更好的模型,但还有其他超参数可以进行实验。例如,我们之前将最大句子长度设置为 100,但这个值纯粹是随意选的,可能并不是最佳值。一个好主意是探索语料库,看看有没有更合适的句子长度。

以下是一个代码片段,用来检查句子的长度并将它们从短到长排序后绘制成图表:

xs = []

ys = []

current_item = 1

for item in sentences:

xs.append(current_item)

current_item += 1

ys.append(len(item))

newys = sorted(ys)

import matplotlib.pyplot as plt

plt.plot(xs, newys)

plt.show()

图 6-16 展示了这个代码的结果。

图 6-16:探索句子长度

在整个 26,000 多条语料中,长度达到 100 个单词或以上的句子不到 200 条。所以,把句子长度的最大值设为 100,就会引入很多不必要的填充(padding),这会影响模型的性能。如果把最大长度减少到 85,仍然可以覆盖 26,000 条语料中的 99% 以上,几乎不需要任何填充。

总结:
正则化也是为了让模型变聪明的一种方法,即增强模型的泛化能力。它的角色就像我们从小到大的老师,负责引导和规范我们的学习框架和方向。下一节我们将把通过各种方法优化后训练好的模型,用于实际应用——分类新闻中的句子并进行预测。

本文书接上回《
解决DDD最大难题-如何划分领域
》,关注公众号(老肖想当外语大佬)获取信息:

  1. 最新文章更新;

  2. DDD框架源码(.NET、Java双平台);

  3. 加群畅聊,建模分析、技术交流;

  4. 视频和直播在B站。

声明: 本文观点限定在重业务的软件系统研发场景下,其它场景不作为本文讨论的范围。

前言

1975 年《人月神话:软件项目管理之道》首次出版,揭示了一个被程序员奉为圣典的法则,认为增加开发者无法线性地缩短软件交付时间,其中的损耗巨大。时隔近50年,我的软件交付经验中却出现了打破这个法则的现象,我被这些现象深深地震撼,但当时却没有联想到“人月神话”,而最近在思考“如何为大家呈现我们实践DDD所获得的收益”时,灵光乍现,意识到实际上我们已经实现了通过增加人数来有效地缩短项目交付周期的能力,我意识到我们真的打破了“人月神话”。

还是那个故事

我在《
为了落地DDD,我是这样“PUA”大家的
》一文中,讲述了一支团队落地DDD的实践经历,这里有一个小插曲,在我们重构系统最艰难的时刻,也就是最复杂的订单模块整个生命周期时,我们的进度压力很大,团队期望能够进行渐进式交付,一块一块地交付测试,而订单的“创建-扣库存-支付成功”一整个逻辑又相互牵扯,需要完整实现才能提交测试,评估下来,如果这一块由一个开发者来开发,需要大约三天时间,而我们期望一天能够完成,于是我们本能地想到了方法:“加人”。但我们也很清楚,按照以往地经验,加人的损耗肯定是非常巨大的,三个开发者参与进来,一天能够完成也几乎是不可能的,但我们没有别的选择。

于是,我把三位开发者叫到会议室,按照我们的DDD工作流,花了近一个小时时间,确认了“领域模型”、“创建订单命令”、“订单创建成功事件”、“订单支付成功事件”、各个“事件处理器”逻辑、前端接口定义等设计方案,然后分工分别负责“命令处理器”、“事件处理器”、“前端接口”的开发工作。

令人惊奇的是,基于这样的分工,团队很快完成了各自的工作,并在当天下班前,团队完成了代码合并和联调,意外的进度给我们带来了一丝丝惊喜,但很快投入到了后续的工作中,并没有来得及深入思考。

而此后,团队的交付过程中,类似对于突发事件的应对,也多次复现了这样的现象,似乎我们的分工可以做到更细的颗粒度,使得团队能够通过增加人数的方式缩短需求的交付。

为什么可以这样

在我们团队重新审视这一现象时,我们可以看到:

  1. 我们将交付过程明确分为了“建模设计”和“代码编写”两个阶段,其中“代码编写”需要的能力是模式化、可复制的

  2. 我们的代码组织方式,非常有利于分工;

“建模设计”和“代码编写”

“建模设计”,是输入需求信息,输出方案的过程,是一个做决定的过程,这个过程,本质上是将“不确定性”尽可能转变为“确定性”的结论,需要需求方、决策者建立共识,做出设计结论,这个阶段无法通过加人来加速,但同时也不需要大量广泛的参与者,本质上是由“决策者”参与即可。

图片

一旦我们“建模设计方案”确定了,而“代码编写”要做的就是按照“模型设计”编写确定性的代码,这个过程本质上就是“做执行”,团队成员一旦适应了团队的代码风格和模式,基本不需要太多的思考,就可以写出“符合预期”的代码,因为这个“预期”已经被“建模设计”框定了。而且实践中我们发现,对于一个新人,通过不到一周的学习和模仿,就可以掌握这个能力。

图片

所以我们开发团队的整个流程就变成了“做决策”和“做执行”两件事,也是由“不确定性”到“确定性”的快速收敛的一个过程。

图片

代码风格的可协作性

我在《
DDD建模后写代码的正确姿势(Java、dotnet双平台)
》一文中为大家展示了我们的代码组织方式,我在视频《掌握这个模型你就能设计一切》(
https://www.bilibili.com/video/BV114421Q7vp)
中也介绍过业务系统中,最核心的就是“命令-事件”,系统的所有业务,都可以映射到这个模型中。用DDD+CQRS+Event Driven的组合,我们发现代码被一个个的“CommandHandler”、“EventHandler”拆分成一个个的独立的业务逻辑处理单元,这些单元的协作,在我们“建模设计”阶段已经确定下来,因此,开发者要做的就是完成这一个个填空,就完成了代码的编写,心智负担非常小。

图片

我们分工的最小颗粒度,就是这一个个的“CommandHandler”和“EventHandler”,这比传统的CRUD按模块分工的颗粒度要细致地多,也就意味着,我们团队可以更细粒度地调配人力,这其中的损耗却几乎可以忽略不记。

我们甚至规定,“
当你写代码不舒服时,大概率是建模设计出了问题
”,要求开发者反馈并由设计者及时修改迭代模型设计,尽可能地确保开发时,代码的
上下文能够获取到支撑实现逻辑单元目标的信息
,从而使得整个开发过程是丝滑的。

回到主题

在我们实践DDD的过程中,我们意识到,在“代码编写”环节,我们可以非常灵活地调配人力资源,哪怕是被临时调入项目的开发人员,也可以高效地按照设计完成代码的编写,这其中的损耗几乎可以忽略不记。

基于这样的情况,我们认为,一支研发团队,就可以实现一个建模设计师加上多个实现开发者这样的模型,而这个团队模型,我相信也是很多团队期望的但又很难把协作效率提升上来。

现在看来,我们的实践做到了,所以,我想,人月神话不再是神话。

交互类组件

Web
应用程序中至关重要,它们允许用户与应用进行实时互动,能够显著提升用户体验。

用户不再只是被动地接收信息,而是可以主动地输入数据、做出选择或触发事件,从而更加深入地参与到应用中来。

此外,对于某些复杂的任务或操作,
交互类组件
可以将其分解成一系列简单的步骤或选择,从而降低用户的认知负担和学习成本

。这使得用户能够更轻松地完成这些任务,提高应用的易用性。

Streamlit
中交互类组件有很多,本篇介绍其中最常用的几种,这也是
Web
页面中最常见到的几种组件。

  • st.text_input
    :允许用户输入文本,用于收集用户输入的字符串信息。
  • st.button
    :提供一个可点击的按钮,用户点击后触发特定操作或事件。
  • st.selectbox
    :显示下拉列表,让用户从预设选项中选择一个。
  • st.multiselect
    :提供下拉多选功能,允许用户从预设选项中选择多个。
  • st.radio
    :显示单选按钮组,让用户从多个选项中选择一个。
  • st.checkbox
    :提供复选框,让用户选择或取消选择特定选项。

1. 组件概述

1.1. st.text_input

用于输入普通文本或者密码,类似于HTML中的
<input type="text">

核心的参数有:

名称 类型 说明
label str 输入框前面的标签
key str 唯一标识此输入框的键,可用于在回调中引用
value str 输入框的初始值
type str 输入类型,可以是"default"(默认)或者"password"(密码)

1.2. st.button

提供一个按钮用来出发特定事件,类似于HTML中的
<button>

核心的参数有:

名称 类型 说明
label str 按钮上的文字
key str 唯一标识此按钮的键
help str 按钮旁边的帮助文本

1.3. st.selectbox

下拉选择框,类似于HTML中的
<select>

核心的参数有:

名称 类型 说明
label str 下拉框前面的标签
key str 唯一标识此下拉框的键
options list 下拉框中的选项列表
index int 初始选中项的索引

1.4. st.multiselect

可以多选的下拉选择框,类似于HTML中的
<select multiple>

核心的参数有:

名称 类型 说明
label str 多选框前面的标签
key str 唯一标识此多选框的键
options list 多选框中的选项列表
default list 默认选中的选项列表

1.5. st.radio

单选按钮组,类似于HTML中的
<input type="radio">

核心的参数有:

名称 类型 说明
label str 单选按钮组前面的标签
key str 唯一标识此单选按钮组的键
options list 单选按钮组中的选项列表
index int 初始选中项的索引

1.6. st.checkbox

复选框,类似于HTML中的
<input type="checkbox">

核心的参数有:

名称 类型 说明
label str 复选框旁边的标签
key str 唯一标识此复选框的键
value bool 复选框的初始状态(选中或未选中)

2. 组件使用示例

下面通过从实际场景中简化而来的示例,来看看如何使用
Streamlit
的交互类组件。

2.1. "用户偏好调查"示例

这个示例模拟了一个真实的用户调查场景,

通过
Streamlit
的交互式组件,用户可以轻松地输入和选择信息,并提交给应用进行处理和显示。

import streamlit as st

# 标题
st.title("用户偏好调查")

# 文本输入框:收集用户名
username = st.text_input("请输入您的姓名:")

# 下拉单选框:选择性别
gender = st.selectbox("请选择您的性别:", ["男", "女", "其他"])

# 下拉多选框:选择兴趣爱好
hobbies = st.multiselect(
    "请选择您的兴趣爱好:", ["阅读", "运动", "旅行", "音乐", "电影"]
)

# 单选按钮组:选择喜欢的颜色
favorite_color = st.radio("请选择您喜欢的颜色:", ["红色", "蓝色", "绿色", "黄色"])

# 复选框:是否同意接收推送
accept_push = st.checkbox("您是否同意接收推送消息?")

# 按钮:提交调查
if st.button("提交调查"):
    # 收集所有输入信息并显示
    user_info = {
        "姓名": username,
        "性别": gender,
        "兴趣爱好": ", ".join(hobbies),
        "喜欢的颜色": favorite_color,
        "是否同意接收推送": "是" if accept_push else "否",
    }

    st.subheader("您的调查信息如下:")
    st.write(user_info)

2.2. "数据分析项目仪表板"示例

这个示例模拟了一个数据分析项目的仪表板,

通过
Streamlit
的交互式组件,用户可以轻松地与数据进行交互,选择他们感兴趣的分析方式,并查看和下载分析结果。

import streamlit as st
import pandas as pd
import numpy as np

# 假设数据集
data = pd.DataFrame(
    {
        "日期": pd.date_range(start="2023-01-01", periods=100, freq="D"),
        "类别": np.random.choice(["A", "B", "C"], 100),
        "销售额": np.random.randint(100, 1000, 100),
        "利润": np.random.randint(10, 100, 100),
    }
)

# 标题
st.title("数据分析项目仪表板")

# 文本输入框:输入项目名称
project_name = st.text_input("请输入项目名称:")

# 下拉单选框:选择分析类别
analysis_category = st.selectbox("请选择分析类别:", data["类别"].unique())

# 下拉多选框:选择显示的列
display_columns = st.multiselect("请选择要显示的列:", data.columns)
selected_data = data[display_columns]

# 单选按钮组:选择汇总方式
agg = st.radio("请选择汇总方式:", ["总和", "平均值", "最大值", "最小值"])
agg_dict = {
    "总和": "sum",
    "平均值": "mean",
    "最大值": "max",
    "最小值": "min",
}

# 复选框:是否按类别汇总
group_by_category = st.checkbox("是否按类别汇总?")

# 按钮:执行分析
if st.button("执行分析"):
    # 根据用户选择进行分析
    if group_by_category:
        grouped_data = (
            selected_data.groupby("类别")
            .agg({col: agg_dict[agg] for col in selected_data.columns if col != "类别"})
            .reset_index()
        )
    else:
        grouped_data = (
            selected_data.agg({col: agg_dict[agg] for col in selected_data.columns})
            .to_frame()
            .T
        )

    # 显示分析结果
    st.subheader("分析结果:")
    st.dataframe(grouped_data)

3. 总结

总之,这些交互式组件使得用户可以通过文本输入、选择、勾选等方式与应用进行互动,从而根据用户需求动态地展示和分析数据。

它们极大地增强了应用的灵活性和用户体验,使得数据分析、数据可视化等任务变得更加直观和便捷。

如果你做过个人博客网站,那么一定对静态网站生成器不陌生。无论是 Ruby 语言的 Jekyll、Go 语言的 Hugo、还是基于 React 的 Gatsby,这些工具都有庞大的用户群体。对于喜欢的人来说,它们是无可替代的神器,而对于不喜欢的人,则可能难以“下咽”。正如俗话所说,“萝卜青菜,各有所爱”,没有最好用的工具,只有最适合自己的。

比如,上周热门的开源项目 zola,它的诞生就是因为作者不喜欢 Hugo 的模板引擎,同时为了追求更简洁的使用体验。他选择用 Rust 开发了 zola 这款静态网站生成器,提供独立的可执行文件和更简单易用的模版语言。同样备受关注的还有 dockur/macos,它可以让用户在 Docker 中体验 macOS 系统。用于备份 QQ 空间说说的 GetQzonehistory,虽看似简单,但凭借切中用户痛点和开箱即用的特点,让它在短时间内获得上千 Star 的关注。

  • 本文目录
    • 1. 热门开源项目
      • 1.1 Rust 的静态网站生成器:zola
      • 1.2 Linux 平台的 GDB 图形化增强工具:Seer
      • 1.3 在 Docker 中体验 macOS 系统:macos
      • 1.4 QQ 空间说说备份工具:GetQzonehistory
      • 1.5 利用家用设备打造低成本的 AI 集群:exo
    • 2. HelloGitHub 热评
      • 2.1 开源的网络钓鱼平台:Gophish
      • 2.2 Rust 驱动的 HTTP 压测工具:oha
    • 3. 结尾

1. 热门开源项目

1.1 Rust 的静态网站生成器:zola

主语言:Rust

Star:14k

周增长:200

该项目是用 Rust 语言编写的静态网站生成器,其方便的可执行文件使得安装过程简单快捷。它采用了更易于使用的 Tera 模版引擎,并提供了一体化的静态网站解决方案,内置全面的功能模块,包括内容管理、语法高亮、检查外部链接、快速预览、搜索和多语言等,适用于快速搭建技术博客、产品文档和公司官网等网站。

zola init my_site
zola check
zola serve
zola build

GitHub 地址→
github.com/getzola/zola

1.2 Linux 平台的 GDB 图形化增强工具:Seer

主语言:C++

Star:2.8k

周增长:600

这是一款专为 Linux 系统设计的工具,提供了 GDB 的图形化用户操作界面。它为 GNU 调试器 GDB 提供了友好的图形化界面,包括代码管理、变量/寄存器信息、断点管理等多个功能视图,支持变量跟踪、回放指令、内存、结构体和数组可视化等功能。

GitHub 地址→
github.com/epasveer/seer

1.3 在 Docker 中体验 macOS 系统:macos

主语言:Python

Star:8.3k

周增长:7k

该项目允许用户在 Docker 容器中运行 macOS 系统,实现在非苹果硬件上体验 macOS。它基于 Docker 和 KVM 的虚拟化技术,简化了 macOS 的安装过程。用户可以通过浏览器使用 macOS 系统,支持调整 CPU、内存和硬盘大小,并兼容从 macOS 11 到 macOS 15 的多个版本,适合在 Linux 和 Windows 环境中测试 macOS 应用。

GitHub 地址→
github.com/dockur/macos

1.4 QQ 空间说说备份工具:GetQzonehistory

主语言:Python

Star:5.7k

周增长:2.6k

这是一个用于获取个人 QQ 空间历史说说的工具。它通过模拟登录 QQ 空间,可以自动获取个人账号下所有发布过的说说,并导出成 Excel 文件。用户只需执行几个简单的步骤,即可轻松备份个人的所有历史说说。

GitHub 地址→
github.com/LibraHp/GetQzonehistory

1.5 利用家用设备打造低成本的 AI 集群:exo

主语言:Python

Star:14k

周增长:3k

该项目能够利用日常家用设备(如手机、笔记本电脑、台式机等)来搭建家庭 AI 集群。它通过整合现有的设备,无需昂贵硬件,即可构建一个低成本、可扩展的 GPU 计算集群,支持动态模型分区、自动发现设备、ChatGPT API、P2P 连接和多种推理引擎。

GitHub 地址→
github.com/exo-explore/exo

2. HelloGitHub 热评

在此章节中,我们将为大家介绍本周 HelloGitHub 网站上的热门开源项目,我们不仅希望您能从中收获开源神器和编程知识,更渴望“听”到您的声音。欢迎您与我们分享使用这些
开源项目的亲身体验和评价
,用最真实反馈为开源项目的作者注入动力。

2.1 开源的网络钓鱼平台:Gophish

主语言:Go

该项目提供了一个开箱即用的网络钓鱼平台,可用于模拟钓鱼攻击。它拥有友好的 Web 管理后台,支持邮件模板、批量发送邮件、网站克隆和数据可视化,适用于企业安全培训和渗透测试等场景。

项目详情→
hellogithub.com/repository/6f6ec956985847f6a133ee5daafae964

2.2 Rust 驱动的 HTTP 压测工具:oha

主语言:Rust

这是一个用 Rust 开发的 HTTP 请求压测工具,它操作简单、带 TUI 动画界面,支持生成请求延迟、吞吐量等指标的报告,以及动态 URL 和更灵活的请求间隔(burst-delay)等功能。

项目详情→
hellogithub.com/repository/98b46ea0d7d84f4c944d0a35a9d2d140

3. 结尾

以上就是本期「GitHub 热点速览」的全部内容,希望你能够在这里找到自己感兴趣的开源项目,如果你有其他好玩、有趣的 GitHub 开源项目想要分享,欢迎来
HelloGitHub
与我们交流和讨论。

往期回顾