Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
---
slug: engineering-practice-doing-small-things-well
title: "工程实践分享 | 把小事做好"
authors: [techcamp]
tags: [ai, architecture, best-practices, career, compiler, engineering, go, tutorial]
title: 工程实践分享 | 把小事做好
authors:
- techcamp
tags:
- ai
- architecture
- career
- compiler
- engineering
- go
date: 2025-01-15
description: "在日前举办的第三期 1024 实训营结营成果展示会上,导师杨寒星基于同学们的展示,分享了他的一些看法,也阐述了为什么做好小事对开发者的个人成长具有积极的意义。"
description: 在日前举办的第三期 1024 实训营结营成果展示会上,导师杨寒星基于同学们的展示,分享了他的一些看法,也阐述了为什么做好小事对开发者的个人成长具有积极的意义。
---

在工程实践中,做好小事非常重要。
Expand All @@ -14,20 +21,20 @@ description: "在日前举办的第三期 1024 实训营结营成果展示会上
* 杨寒星 GitHub:https://github.com/nighca

## 一些启发
![pic-1](/img/blog/engineering-practice-doing-small-things-well/11111.png)
![pic-1](/img/blog/工程实践分享-把小事做好/11111.png)

要在3个月内实现Go+ Builder向导系统,这是一个复杂且工作量巨大的任务。同学们需要涵盖从调研到设计再到实现的整个流程。而且,Go+ Builder项目已有一定基础,需在此基础上进行设计、添加功能和编写代码,必然会面对一定的复杂性。此外,同学们还需在实现过程中解决许多具体问题(例如,如何实现代码检测)。

这个过程对我也有一些启发。以代码检测为例,我们在设计这一功能时,考虑过逐字符匹配、正则表达式,甚至通过编译器解析代码并检查抽象语法树(AST)来判断用户输入是否正确。经过多种方案的思考,我们最终想到利用大模型解决这个问题。这是一个典型的例子,展示了大模型如何改变我们既有的交互范式,进而影响我们解决问题的方式。

## 把小事做好
![pic-2](/img/blog/engineering-practice-doing-small-things-well/22222.png)
![pic-2](/img/blog/工程实践分享-把小事做好/22222.png)

这次实训过程,因为时间紧、任务重,我们在过程中对很多“似乎暂时不影响功能实现”的细节关注得并不多,但今天我想借这个机会再来分享一下,我是如何看待这些“小的事情”的。

小事是指哪些事情呢?它可能包括:是否在设计/产品/技术文档中进行了精准的表述、文档的格式细节是否正确、每个模块在集成之前是否做了充分的自测、代码中的实例在生命周期结束时其副作用是否被正确清理、类型安全问题、在做复杂客户端应用时经常面临的时序问题等等。

![pic-3](/img/blog/engineering-practice-doing-small-things-well/33333.png)
![pic-3](/img/blog/工程实践分享-把小事做好/33333.png)

无论是文档方面,还是代码方面,这些“小事”暂时不处理似乎也没什么问题,反正项目可以继续、功能也能实现、用户也能使用,但其实,把小事做好,无论是对项目,还是对个人,都是很有意义的。今天,我们主要谈谈,“把小事做好”对个人的积极意义。

Expand Down
23 changes: 16 additions & 7 deletions website/blog/2025-01-19-why-you-should-join-1024-techcamp.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
---
slug: why-you-should-join-1024-techcamp
title: "同学,为什么我建议你关注 1024 实训营?"
authors: [techcamp]
tags: [ai, architecture, best-practices, career, compiler, engineering, go, llgo, xgo]
title: 同学,为什么我建议你关注 1024 实训营?
authors:
- techcamp
tags:
- ai
- architecture
- career
- compiler
- engineering
- go
- llgo
- xgo
date: 2025-01-19
description: "2023 年底,我幸运地通过 1024 创作节获得了参加第一届 1024 实训营的机会,这次经历彻底改变了我对技术学习和职业发展的认知。"
description: 2023 年底,我幸运地通过 1024 创作节获得了参加第一届 1024 实训营的机会,这次经历彻底改变了我对技术学习和职业发展的认知。
---

2023 年底,我幸运地通过 1024 创作节获得了参加第一届 1024 实训营的机会,这次经历彻底改变了我对技术学习和职业发展的认知。

