sublimetext 开发 GO 使用体验怎么样
一直使用 vs code 开发 go,主要搞 web ,最近体验了一下 sublime-text ,发现这个曾经流行的开发工具对 GO 的支持很一般,插件还是很多年前的,是不是我不会配置,有没大神使用 ST 开发?
xiaohack博客专注前沿科技动态与实用技术干货分享,涵盖 AI 代理、大模型应用、编程工具、文档解析、SEO 实战、自动化部署等内容,提供开源项目教程、科技资讯日报、工具使用指南,助力开发者、AI 爱好者获取前沿技术与实战经验。
一直使用 vs code 开发 go,主要搞 web ,最近体验了一下 sublime-text ,发现这个曾经流行的开发工具对 GO 的支持很一般,插件还是很多年前的,是不是我不会配置,有没大神使用 ST 开发?
下面代码中 f()会被重复执行吗?
package main
import (
"fmt"
"sync"
)
type Once struct {
m sync.Mutex
done uint32
}
func (o *Once) Do(f func()) {
if o.done == 1 {
return
}
o.m.Lock()
defer o.m.Unlock()
fmt.Println("bing: ", o.done)
if o.done == 0 {
o.done = 1
f()
}
}
func main() {
var once Once
wg := sync.WaitGroup{}
wg.Add(100)
for i := 0; i < 100; i++ {
go func() {
defer wg.Done()
once.Do(func() {
println("executed---------》 ")
})
}()
}
wg.Wait()
}
之前在这发布过的,最近花了些时间给这个小工具写了份比较详细的文档了,请查阅
Github: https://github.com/threatexpert/gonc
自己平时使用的场景:
1 、公司的 VPN 好久不用了,家里 CGNAT 宽带和公司建立 P2P 的 HTTP+SOCKS5 代理隧道,自由访问公司网络。
2 、和分公司内网直接 P2P 快速(实时压缩)传输文件/目录。
3 、内置服务模块满足其他场景,例如 TCP/UDP 端口转发、类 frp 反向代理、甚至科学上网,一个工具都胜任了。
还真别说,通过打洞建立 P2P 的加密隧道,定期端口轮换的功能本来是针对运营商 Qos 的,在科学上网方面有独特的效果。
篇幅较长无法粘贴全文,原文链接:
https://github.com/allmonday/A-Python-web-development-methodology-for-complex-business-scenarios/blob/main/README.zh.md
一套面向复杂业务场景的 Python Web 开发方法论
在 Python Web 开发中,处理复杂业务场景时,开发者通常采用以下几种模式:
@router.get("/teams/{team_id}", response_model=TeamDetail)
async def get_team(team_id: int, session: AsyncSession = Depends(get_session)):
# 获取团队基本信息
team = await session.get(Team, team_id)
# 获取 Sprint 列表
sprints = await session.execute(
select(Sprint).where(Sprint.team_id == team_id)
)
team.sprints = sprints.scalars().all()
# 获取每个 Sprint 的 Story
for sprint in team.sprints:
stories = await session.execute(
select(Story).where(Story.sprint_id == sprint.id)
)
sprint.stories = stories.scalars().all()
# 获取每个 Story 的 Task
for story in sprint.stories:
tasks = await session.execute(
select(Task).where(Task.story_id == story.id)
)
story.tasks = tasks.scalars().all()
# 获取每个 Task 的负责人
for task in story.tasks:
task.owner = await session.get(User, task.owner_id)
return team
这种做法在简单场景下确实很直观,能够快速上手。ORM 的类型安全特性也能在编译时发现一些错误,而且与数据库表结构的一一对应关系让代码容易理解。但当我们面对真正的业务场景时,这种方式的缺陷很快就暴露出来了。
最致命的问题是 N+1 查询。虽然代码看起来很清晰,但执行时会产生大量的数据库查询。每当我们访问一个关联关系时,ORM 就会发起一次新的查询。在深层嵌套的情况下,查询数量会呈指数级增长。更糟糕的是,这种性能问题在开发阶段不容易发现,只有当数据量积累到一定程度后才会显现出来,那时候往往已经太晚了。
代码的组织方式也是个问题。数据获取的逻辑散落在各个嵌套的循环中,业务逻辑和数据获取逻辑混在一起,难以阅读和维护。当需要修改业务规则时,开发者不得不在复杂的嵌套结构中寻找修改点,很容易引入新的 bug 。性能更是不可控,随着数据量的增长,查询效率会急剧下降,而这些性能瓶颈很难在代码层面直接观察到。
此外,相似的数据获取逻辑会在多个 API 中重复出现,导致大量代码冗余。当一个 API 需要获取"团队及其 Sprint",另一个 API 需要"团队及其成员"时,即使它们的查询逻辑非常相似,也不得不重复编写。这违反了 DRY ( Don't Repeat Yourself )原则,增加了维护成本。
@router.get("/teams/{team_id}", response_model=TeamDetail)
async def get_team(team_id: int, session: AsyncSession = Depends(get_session)):
# 使用 joinedload 预加载关联数据
result = await session.execute(
select(Team)
.options(
joinedload(Team.sprints)
.joinedload(Sprint.stories)
.joinedload(Story.tasks)
.joinedload(Task.owner)
)
.where(Team.id == team_id)
)
return result.scalar_one()
为了解决 N+1 查询问题,ORM 提供了 Eager Loading 机制,让我们可以通过 joinedload、selectinload 等方式预先加载关联数据。代码变得更简洁了,性能问题也得到了缓解。但这种方案也带来了新的挑战。
最明显的问题是笛卡尔积。当我们使用多层 JOIN 预加载关联数据时,数据库返回的数据量会急剧膨胀。比如一个团队有 10 个 Sprint ,每个 Sprint 有 10 个 Story ,每个 Story 有 10 个 Task ,那么 JOIN 的结果集会包含 1000 行数据,即使每行的数据量不大,也会给网络传输和内存占用带来压力。
更严重的问题是灵活性差。Eager Loading 的策略是在代码中硬编码的,所有使用同一个 Model 的 API 都会执行相同的预加载逻辑。但不同的 API 往往需要不同的数据。比如一个 API 只需要团队的基本信息,另一个 API 需要团队的 Sprint ,还有一个 API 需要团队的成员。如果统一使用 Eager Loading 加载所有关联数据,就会出现过度获取的问题,前端不需要的数据也被查询和传输了,浪费了资源。
配置 Eager Loading 本身就很复杂。开发者需要理解 lazy、joinedload、selectinload、subquery 等多种加载策略的区别,知道什么时候用哪一种,以及它们各自会有什么副作用。这种配置错误很容易导致性能问题或意外的数据加载行为。而且,这种"一刀切"的配置方式意味着所有 API 都使用相同的加载策略,无法针对特定场景进行优化。
@router.get("/teams/{team_id}", response_model=TeamDetail)
async def get_team(team_id: int, session: AsyncSession = Depends(get_session)):
# 1. 批量获取所有需要的数据
team = await session.get(Team, team_id)
sprints_result = await session.execute(
select(Sprint).where(Sprint.team_id == team_id)
)
sprint_ids = [s.id for s in sprints_result.scalars().all()]
stories_result = await session.execute(
select(Story).where(Story.sprint_id.in_(sprint_ids))
)
story_ids = [s.id for s in stories_result.scalars().all()]
tasks_result = await session.execute(
select(Task).where(Story.id.in_(story_ids))
)
tasks = tasks_result.scalars().all()
owner_ids = list(set(t.owner_id for t in tasks))
owners_result = await session.execute(
select(User).where(User.id.in_(owner_ids))
)
owners = {u.id: u for u in owners_result.scalars().all()}
# 2. 手动组装数据结构
sprint_dict = {s.id: s for s in sprints_result.scalars().all()}
story_dict = {s.id: s for s in stories_result.scalars().all()}
for story in story_dict.values():
story.tasks = [t for t in tasks if t.story_id == story.id]
for task in story.tasks:
task.owner = owners.get(task.owner_id)
for sprint in sprint_dict.values():
sprint.stories = [s for s in story_dict.values() if s.sprint_id == sprint.id]
team.sprints = list(sprint_dict.values())
return team
为了获得最优的性能和精确的数据控制,有经验的开发者会选择手动组装数据。这种方式完全掌控查询逻辑,可以精确控制每个查询的 SQL 语句,避免不必要的数据库访问。通过批量查询和智能的数据组装,可以获得最佳的性能,而且没有冗余数据。
但这种方式的代价是代码变得非常冗长。如上面的例子所示,为了获取一个团队的完整信息,我们需要编写多个查询,手动构建数据字典,然后通过嵌套循环组装数据。代码的长度和复杂度都大幅增加,而真正表达业务逻辑的代码反而被淹没在数据组装的细节中。
更容易出错也是个大问题。手动组装数据涉及到大量的索引操作和循环嵌套,很容易出现索引错误、空指针引用等 bug 。而且这些错误往往只有在运行时、特定数据条件下才会暴露,难以在开发阶段发现。
维护成本更是高昂。当业务规则发生变化时(比如需要添加一个新的关联关系),开发者需要在所有相关的 API 中修改数据组装逻辑。如果遗漏了某个地方,就会导致数据不一致。而且,相似的数据组装逻辑会在多个 API 中重复出现,违反了 DRY 原则。
最根本的问题是,这种代码已经变成了纯粹的数据搬运工,看不出任何业务意图。代码中充满了字典操作、循环嵌套、索引查找,而这些都是技术细节,与业务需求毫无关系。新加入的团队成员很难从这些代码中理解业务逻辑,业务知识的传递变得异常困难。
type Query {
team(id: ID!): Team
}
type Team {
id: ID!
name: String!
sprints: [Sprint!]!
}
type Sprint {
id: ID!
name: String!
stories: [Story!]!
}
type Story {
id: ID!
name: String!
tasks: [Task!]!
}
type Task {
id: ID!
name: String!
owner: User!
}
GraphQL 确实是一个很有吸引力的方案。前端可以按需获取数据,需要什么字段就查什么字段,不会有过度获取的问题。它提供了类型安全的查询接口,而且通过 DataLoader 可以自动解决 N+1 查询问题。这些特性让 GraphQL 在前端开发中广受欢迎。
但 GraphQL 的学习曲线非常陡峭。开发者需要学习全新的查询语言、Schema 定义、Resolver 编写、DataLoader 配置等一堆概念,这与 REST API 的直观性形成了鲜明对比。更麻烦的是,GraphQL 的过度灵活性给后端带来了巨大的挑战。前端可以构造任意复杂的查询,有些查询甚至可能是开发者没有想到过的,这导致后端很难进行针对性的优化。当一个查询嵌套了 10 层,返回了数百万条数据时,数据库和服务器都会面临巨大的压力。
调试 GraphQL API 也比调试 REST API 复杂得多。当一个 GraphQL 查询出错时,错误信息往往很难定位到具体的问题源头。而且 GraphQL 需要额外的服务器和工具链支持,无法直接利用现有的 FastAPI 生态系统。比如 FastAPI 的依赖注入、中间件、自动文档生成等特性,在 GraphQL 中都无法直接使用。
还有一个更深层次的问题是 ERD 和用例的界限模糊。GraphQL 的 Schema 同时扮演了实体模型和查询接口两个角色。当我们设计一个 GraphQL Schema 时,很难确定应该按照实体来组织(一个 Type 对应一个数据库表),还是按照用例来组织(不同的业务场景需要不同的字段)。这导致最佳实践不清晰,不同的项目、不同的开发者可能有完全不同的组织方式。
而且随着业务增长,所有的用例都会堆砌在同一个 Schema 中,导致 Schema 膨胀,难以维护。权限控制也变得异常复杂。不同的 API 端点可能有不同的权限要求,但它们可能都查询同一个实体(比如 User ),在 GraphQL 中很难针对不同的查询场景应用不同的权限规则。
上面我们探讨的所有模式,虽然表面上的问题各不相同,但它们的核心困境其实是一致的。
# SQLAlchemy ORM 同时扮演两个角色:
# 1. 数据模型(如何存储)
# 2. 业务模型(业务概念)
class Team(Base):
__tablename__ = 'teams'
id = Column(Integer, primary_key=True)
name = Column(String)
# 这是数据库的外键关系,还是业务关系?
sprints = relationship("Sprint", back_populates="team")
在传统的 ORM 开发中,业务模型和数据模型是混在一起的。看看这个例子,Team 类既表达了业务概念(团队是什么),又承载了数据模型的细节(如何在数据库中存储)。当我们在 sprints 字段上定义 relationship 时,这到底是在描述一个业务关系(团队有多个 Sprint ),还是在声明一个数据库外键约束?这种模糊性会导致很多问题。
数据库的设计约束会直接影响我们的业务建模。比如,如果数据库中的 teams 表没有直接到 users 的外键,而是通过中间表 team_members 关联,那么在 ORM 中我们也必须通过这个中间表来定义关系。这意味着业务模型被迫适应数据库的实现细节,而不是反过来。
更严重的是,这种方式无法表达跨库、跨服务的业务关系。现代系统中,数据可能分布在不同的数据库中,甚至存储在外部服务里。比如用户的基本信息在 PostgreSQL ,而用户的偏好设置在 MongoDB ,用户的实时状态在 Redis 中。ORM 的 relationship 无法跨越这些边界,业务模型因此被限制在了单一数据库的范围内。
传统架构的依赖方向:
┌─────────────┐
│ API Layer │ ← 依赖于
└──────┬──────┘
│
↓
┌─────────────┐
│ ORM Models │ ← 依赖于
└──────┬──────┘
│
↓
┌─────────────┐
│ Database │
└─────────────┘
问题:业务规则依赖于数据库实现!
这违反了 Clean Architecture 的依赖规则。正确的依赖关系应该是:业务规则最稳定,不依赖任何外层;数据库是实现细节,应该依赖业务规则;当数据库变化时,业务规则不应该受影响。但传统架构的依赖方向恰恰相反,业务规则被数据库的实现细节所绑架。
# 传统方式:业务关系隐藏在查询中
async def get_team_tasks(team_id: int):
# "团队的任务"这个业务概念隐藏在 SQL WHERE 中
result = await session.execute(
select(Task)
.join(Sprint, Sprint.id == Task.sprint_id)
.where(Sprint.team_id == team_id)
)
return result.scalars().all()
业务关系没有被显式声明出来,这是个很隐蔽但危害很大的问题。看看这个例子,"团队的任务"是一个清晰的业务概念,但这个概念被隐藏在 SQL 的 JOIN 和 WHERE 子句中。新加入团队的成员需要阅读大量代码才能理解系统中有哪些业务关系,这些关系是如何定义的。更糟糕的是,没有自动化的方式来检查业务关系的一致性。当需求变化需要修改某个关系时,开发者很难找到所有相关的代码,很容易遗漏某个地方,导致业务逻辑的不一致。
在 SQLAlchemy ORM 中,多对多关系需要显式定义中间表,这导致技术细节泄漏到业务层。
# SQLAlchemy ORM:必须定义中间表
class Team(Base):
__tablename__ = 'teams'
id = Column(Integer, primary_key=True)
name = Column(String)
# ORM relationship 需要指定中间表
members = relationship("User",
secondary="team_members", # 必须指定中间表
back_populates="teams")
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
teams = relationship("Team",
secondary="team_members", # 必须指定中间表
back_populates="members")
# 中间表(技术实现细节)
class TeamMember(Base):
__tablename__ = 'team_members'
team_id = Column(Integer, ForeignKey('teams.id'), primary_key=True)
user_id = Column(Integer, ForeignKey('users.id'), primary_key=True)
role = Column(String) # 可能还有额外字段
# 查询时需要关心中间表的存在
@router.get("/teams/{team_id}")
async def get_team_members(team_id: int, session: AsyncSession):
# 必须通过中间表查询
result = await session.execute(
select(User)
.join(TeamMember, TeamMember.user_id == User.id) # 中间表暴露
.where(TeamMember.team_id == team_id)
)
return result.scalars().all()
这个问题的根源在于,ORM 的多对多关系需要显式定义中间表,这导致技术细节直接泄漏到业务层代码中。业务代码必须知道 team_members 中间表的存在,查询时也需要显式地 join 这个中间表。这增加了代码复杂度,更重要的是,业务逻辑被数据库的实现细节所绑架。
更深层的问题是业务语义变得模糊。TeamMember 到底是一个有意义的业务概念,还是纯粹的技术实现?如果中间表还有额外的字段(比如 role 表示用户在团队中的角色,joined_at 表示加入时间),这些字段应该被建模为独立的实体吗?不同的开发者可能给出不同的答案,缺乏统一的指导原则。
数据组装也因此变得复杂。查询"团队的所有成员"需要 join 中间表,查询"用户所属的团队"也需要 join 中间表。所有涉及多对多关系的查询都变得冗长和难以理解。当业务规则要求"获取用户在所有团队中的角色"时,情况就更加复杂了。这些技术细节让业务逻辑的实现变得异常沉重。
对比:Pydantic-Resolve ERD 的方式
# ERD:业务概念清晰,无需关心中间表
class TeamEntity(BaseModel, BaseEntity):
"""团队实体 - 业务概念"""
__relationships__ = [
# 直接表达"团队有多个成员"的业务关系
Relationship(
field='id',
target_kls=list[UserEntity],
loader=team_to_users_loader # loader 内部处理中间表
),
]
id: int
name: str
class UserEntity(BaseModel, BaseEntity):
"""用户实体 - 业务概念"""
__relationships__ = [
# 直接表达"用户属于多个团队"的业务关系
Relationship(
field='id',
target_kls=list[TeamEntity],
loader=user_to_teams_loader
),
]
id: int
name: str
# Loader 实现细节:中间表只在这里出现
async def team_to_users_loader(team_ids: list[int]):
"""加载团队成员 - 内部处理中间表"""
async with get_session() as session:
# 只有这里需要知道中间表的存在
result = await session.execute(
select(User)
.join(TeamMember, TeamMember.user_id == User.id)
.where(TeamMember.team_id.in_(team_ids))
)
users = result.scalars().all()
# 构建映射
users_by_team = {}
for user in users:
for tm in user.team_memberships:
if tm.team_id not in users_by_team:
users_by_team[tm.team_id] = []
users_by_team[tm.team_id].append(user)
return [users_by_team.get(tid, []) for tid in team_ids]
关键差异:
| 维度 | SQLAlchemy ORM | Pydantic-Resolve ERD |
|---|---|---|
| 中间表位置 | 暴露在业务层 | 隐藏在 loader 实现中 |
| 业务语义 | 技术关系 (secondary) |
业务关系 (团队包含成员) |
| 查询代码 | 需要 join 中间表 | loader.load(team_id) |
| 代码位置 | 分散在多处 | 集中在 loader |
| 测试 | 依赖数据库表结构 | 可 mock loader |
架构优势:
传统方式:
Team → TeamMember (中间表) → User
业务层需要知道中间表的存在
Pydantic-Resolve 方式:
Team → User (业务关系)
中间表是数据层的实现细节,业务层不关心
这意味着:
业务模型纯净:Team 和 User 的关系直接表达业务语义
技术细节封装:中间表的存在被封装在 loader 中
灵活的存储策略:
易于理解:新人看到 ERD 就能理解业务关系,不需要先学习数据库设计
Clean Architecture 由 Robert C. Martin (Uncle Bob) 提出,核心思想是:
"Software architecture is the art of drawing lines that I call boundaries."
软件架构的艺术在于画界线。
外层依赖内层,内层不依赖外层。
↓ 依赖方向
┌─────────────────────┐
│ Frameworks & │ 外层
│ Drivers │ (实现细节)
├─────────────────────┤
│ Interface │
│ Adapters │
├─────────────────────┤
│ Use Cases │
│ (Application) │
├─────────────────────┤
│ Entities │ 内层
│ (Business Rules) │ (核心)
└─────────────────────┘
遵循依赖规则有几个关键点需要注意。首先,内层不知道外层的存在,这意味着核心业务逻辑不依赖于任何框架、数据库或 UI 的细节。其次,内层不包含外层的信息,比如业务规则不应该知道数据是用 PostgreSQL 还是 MongoDB 存储的。最后,外层的实现可以随时替换而不影响内层,这意味着我们可以从 SQLAlchemy 切换到 MongoDB ,或者从 FastAPI 切换到 Django ,而业务逻辑代码无需修改。
# ❌ 错误:业务规则依赖数据库
class Task:
def calculate_priority(self, session):
# 业务逻辑被数据库实现细节污染
if self.assignee_id in session.query(TeamMember).filter_by(role='lead'):
return 'high'
# ✅ 正确:业务规则独立
class Task:
def calculate_priority(self, assignee_roles):
# 业务逻辑只依赖业务概念
if 'lead' in assignee_roles:
return 'high'
# 内层定义数据结构
class TaskEntity(BaseModel):
id: int
name: str
assignee_id: int
# 外层负责转换
def task_entity_to_orm(entity: TaskEntity) -> Task:
return Task(
id=entity.id,
name=entity.name,
assignee_id=entity.assignee_id
)
在 Web 开发中,依赖规则可以这样理解:
┌────────────────────────────────────────────────────┐
│ Presentation Layer (外层) │
│ - FastAPI Routes │
│ - Request/Response Models │
│ - 依赖: Application Layer │
└────────────────────────────────────────────────────┘
↓
┌────────────────────────────────────────────────────┐
│ Application Layer (Use Cases) │
│ - 业务用例(获取用户、创建订单) │
│ - 依赖: Domain Layer │
└────────────────────────────────────────────────────┘
↓
┌────────────────────────────────────────────────────┐
│ Domain Layer (内层) │
│ - Entities (业务实体) │
│ - Business Rules (业务规则) │
│ - Value Objects (值对象) │
│ - 不依赖任何外层 │
└────────────────────────────────────────────────────┘
↓
┌────────────────────────────────────────────────────┐
│ Infrastructure Layer (最外层) │
│ - Database (SQLAlchemy) │
│ - External Services │
│ - File System │
└────────────────────────────────────────────────────┘
关键洞察:
# 传统方式:所有层次耦合
# Domain Layer (应该独立,但实际上依赖了 ORM)
class User(Base): # ← SQLAlchemy Base
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
# Application Layer (应该只依赖 Domain ,但直接使用了 ORM)
async def create_user(data: dict, session: AsyncSession):
user = User(**data) # ← 直接使用 ORM Model
session.add(user)
await session.commit()
# Presentation Layer
@router.post("/users")
async def api_create_user(data: dict, session=Depends(get_session)):
return await create_user(data, session) # ← 暴露了数据库细节
这段代码暴露了传统架构的核心问题。SQLAlchemy 虽然建立了对象关系映射( ORM ),让数据库表可以通过 Python 对象来操作,但这种映射关系过于紧密。ORM Model 既承担了数据持久化的职责,又要表达业务概念,导致对象无法自由地代表业务模型。业务实体被数据库的实现细节所绑架,每个字段、每个关系都必须与数据库表结构一一对应,完全失去了作为独立业务概念存在的自由。
更深层次的问题包括:
。。。

路由跟踪去 google

跟踪去 ytb

dns 出口

多出口
我实在是没测出来有什么穿透网络什么的
但是我朋友说体感很差大概心里也有点数了
夜猫上线!!
目前的个人信息栏会固定占用一个宽度,导致长帖子在窄屏浏览时被悬挂(即有一定的空白空间被浪费)
站长是否考虑加入一个收缩个人信息栏的功能(或者有更优秀的方案),实现并不难:

这里我是通过 css 去控制的,临时方案
另外关于自定义主题,能不能导出站内的主题预设,然后去根据自己的喜好进行微调,再导入回来?
直接从 0 开始配置自定义主题,审美 hold 不住啊
通过输入两个冒号唤起表情联想时,面板不会跟选键盘选中的焦点滚动
刚刚在编辑的时候发现的,输入框全屏的时候无法唤起表情包联想、表情包面板等
最新新增的图片排版功能
通过键盘控制光标进入图片链接时不会提示排版按钮
只有鼠标点击才会
这个项目( Clawdbot -> Moltbot -> OpenClaw )第二次改名了,很影响 SEO 。
用 openclaw configure 看起来是无法修改 baseUrl 的,所以需要打开 ~/.openclaw/openclaw.json
然后关键是 agents 和 models 这两段 json:
agents: {
defaults: {
model: { primary: "hodlai/claude-opus-4-5-20251101" },
models: {
"hodlai/claude-opus-4-5-20251101": { alias: "Opus" }
}
}
},
models: {
mode: "merge",
providers: {
hodlai: {
baseUrl: "https://api.hodlai.fun/v1",
apiKey: "这里换成你自己的 API key",
api: "openai-responses",
models: [
{
id: "claude-opus-4-5-20251101",
name: "Claude Opus 4.5 20251101",
reasoning: true,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 196608,
maxTokens: 8192
}
]
}
}
},
然后就可以用了。

很久以前,就想写一篇关于SDL与DevSecOps的文章,但疏于实践一直未能动笔。想写的原因很简单,因为总是听到有人说SDL落后、DevSecOps相关技术更高超。一提到研发安全建设,不分研发模式都在赶时髦一样地说DevSecOps。从我的观察来看,不结合研发模式来做研发安全,都是不成功的。 在数字化浪潮的推动下,一些公司已经完全步入DevOps模式,有的则出现瀑布、敏捷或DevOps并存,且后者是居多的。所以如何在多种研发模式下进行有效的研发安全建设,成为一个必须解决的难题。经过近十年的实践,终于在探索解法上有一点点收获与经验,于是有了“深耕研发安全”这一系列文章。 本文是第四篇,正式步入DevSecOps实施前的准备阶段。首先是组织架构,既要包括高层的组织,从公司战略层面进行安全工作规划;又得有实际落地安全工作的团队。文中首次提出“研发安全团队”及架构,既是理想中的完备团队,又是做好研发安全工作必备的最小能力集。 01 安全团队全貌 在建组织的过程中,一般是从所在岗位开始,比如最开始有安全运维岗或安全测试岗,随着公司的不断发展可能独立成为安全部门。这时候就需要继续往上发展,建立安全管理委员会之类的高层组织,无论是从拿政策、拉资源,还是工作呈现、汇报,对于网络安全工作的开展都大有裨益。 02 研发安全团队 上述四个团队映射的能力和权责,其实就是做好研发安全的必备要素。不管是单独设置岗位,或是人员复用承担多个职责,都极具参考价值。 本文首发于微信公众号:我的安全视界观
(研发安全视角下的组织架构全景图)
在我们的实践中,主要有四个重要的安全组织,从上到下依次为:
再回到SDL团队(研发安全团队 = 产品安全 - 产品安全事件应急响应小组 = 安全体系组 + 安全测试组 + 安全工具组 + 安全运营组),这是在资源充足的前提下的完美状态,从做好SDL来说也确实需要这四种角色。经过五年的历程,我们基本实现了这种状态,具体分工和职责如下:
你说一个东西不好,他立刻跳出来指责你说都是你自己的问题,就感觉你在说他的东西不好一样,这种人是什么心理,怼他又显得我没素质。
(几次在微信群咨询/分享时的经历)
只用了几年时间,上下文窗口就从 4k 膨胀到 1000 万。Meta 发布的 Llama 4 Scout 的时候说这个模型支持 1000 万 Token,是 Llama 3 那 128k 的 78 倍。而Google Gemini 3 Pro 是 100 万,Claude 4 也桐乡市100万。 一次推理跑完整个代码库、几百篇论文、连续好几天的对话记录在技术上可行了,但问题是硬件跟不上。 405B 参数的模型,32 位精度下光权重就要 6.5TB 内存。再算上梯度、状态、激活值,后者还随上下文长度二次方增长。单台 NVIDIA HGX B300 配了 2.3TB HBM3e都不够。 这就逼着必须做多节点分布式训练和推理,几十上百块 NVIDIA Blackwell GPU 、NVLink 再加上 InfiniBand,就成了数据中心的标配。所以难点就变味了 GPU 之间的通信瓶颈。 模型或数据集超出单卡容量,就得上并行策略,但是每种策略本质上都是拿通信开销换内存空间。 数据并行是最直接的方案:整个模型复制到每张卡上,训练数据切开,每张卡跑不同的 batch跑完一步同步梯度。适合小模型,计算是瓶颈、内存不是问题的场景。 模型并行针对大模型:单卡装不下,就把模型拆开,不同的层放不同的卡上,按顺序跑。405B 这种规模只能这样,并且下游的卡得等上游算完中间是有空转的。 张量并行更极端:连单个矩阵乘法都塞不进一张卡。就需要把矩阵按行或按列切开,分到各卡上算,再通过 all-reduce 合起来。 但这些都有共同的局限。模型大、上下文又长到几百万 Token,张量并行也顶不住。因为注意力的二次方内存增长太凶,激活值直接占满显存。128k 上下文的激活值内存是 8k 的 16 倍,这个目前没办法,因为就是这么夸张。 序列并行和上下文并行都是在设备间切序列来省内存,但切法不一样。 序列并行配合张量并行使用,只切那些非矩阵乘法的操作,比如层归一化、dropout。张量并行管不到的地方,序列并行接手,每张卡处理一部分激活值。两者配合能把序列撑长一些,但到 128k 以上还是会有问题,因为注意力的二次方增长是绕不过去。 上下文并行更彻底:整个序列在所有模块里都切开,包括注意力。每个操作拿到的都是分区后的序列。百万级上下文的训练就靠这个,把激活值的内存占用分摊到各卡上。 注意力一直是最麻烦的问题,因为模型的其他操作基本都是逐 Token 独立处理并行起来很自然。但注意力不行,每个 Token 都要"看"序列里所有其他 Token。序列切到多张卡上之后,GPU 1 的 Token 怎么看 GPU 2 的 Token?直接等数据传完再算,整个流水线就卡住了。 Ring Attention 就是来解决这个问题的,让多节点多卡的大模型训练和推理能在大规模数据中心里跑起来。 Ring Attention 把 GPU 组织成环形拓扑。每张卡的工作流程是这样的:持有序列中 Q、K、V 张量的一个分块;用本地的 K 和 V 给自己的 Q 分块算注意力;把 K 和 V 传给环里的下一张卡;从上一张卡接收 K 和 V;循环往复,直到所有 Q Token 都跟所有 K/V Token 算完注意力。 关键在于计算和通信是重叠的。GPU 1 拿着当前的 K/V 分块算注意力的时候,同时在从 GPU 0 接收下一批分块。通信延迟减少了,因为不用干等数据全到了再开算。 GPT 这类自回归模型有个额外的麻烦:Token 只能看前面的 Token不能看后面的。所以会导致负载不均衡有些卡会空转,Zig-Zag Ring Attention 解决这个问题的办法是交错分配,不是按顺序切块而是 GPU 0 拿 Token [0, 4, 8...],GPU 1 拿 [1, 5, 9...],以此类推。每张卡都拿到早期和晚期 Token 的混合,因果注意力计算时负载就均衡了环里不会有卡闲着。 但是代价是索引逻辑稍微复杂一点,不过大规模场景下性能收益很可观,因果掩码下也能做到接近满 GPU 利用率。 上下文并行把输入序列切到多张 GPU 上,突破训练时的内存限制。跟张量并行、数据并行不同,它在所有模型模块里都切序列维度。单卡装不下的百万级 Token 上下文,只有靠这个才能训。 Ring Attention 把 GPU 排成环,每张卡一边算当前数据的注意力,一边把键值对往下传。通信和计算重叠,全对全的注意力计算不用等完整序列数据到齐,GPU 不会干等。 而序列并行只切非矩阵乘法操作(层归一化之类的),配合张量并行用。上下文并行在所有模块里都切序列,包括注意力。超过 128k Token 的上下文必须用后者,因为激活值内存二次方增长太猛了。 为什么 Zig-Zag Ring Attention 比标准 Ring Attention 更好? Zig-Zag 用交错分配代替顺序分配,因果掩码计算时各卡负载更均衡。标准 Ring Attention 会让后面的卡等前面的分块,造成计算空闲。Zig-Zag 把早期和晚期 Token 均匀撒到各卡上,避免这个问题。 那么训练百万级 Token 上下文的模型需要什么硬件? 多节点 GPU 集群,配 HBM 内存,加高速互连——NVIDIA NVLink 1.8TB/s 或者 InfiniBand。405B 参数模型 32 位精度从头训练加推理,4 台 NVIDIA HGX B300 的机架部署是个不错的起点。 上下文并行本质上是拿通信开销换内存空间,而网络带宽是最要命的瓶颈。Ring Attention 要在 GPU 之间不停交换键值对,传输时间一旦超过计算时间,各卡就会从"边算边传"退化成"等数据"。NVIDIA NVLink 1.8TB/s 加 InfiniBand 的高速互连,在多机架部署里不是可选项是必需品。互连带宽必须匹配 GPU 计算吞吐量,否则上下文并行的效果会大打折扣。 https://avoid.overfit.cn/post/fd6022b9196942ffb737ba306925b6db by Khang Pham
并行化基础
上下文并行与序列并行
Zig Zag Ring Attention:通信和计算重叠


上下文并行与 Ring Attention 常见问题
总结
用京东就图他优惠力度大,但是京东的外卖员,真的是一言难尽,这个月已经好几次严重超时了,而且打电话沟通态度也不好。
今天更夸张,到了楼下了,因为写字楼这个点电梯比较难等,他叫我下去拿,wdf。。。他上来难,我下去拿再上来就不难吗,我拒绝了,然后他说那他先去送其他的单,最后来送我这个(略带威胁),but 我这个单已经超时五分钟了。。。。。。。
好的是,找京东客服退单,秒处理,而且还给了补偿。
大家好,我是民工哥。 之前我们聊过了:国内互联网公司TOP 10与全球操作系统 TOP 10。 最近,看到很多人都在谈论外包公司,这不,我也来蹭一下热闹。 其实,怎么讲呢,对于从事IT行业的我们来说,外包企业永远是IT人逃不掉的坎,而且,很多人都有一个疑问:为什么 it 外包永远在招人? 特别是最近几年,大环境不好的情况,很多企业都在缩招、精减岗位。 这么做目的很明确,开源节流,减少人力成本的支出,降低管理责任。 这也是外包公司一直存在的核心原因,也是为什么有的外包企业越做越好,越来越大的核心所在。 所以,很多中大型企业的部分岗位都会选择给外包公司来做。 用行话来说就是:利益共分,风险共担。 对于,求职者来说,前几年,都流行:外包狗都不去。 但是,在当前这种情况之下,如果空窗期过长也不是很好的情况,选择外包企业也是一种曲线选择(先生存才能有后续)。 其实,就是上面所说的,企业为了节省成本,而将企业内部一些岗位或项目交由第三方公司承做,企业可以将优势资源与核心精力集中于发展核心 业务上面。 我们在日常求职过程中,常见的有:企业IT资产管理、桌面运维、机房服务器运维管理(服务器硬件、软件、监控、巡检等)诸如这些工作,都可以视作外包企业对外提供的服务项目。 外包企业的业务模式一般来说有以下三种: 总体来说,1、2这类模式占比较高。 我们通常讨论比较多的还是东软集团、中软国际、软通动力、文思海辉(现中电金信)这四家。 它们在规模、业务领域、市场影响力等方面均处于行业领先地位。 近日,有专业机构发布了《2026年中国十大IT外包企业》,排名不分先后,位居前十的有: 今天,我们就一同来理一理这十大 IT 外包企业,希望对大家来年的求职找工作有所帮助与借鉴。 成立时间:1991年,1996年上市,上交所,股票代码:600718。 核心优势:中国第一家上市的软件公司,以软件技术为核心,业务覆盖智慧城市、医疗健康、智能汽车互联等领域。 业务领域:业务重心涵盖智慧医疗、智慧城市、汽车电子三大核心领域。 市场地位: 嵌入式软件服务于全球知名品牌,拥有Linux操作系统与办公软件业务。 成立时间:2000年,2008年上市香港主板,股票代码:00354.HK。 核心优势:全球化软件与信息技术服务企业,与华为等战略伙伴合作构建互联网信息技术服务平台。 业务领域:早期专注于电子政务和金融信息化,后成为华为生态里的“关键玩家”,深度参与华为云计算、人工智能、通信设备等核心领域的研发项目。 市场地位: 在政务云、金融信息化等赛道市场份额领先,具备从咨询到交付的全流程服务能力。 成立时间:2005年 核心优势:全栈智能化产品与服务提供商,具备从咨询到交付的全流程服务能力。 业务领域:业务覆盖金融、能源、智能制造、ICT等多个领域,搭建了从咨询规划、技术开发到运维服务的全流程体系。 市场地位: 聚焦云计算、大数据、人工智能等新兴技术,服务华为、腾讯等头部企业。 成立时间:由1995年成立的文思创新和1996年成立的海辉软件于2012年合并而来,后加入中国电子(CEC)阵营。 核心优势:国有企业背景,专注于金融科技赛道,具备从咨询到软件开发的全流程服务能力。 业务领域:主攻金融科技赛道,尤其是在银行业IT项目上堪称“隐形冠军”。业务覆盖银行核心系统升级、数字支付解决方案、金融风控的AI模型开发等银行数字化转型的全流程。 市场地位: 核心数字化产品为智翼云SuperDXP企业数字化创新平台,采用分布式互联网中台PaaS技术架构。 成立时间:1945 年 核心优势:中国领先的IT解决方案和产品提供商,提供全方位IT产品和服务。 业务领域:云计算、大数据、人工智能、企业资源规划(ERP)、服务器、存储设备等。 市场地位:服务器产品国内市场占有重要地位,国际市场影响力不断扩展。 与Intel、NVIDIA、华为等全球领先科技公司合作,推动技术生态建设。 成立时间:1995年 核心优势:全球IT咨询、产品及解决方案服务商,业务涵盖人工智能、大数据、物联网等领域。 业务领域:IT服务、金融IT服务、IT综合解决方案、企业服务及全球化和本地化解决方案。 市场地位:在中国、美国、日本、印度等八个国家设有70余家分支机构,服务15个行业客户。 获得CMMI 3、ISO 20000、ISO 9001、ISO 27001等资质认证,具备全球交付能力。 成立时间:1996年,2019年上交所上市。 核心优势:国内保险IT领域的龙头企业,具备深厚的技术积累和行业经验。 业务领域:计算机软件开发及产品的销售与服务,专注于保险、政务信息化等行业应用。 市场地位:保险IT解决方案市占率领先,政务信息化行业应用经验丰富。 持续加码AI研发,赋能业务全流程,具备垂直应用软件开发能力。 成立时间:2009年(整合升级为集团化运营于2018年) 核心优势:以数字化作业平台为核心,提供业务运营服务,具备卓越的服务交付能力。 业务领域:文档服务、远程服务、网点服务、智慧运营和金融科技等五大战略业务。 市场地位:在科技服务领域深耕二十九年,服务客户遍布多个行业。 构建“大平台+小前端+多生态+共运营”模式,提供账户管理服务、信贷风险服务等。 成立时间:成立于1996年(原大连华信计算机技术股份有限公司) 核心优势:以软件技术为核心,从事计算机应用软件开发、系统集成、软件外包服务等多个业务领域。 业务领域:国际业务主要提供软件外包服务、BPO和ITO服务;国内业务主要提供IT战略方案咨询、系统策划和设计等全方位服务。 市场地位:国家规划布局内重点软件企业,中国软件产业最大规模前100家企业之一。 获得ISO9001:2008、CMM5级、CMMI5级等资质认证,具备嵌入式软件、BPO服务、ITO服务等技术能力。 成立时间:2006年 核心优势:中国中西部地区领先的服务外包供应商,具备专业、成熟的ODC(离岸交付中心)模式交付能力。 业务领域:为制造业、金融、电信、能源、IT及政府公共服务行业提供信息技术外包(ITO)和业务流程外包(BPO)服务。 市场地位:客户涵盖IBM、华为、阿里巴巴等世界500强企业,在中国大陆及海外设立32个分支机构。 持有国家高新技术企业、软件企业资质,并通过CMMI ML5、ISO27001等国际管理体系认证。 最近,很多小伙伴问:只有外包的 offer 能去吗? 大环境不行,面试太少了,很多本科生想进外包都没机会。 之前都是买方市场(求职者),如今,角色转换了,成卖市场了(企业)。 并不要认为你有大厂履历、多牛逼的技术,多少年多少年的经验,这些在现实面前都是浮云。 当今市场情况下,多数企业不太会用高薪去招聘一个技术较牛的人,毕竟可能多数情况下企业目前也用不上这类人才,招一个能干活的要求并不高的才是第一要务,活下去才是硬道理,否则,什么发展都空谈。 真的,听劝! 非常时期,不需要在意那么多,外包作为过渡是完全没问题的,很多外包其实比小公司还要好多了。 也不要太担心去外包会导致自己的简历有“污点”,只要在实际工作中接触的项目还可以,写在简历上再润色一下,再就业求职也是完全没问题的,放心! 默默沉淀,提高个人竞争力,等待时机成熟再溜就好了。 之前给大家也整理过一篇关于外包薪资的文章:目前工资最高的几家外包公司汇总(最新版)!

外包企业概述
业务模式
东软集团

中软国际

软通动力

文思海辉(现中电金信)

浪潮(Inspur)

博彦科技

中科软科技

银雁科技

信华信

佰钧成

外包能去吗?
📌 本文适用于已安装 ClawdBot 用户,介绍如何修改配置以接入 HodlAI 接口。详细安装教程请自行搜索,或借助 AI 指导,后续我们也将推出完整版教程。
使用任意编辑器打开 clawdbot.json:
nano ~/.clawdbot/clawdbot.json
将 models 和 agents 部分替换为以下内容:
⚠️ 如需更换模型,请同步修改所有
gpt-5.2相关字段(id、name、primary、models)
"models": {
"mode": "merge",
"providers": {
"llm": {
"baseUrl": "https://api.hodlai.fun/v1",
"apiKey": "你的 API Key",
"api": "openai-completions",
"models": [
{
"id": "gpt-5.2",
"name": "GPT-5.2",
"reasoning": true
}
]
}
}
},
"agents": {
"defaults": {
"model": {
"primary": "llm/gpt-5.2"
},
"models": {
"gpt-5.2": {}
},
"workspace": "/root/clawd",
"compaction": {
"mode": "safeguard"
},
"maxConcurrent": 4,
"subagents": {
"maxConcurrent": 8
}
}
}
clawdbot doctor --fix
clawdbot gateway restart
持有 $HODLAI 代币,即可免费使用 200+ AI 模型
📋 完整模型列表:https://api.hodlai.fun/pricing
| 平台 | 链接 |
|---|---|
| 🌐 官网 | https://hodlai.fun/ |
| https://x.com/hodlai_bsc | |
| 💬 Telegram | https://t.me/hodlai_fun |