与其他公司的实习不同,七牛云的实训营不是简单地让我们熟悉业务或写代码,而是提供了一个完整的项目实战机会。在实训营中,我们完整经历了技术选型、需求分析、架构梳理、模块拆分、实际编码测试,最终到上线和路演的整个软件开发生命周期。这种全方位的实战体验,让我第一次深刻理解了 1024 实训营"实践驱动成长"的培养理念。

实训过程中最令我印象深刻的是导师们对工程质量的极致追求。一个 PR 经常被来回 review 三四十条 comment,比如 [PR#122](https://github.com/goplus/builder/pull/122) 和 [PR#96](https://github.com/goplus/builder/pull/96)。从前端构建过程到代码实现、从工程规范到部署落地,导师们以几乎"苛刻"的态度对待每一个技术细节。这种严谨的工程文化深深影响了我,至今在我的工作中,我仍然保持着对 PR 质量的高标准要求。
实训过程中最令我印象深刻的是导师们对工程质量的极致追求。一个 PR 经常被来回 review 三四十条 comment,比如 [https://lt;https://github.com/goplus/builder/pull/122\](https://lt;https://github.com/goplus/builder/pull/122\)gt; 和 [https://lt;https://github.com/goplus/builder/pull/96\](https://lt;https://github.com/goplus/builder/pull/96\)gt;。从前端构建过程到代码实现、从工程规范到部署落地,导师们以几乎"苛刻"的态度对待每一个技术细节。这种严谨的工程文化深深影响了我,至今在我的工作中,我仍然保持着对 PR 质量的高标准要求。

![pr-review](/img/blog/why-you-should-join-1024-techcamp/pr-review.png)
![pr-review](/img/blog/同学为什么我建议你关注-1024-实训营/pr-review.png)

在接口设计阶段,导师们也不会简单地告诉我们“应该怎么做”,而是引导我们思考:这个接口的核心需求是什么?未来可能如何演变?当前设计是否存在潜在问题?这种启发式的教学方式培养了我的系统思维能力和前瞻性设计意识,受益匪浅。

Expand All @@ -25,7 +34,7 @@ description: "2023 年底,我幸运地通过 1024 创作节获得了参加第

每一层技术挑战都有实力强悍的导师耐心指导。这种阶梯式的学习路径让每个人都能找到适合自己的成长方向。

目前我正在负责 XGo 的底层编译器 LLGo 的子项目——llcppg,旨在自动生成 C/C++ 库的 LLGo Binding。通过这个项目,我不仅更深入理解了 C 编译器工作原理,也更理解了不同语言在设计其语法特性时的思考,还经常能从这一角的开源实践,窥探到整个软件工程的历史。在开发过程中也经常会得到导师们的经验上的分享、以及在架构设计方面的持续指导,这段经历成为我技术成长的重要里程碑。对于该工程的相关技术细节我专门写了一篇文章分享([https://mp.weixin.qq.com/s/cx9F5lYKyxwvFpokicJ8Yw](https://mp.weixin.qq.com/s/cx9F5lYKyxwvFpokicJ8Yw)),项目代码也已开源在 GitHub([https://github.com/goplus/llcppg](https://github.com/goplus/llcppg)),欢迎沟通交流。
目前我正在负责 XGo 的底层编译器 LLGo 的子项目——llcppg,旨在自动生成 C/C++ 库的 LLGo Binding。通过这个项目,我不仅更深入理解了 C 编译器工作原理,也更理解了不同语言在设计其语法特性时的思考,还经常能从这一角的开源实践,窥探到整个软件工程的历史。在开发过程中也经常会得到导师们的经验上的分享、以及在架构设计方面的持续指导,这段经历成为我技术成长的重要里程碑。对于该工程的相关技术细节我专门写了一篇文章分享([https://lt;https://mp.weixin.qq.com/s/cx9F5lYKyxwvFpokicJ8Yw\](https://lt;https://mp.weixin.qq.com/s/cx9F5lYKyxwvFpokicJ8Yw\)gt;),项目代码也已开源在 GitHub([https://lt;https://github.com/goplus/llcppg\](https://lt;https://github.com/goplus/llcppg\)gt;),欢迎沟通交流。

可以说,实训营的经历直接影响了我现在的工作方式:

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
---
slug: engineer-core-competitiveness-in-ai-era
title: "当 AI 能写代码,工程师的核心竞争力是什么?"
authors: [techcamp]
tags: [ai, architecture, career, engineering]
title: 当 AI 能写代码,工程师的核心竞争力是什么?
authors:
- techcamp
tags:
- ai
- architecture
- career
- engineering
date: 2025-01-21
description: "Programming is changing so fast。"
description: Programming is changing so fast。
---

Programming is changing so fast。
Expand Down
13 changes: 9 additions & 4 deletions website/blog/2025-01-23-qualities-of-excellent-engineers.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
---
slug: qualities-of-excellent-engineers
title: "我眼中的优秀工程师特质"
authors: [techcamp]
tags: [ai, architecture, best-practices, career, engineering]
title: 我眼中的优秀工程师特质
authors:
- techcamp
tags:
- ai
- architecture
- career
- engineering
date: 2025-01-23
description: "在工作中我们会遇到各种各样的工程师,优秀的工程师会让项目的进展更顺利、产品的质量更有保障,与他们的合作也会让人感到愉快。"
description: 在工作中我们会遇到各种各样的工程师,优秀的工程师会让项目的进展更顺利、产品的质量更有保障,与他们的合作也会让人感到愉快。
---

在工作中我们会遇到各种各样的工程师,优秀的工程师会让项目的进展更顺利、产品的质量更有保障,与他们的合作也会让人感到愉快。
Expand Down
14 changes: 9 additions & 5 deletions website/blog/2025-01-25-why-end-files-with-newline.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
---
slug: why-end-files-with-newline
title: "一行之差:为什么你的文件末尾应该留一个空行?"
authors: [techcamp]
tags: [ai, best-practices, engineering, go]
title: 一行之差:为什么你的文件末尾应该留一个空行?
authors:
- techcamp
tags:
- ai
- engineering
- go
date: 2025-01-25
description: "> ![github-no-nl-marker](github-no-nl-marker.png)"
description: '> ![github-no-nl-marker](/img/blog/一行之差为什么你的文件末尾应该留一个空行/github-no-nl-marker.png)'
---

> ![github-no-nl-marker](/img/blog/why-end-files-with-newline/github-no-nl-marker.png)
> ![github-no-nl-marker](/img/blog/一行之差为什么你的文件末尾应该留一个空行/github-no-nl-marker.png)
>
> “咦?怎么 GitHub PR 里多了个 ⛔️ 小红标?”
>
Expand Down
130 changes: 130 additions & 0 deletions website/blog/2025-02-04-github-pr-merge-strategies-which-to-choose.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
---
slug: github-pr-merge-strategies-which-to-choose
title: GitHub PR 合并三选一:主分支该怎么选?
authors:
- techcamp
tags:
- ai
- architecture
- engineering
date: 2025-02-04
description: '> ![GitHub PR merge menu](/img/blog/github-pr-合并三选一主分支该怎么选/github-pr-merge-menu.png)'
---

> ![GitHub PR merge menu](/img/blog/github-pr-合并三选一主分支该怎么选/github-pr-merge-menu.png)
>
> 在每个 PR 的底部,GitHub 都会给出三个合并选择。大多数开发者会习惯性地点击默认选项,但这个看似简单的决定却深刻影响着项目历史。
>
> 今天我们来聊聊:为什么这个选择如此重要,以及为什么我坚持只用其中的一个。

## TL;DR

**对指向主分支的 PR,一律选择 `Squash and merge`。**

配合 [rulesets](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/about-rulesets) 开启 [`Require linear history`](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets#require-linear-history),把线性历史与回滚边界制度化,从源头避免误操作。

## 核心原则:one PR, one commit

**一个 PR 最终只对应主分支上的一个 commit。**

PR 内部发生的多个 commits 都是开发阶段的中间态。历史被合并进主分支的那一刻,维护者更关心“结果”,也就是合并时那个版本的变更。需要更细的过程与讨论,可以通过 commit message 中的 PR 链接进入 PR 页面回看所有细节。

这个原则与 GitHub 的 `Squash and merge` 天然契合:一件事,一个节点,边界清晰。

## 三种方式全面对比

| 维度 | Create a merge commit | Rebase and merge | Squash and merge |
|------|-----------------------|------------------|------------------|
| **历史结构** | 产生 merge commit,主分支出现分叉 | 把 PR 的每个 commit 接到主分支,历史线性 | 把整个 PR 压成一个 commit 进入主分支,历史线性 |
| **协作影响** | 图谱更杂,阅读与 bisect 成本上升 | 改写 commit hashes,评论锚点与外部引用容易受影响 | 主分支整洁,release notes 更直观,审计与回滚成本更低 |
| **代码审计** | 需要追踪分支拓扑,复杂度高 | Commit hash 变化影响引用 | 线性历史,一目了然 |
| **版本回滚** | `git revert -m` 回滚合并节点,语义复杂 | 可逐条或成组回滚 | `git revert <squash_hash>` 一键整块撤回 |
| **Git bisect** | 在合并点容易困惑 | 可能命中中间态 | 每个 commit 都是完整功能态 |
| **生成 changelog** | 混合修修补补的小 commits | 同样包含中间 commits | 直接基于 PR 生成,语义清晰 |

**本文主张**:主分支只接受 `Squash and merge`。

## 为什么选择 `Squash and merge`

基于上面的对比分析,`Squash and merge` 的核心优势在于:
- **历史整洁**:线性历史,加上一个 PR 一个 commit,主分支成为清晰的时间轴
- **操作简单**:回滚用 `git revert <squash_hash>`,发布用 PR 生成 changelog,边界明确
- **协作友好**:避免已存在 commit 的 hash 被重写,保持评论和审计完整性

这些优势让 `Squash and merge` 成为团队协作的最佳选择。

## 潜在担忧与应对

### 信息粒度损失

Squash 会丢失分支内的细粒度 commits。

**解决方案**:在合并对话框里写好一条高质量的 commit message,正文包含动机、设计取舍、风险与兼容性影响、迁移指引,并保留 `Co-authored-by`。细粒度历史保存在 PR 页面,随时可溯源。

### 复杂功能的开发过程追踪

对于包含多个开发阶段的复杂功能,有些团队希望保留详细的开发轨迹。

**解决方案**:建议将复杂功能拆分成多个独立 PR。如需保留内部开发结构,可在长期功能分支或发布分支间使用 merge commit,主分支仍用 squash 保持整洁。

## 配置指南

### 个人项目配置

如果是项目 owner,可以直接在仓库设置中限制合并方式:
1. 进入仓库的 `Settings -> General -> Pull Requests`
2. 勾选 `Allow squash merging`
3. 取消 `Allow merge commits`
4. 取消 `Allow rebase merging`

### 团队项目强制约束

对于团队协作,建议使用 rulesets 进行强制约束:
1. **创建分支保护规则**
- 进入仓库的 `Settings -> Rules -> Rulesets -> New branch ruleset`
- 勾选 `Require linear history` 强制线性历史
2. **应用到目标分支**
- 将创建的规则应用到主分支或使用匹配模式覆盖多个分支

### Commit message 编写规范

- **标题**:使用 PR 标题,简洁描述变更内容
- **正文**:详细说明变更动机、技术方案、潜在风险和迁移指引
- **溯源信息**:保留 PR 链接和 `Co-authored-by` 列表,便于追溯
- **格式约定**:如团队使用 [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/),请遵循相应格式

### 问题回滚方案

- **图形界面**:在 PR 页面点击 `Revert` 按钮,自动生成回滚 PR
- **命令行操作**:执行 `git revert <squash_hash>`,然后创建新 PR 提交回滚

## 常见问题与解决方案

### Q:为什么不选择同样线性的 `Rebase and merge`?

**A**:Rebase 会在合并时改写 commit hashes,容易打断评论锚点、外部引用和审计链。将 rebase 的复杂性留在分支阶段更稳妥,主分支只接受最终结果。

### Q:`Squash and merge` 会丢失贡献者信息吗?

**A**:不会。在合并对话框中使用 `Co-authored-by` 即可保留所有贡献者信息,PR 页面也会完整保存讨论记录和检查结果。

### Q:现有项目已有很多 merge commits,如何迁移?

**A**:新规则只影响未来的 commits。建议先为主分支启用 ruleset,在新 PR 中采用 squash,不要重写已有历史以免影响协作。

### Q:团队成员习惯了 `Create a merge commit`,怎么推动改变?

**A**:建议分步推进:
1. 分享线性历史的好处和实际案例
2. 先在新项目中试验 squash-only 策略
3. 为现有项目设定一个切换时间点,提前通知所有成员

## 今天就行动起来

**主分支是团队的时间轴,让它保持清晰。**

复杂的开发过程留在分支中讨论,最终的成果用一个明确的 commit 记录在主分支上。这不仅是技术规范,更是对未来维护者的尊重。

现在就打开你的项目设置页面,将合并方式调整为 squash-only,你的团队(和未来的自己)会感谢你。

**记住:one PR, one commit. Keep master clean.**
Loading