<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[Heck's  Blog]]></title> 
<link>https://www.heckjj.com/index.php</link> 
<description><![CDATA[一瞬间的决定，往往可以改变很多，事实上，让自己成功的往往不是知识，是精神！ 如果你总是为自己找借口，那只好让成功推迟。执行力，今天！]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[Heck's  Blog]]></copyright>
<item>
<link>https://www.heckjj.com/post/686/</link>
<title><![CDATA[Git不同服务器配置不同身份]]></title> 
<author>Heck &lt;@hecks.tk&gt;</author>
<category><![CDATA[运维管理]]></category>
<pubDate>Thu, 21 May 2026 01:48:34 +0000</pubDate> 
<guid>https://www.heckjj.com/post/686/</guid> 
<description>
<![CDATA[ 
	# 你的默认全局账号<br/>[user]<br/>&nbsp;&nbsp;name = heck<br/>&nbsp;&nbsp;email = i@heckjj.com<br/><br/># ======================<br/># 自动切换 heckjj 账号<br/># ======================<br/>[includeIf &quot;hasconfig:remote.*.url:https://git.tencent.com/**&quot;]<br/>&nbsp;&nbsp;path = .gitconfig-tencent<br/><br/>最后一步：必须新建这个文件<br/>打开文件夹：C:&#92;Users&#92;你的用户名&#92;<br/>新建一个文件，名字叫：<br/>.gitconfig-tencent<br/>内容只有这两行：<br/>[user]<br/>&nbsp;&nbsp;name = heck<br/>&nbsp;&nbsp;email = heck@tencent.com<br/><br/>这样就自动生效了<br/>所有 git.tencent.com 仓库 → 自动用 heck<br/>其他所有仓库 → 用你的默认账号 heck<br/>不用手动切换，不用每个仓库单独设置<br/>
]]>
</description>
</item><item>
<link>https://www.heckjj.com/post/685/</link>
<title><![CDATA[Conventional Commits 常见规范]]></title> 
<author>Heck &lt;@hecks.tk&gt;</author>
<category><![CDATA[运维管理]]></category>
<pubDate>Mon, 18 May 2026 08:53:34 +0000</pubDate> 
<guid>https://www.heckjj.com/post/685/</guid> 
<description>
<![CDATA[ 
	`git feat` 是指在 Git 提交（commit）信息中使用 `feat` 作为前缀，它是英文 “feature”（新功能）的缩写，用于标识本次提交新增了一个功能或特性。<br/><br/>这一用法源于 [Conventional Commits（约定式提交）](https://www.conventionalcommits.org/) 规范，该规范通过标准化提交信息格式，提升团队协作效率，并便于自动生成变更日志（changelog）和版本号管理。<br/><br/>---<br/><br/>常见提交类型前缀含义<br/><br/>- `feat`：新增功能（feature）&nbsp;&nbsp;<br/>&nbsp;&nbsp;示例：`feat: 添加用户登录功能`<br/>- `fix`：修复 bug&nbsp;&nbsp;<br/>&nbsp;&nbsp;示例：`fix: 修复登录超时问题`<br/>- `docs`：仅修改文档&nbsp;&nbsp;<br/>&nbsp;&nbsp;示例：`docs: 更新 README 使用说明`<br/>- `style`：代码样式调整（不影响运行）&nbsp;&nbsp;<br/>&nbsp;&nbsp;示例：`style: 格式化代码缩进`<br/>- `refactor`：代码重构（非新增功能、非修复 bug）&nbsp;&nbsp;<br/>&nbsp;&nbsp;示例：`refactor: 提取用户验证逻辑为独立函数`<br/>- `chore`：构建过程或工具依赖更新&nbsp;&nbsp;<br/>&nbsp;&nbsp;示例：`chore: 更新 npm 依赖包`<br/>- `test`：增加或修改测试&nbsp;&nbsp;<br/>&nbsp;&nbsp;示例：`test: 添加登录接口单元测试`<br/><br/>---<br/><br/>提交信息结构（Conventional Commits）<br/><br/>标准格式为：<br/><br/>```<br/><type>(<scope>): <subject><br/>[body]<br/>[footer]<br/>```<br/><br/>- `type`：必须，如 `feat`、`fix` 等&nbsp;&nbsp;<br/>- `scope`：可选，限定影响范围，如 `(auth)`、`(api)`&nbsp;&nbsp;<br/>- `subject`：简短描述（≤50 字符）&nbsp;&nbsp;<br/>- `body` / `footer`：可选，详细说明或关联 issue<br/><br/>示例完整写法：<br/><br/>```bash<br/>feat(auth): 添加 Google OAuth 登录支持<br/><br/>- 允许用户通过 Google 账号一键登录<br/>- 集成 OAuth2.0 流程<br/>- 关联 JIRA-123<br/>```<br/><br/>---<br/><br/>实践意义<br/><br/>- ✅ 提高可读性：团队成员快速理解提交目的&nbsp;&nbsp;<br/>- ✅ 支持自动化：工具（如 `semantic-release`）可依据 `feat` 自动升级版本号&nbsp;&nbsp;<br/>- ✅ 便于生成 changelog：按类型分类生成发布说明&nbsp;&nbsp;<br/><br/>更多规范细节可参考：[Conventional Commits 官方规范](https://www.conventionalcommits.org/)
]]>
</description>
</item><item>
<link>https://www.heckjj.com/post/684/</link>
<title><![CDATA[团队 Git 使用规范]]></title> 
<author>Heck &lt;@hecks.tk&gt;</author>
<category><![CDATA[运维管理]]></category>
<pubDate>Mon, 18 May 2026 08:29:14 +0000</pubDate> 
<guid>https://www.heckjj.com/post/684/</guid> 
<description>
<![CDATA[ 
	本文档定义了团队使用 Git 的标准流程和规范，所有团队成员必须遵循。<br/><br/>版本：v1.0.0<br/>最后更新：2026年<br/>适用范围：所有项目 <br/><br/>目录<br/>分支管理规范<br/>提交信息规范<br/>工作流程规范<br/>代码审查规范<br/>命名规范<br/>安全规范<br/>工具与配置<br/>常见场景处理<br/>1. 分支管理规范<br/>1.1 分支类型<br/>主分支（Main Branches）<br/>main / master<br/><br/>用途：生产环境代码<br/>保护：✅ 必须通过 Pull Request 合并<br/>禁止：❌ 禁止直接推送，禁止强制推送<br/>develop<br/><br/>用途：开发环境代码，日常开发集成<br/>保护：✅ 必须通过 Pull Request 合并<br/>禁止：❌ 禁止直接推送<br/>辅助分支（Supporting Branches）<br/>feature/* - 功能开发分支<br/><br/>命名：feature/功能名称，如 feature/user-login<br/>来源：从 develop 创建<br/>目标：合并回 develop<br/>生命周期：功能完成后删除<br/>fix/* - Bug 修复分支<br/><br/>命名：fix/问题描述，如 fix/login-button-bug<br/>来源：从 develop 创建<br/>目标：合并回 develop<br/>生命周期：修复完成后删除<br/>hotfix/* - 紧急修复分支<br/><br/>命名：hotfix/紧急修复描述，如 hotfix/security-patch<br/>来源：从 main 创建<br/>目标：合并回 main 和 develop<br/>生命周期：修复完成后删除<br/>release/* - 发布准备分支<br/><br/>命名：release/版本号，如 release/1.0.0<br/>来源：从 develop 创建<br/>目标：合并回 main 和 develop<br/>生命周期：发布完成后删除<br/>1.2 分支命名规则<br/>✅ 允许的命名：<br/><br/>使用小写字母<br/>使用连字符 - 分隔单词<br/>简洁但描述性<br/>示例：feature/user-authentication、fix/payment-error<br/>❌ 禁止的命名：<br/><br/>使用大写字母<br/>使用下划线或空格<br/>使用个人名称<br/>使用特殊字符<br/>示例：Feature/Login、fix_bug、zhangsan-feature<br/>1.3 分支保护规则<br/>main 分支保护<br/>✅ 必须通过 Pull Request 合并<br/>✅ 至少 1 位团队成员审查通过<br/>✅ 必须通过所有 CI/CD 检查<br/>✅ 禁止直接推送<br/>✅ 禁止强制推送<br/>✅ 禁止删除分支<br/>develop 分支保护<br/>✅ 必须通过 Pull Request 合并<br/>✅ 至少 1 位团队成员审查通过<br/>✅ 必须通过所有 CI/CD 检查<br/>✅ 禁止直接推送<br/>✅ 禁止强制推送<br/>2. 提交信息规范<br/>2.1 提交信息格式<br/>&lt;类型&gt;(&lt;范围&gt;): &lt;简短描述&gt;<br/><br/>&lt;详细描述（可选）&gt;<br/><br/>&lt;相关 Issue（可选）&gt;<br/><br/>2.2 类型（Type）<br/>类型&nbsp;&nbsp;说明&nbsp;&nbsp;示例<br/>feat&nbsp;&nbsp;新功能&nbsp;&nbsp;feat(用户): 添加用户登录功能<br/>fix&nbsp;&nbsp;修复 Bug&nbsp;&nbsp;fix(登录): 修复登录按钮点击无效的问题<br/>docs&nbsp;&nbsp;文档更新&nbsp;&nbsp;docs: 更新 API 文档<br/>style&nbsp;&nbsp;代码格式调整&nbsp;&nbsp;style: 修复代码缩进问题<br/>refactor&nbsp;&nbsp;代码重构&nbsp;&nbsp;refactor(服务): 重构用户服务层<br/>perf&nbsp;&nbsp;性能优化&nbsp;&nbsp;perf(数据库): 优化查询性能<br/>test&nbsp;&nbsp;测试相关&nbsp;&nbsp;test: 添加登录功能单元测试<br/>chore&nbsp;&nbsp;构建/工具相关&nbsp;&nbsp;chore: 更新依赖包版本<br/>ci&nbsp;&nbsp;CI/CD 配置&nbsp;&nbsp;ci: 添加自动化测试流程<br/>2.3 范围（Scope）<br/>范围是可选的，用于标识提交影响的部分：<br/><br/>模块名：feat(用户): ...<br/>文件名：fix(api.js): ...<br/>组件名：feat(登录): ...<br/>2.4 提交信息示例<br/>✅ 好的提交信息：<br/><br/>feat(用户): 添加用户注册功能<br/><br/>实现了用户注册的完整流程：<br/>- 添加注册表单验证<br/>- 实现邮箱验证功能<br/>- 添加密码加密存储<br/><br/>Closes #123<br/>fix(支付): 修复支付接口超时问题<br/><br/>修复了支付接口在高峰期超时的问题，增加重试机制。<br/><br/>Fixes #456<br/>❌ 不好的提交信息：<br/><br/>更新代码<br/>修复bug<br/>提交<br/>WIP<br/><br/>2.5 提交频率<br/>✅ 推荐：小步提交，完成一个小功能就提交<br/>✅ 推荐：每个提交解决一个问题<br/>❌ 禁止：大量不相关的更改放在一个提交中<br/>❌ 禁止：提交无法编译或测试失败的代码<br/>3. 工作流程规范<br/>3.1 日常开发流程<br/>开始新功能<br/># 1. 确保 develop 分支是最新的<br/>git checkout develop<br/>git pull origin develop<br/><br/># 2. 创建功能分支<br/>git checkout -b feature/user-login<br/><br/># 3. 开始开发<br/># ... 编写代码 ...<br/>开发过程<br/># 1. 查看修改状态<br/>git status<br/><br/># 2. 添加修改到暂存区<br/>git add .<br/><br/># 3. 提交更改<br/>git commit -m &quot;feat(用户): 实现登录功能&quot;<br/><br/># 4. 定期推送到远程<br/>git push origin feature/user-login<br/>完成功能<br/># 1. 确保代码通过测试<br/>npm test<br/><br/># 2. 确保代码符合规范<br/>npm run lint<br/><br/># 3. 推送到远程<br/>git push origin feature/user-login<br/><br/># 4. 在平台创建 Pull Request<br/><br/>3.2 Pull Request 流程<br/>创建 Pull Request<br/>填写信息：<br/><br/>清晰的标题<br/>详细的描述<br/>关联相关 Issue<br/>添加截图（如适用）<br/>检查清单：<br/><br/> 代码已通过测试<br/> 已更新相关文档<br/> 已遵循代码规范<br/> 无控制台错误<br/> 已关联相关 Issue<br/>请求审查：<br/><br/>指定至少 1 位审查者<br/>添加相关标签<br/>Pull Request 模板<br/>## ???? 变更描述<br/>简要描述本次 PR 的变更内容<br/><br/>## ???? 变更类型<br/>- [ ] 新功能 (feat)<br/>- [ ] Bug 修复 (fix)<br/>- [ ] 文档更新 (docs)<br/>- [ ] 代码重构 (refactor)<br/>- [ ] 性能优化 (perf)<br/>- [ ] 测试相关 (test)<br/>- [ ] 其他 (chore)<br/><br/>## ???? 测试说明<br/>描述如何测试这些变更<br/><br/>## ???? 截图（如适用）<br/>添加相关截图或演示<br/><br/>## ✅ 检查清单<br/>- [ ] 代码已通过测试<br/>- [ ] 已更新相关文档<br/>- [ ] 已遵循代码规范<br/>- [ ] 无控制台错误<br/>- [ ] 已关联相关 Issue<br/><br/>## ???? 相关 Issue<br/>Closes #123<br/><br/>3.3 代码审查流程<br/>审查者职责<br/>及时响应：24 小时内响应审查请求<br/><br/>仔细审查：<br/><br/>代码功能正确性<br/>代码质量和风格<br/>性能和安全问题<br/>测试覆盖<br/>提供反馈：<br/><br/>建设性的意见<br/>具体的改进建议<br/>必要时提供代码示例<br/>提交者职责<br/>及时回复：及时回复审查意见<br/>积极修改：根据反馈修改代码<br/>保持沟通：对审查意见有疑问及时沟通<br/>3.4 合并后清理<br/># 1. 切换到主分支<br/>git checkout develop<br/>git pull origin develop<br/><br/># 2. 删除本地分支<br/>git branch -d feature/user-login<br/><br/># 3. 删除远程分支（如果 PR 合并时未自动删除）<br/>git push origin --delete feature/user-login<br/><br/>4. 代码审查规范<br/>4.1 审查检查清单<br/> 功能正确性：代码实现了预期功能<br/> 代码质量：代码清晰、可读、可维护<br/> 代码风格：遵循团队代码规范<br/> 性能：没有明显的性能问题<br/> 安全性：没有安全漏洞<br/> 错误处理：错误处理完善<br/> 测试：有足够的测试覆盖<br/> 文档：必要文档已更新<br/>4.2 审查意见格式<br/>✅ 好的审查意见：<br/><br/>这里可以优化一下，使用更简洁的方式：<br/><br/>```javascript<br/>// 当前代码<br/>const result = array.filter(item =&gt; item &gt; 0).map(item =&gt; item * 2);<br/><br/>// 建议<br/>const result = array.reduce((acc, item) =&gt; &#123;<br/>&nbsp;&nbsp;if (item &gt; 0) acc.push(item * 2);<br/>&nbsp;&nbsp;return acc;<br/>&#125;, []);<br/><br/>❌ 不好的审查意见：<br/><br/>这个不对<br/>不好<br/>需要改<br/><br/>4.3 审查状态<br/>✅ 批准（Approve）：代码可以合并<br/>⚠️ 需要修改（Request Changes）：需要修改后才能合并<br/>???? 评论（Comment）：有疑问或建议，但不阻止合并<br/>5. 命名规范<br/>5.1 分支命名<br/>见 分支管理规范<br/><br/>5.2 提交信息命名<br/>见 提交信息规范<br/><br/>5.3 文件命名<br/>使用小写字母<br/>使用连字符或下划线分隔<br/>避免使用空格和特殊字符<br/>示例：user-service.js、user_model.py<br/>6. 安全规范<br/>6.1 敏感信息管理<br/>❌ 禁止提交：<br/><br/>密码、密钥、Token<br/>API 密钥<br/>数据库连接字符串<br/>个人隐私信息<br/>配置文件中的敏感信息<br/>✅ 正确做法：<br/><br/>使用环境变量<br/>使用 .gitignore 排除敏感文件<br/>使用密钥管理服务<br/>提供 .env.example 模板<br/>6.2 .gitignore 配置<br/># 环境变量<br/>.env<br/>.env.local<br/>.env.*.local<br/><br/># 密钥和证书<br/>*.key<br/>*.pem<br/>*.cert<br/>secrets/<br/>*.secret<br/><br/># 配置文件<br/>config/production.json<br/>config/local.json<br/><br/># 日志文件<br/>*.log<br/>logs/<br/><br/># 临时文件<br/>*.tmp<br/>*.temp<br/>*.cache<br/><br/><br/>6.3 访问控制<br/>使用 SSH Keys 而非密码<br/>定期轮换访问密钥<br/>遵循最小权限原则<br/>离职员工及时撤销权限<br/>7. 工具与配置<br/>7.1 必需工具<br/>Git：版本 &gt;= 2.30.0<br/>代码托管平台：GitHub / GitLab / Gitee<br/>代码审查工具：平台内置或第三方工具<br/>7.2 推荐工具<br/>Git GUI：SourceTree、GitKraken、GitHub Desktop<br/>IDE 集成：VS Code、WebStorm、IntelliJ IDEA<br/>提交信息检查：commitlint、husky<br/>7.3 Git 配置<br/># 设置用户信息<br/>git config --global user.name &quot;你的姓名&quot;<br/>git config --global user.email &quot;your.email@example.com&quot;<br/><br/># 设置默认编辑器<br/>git config --global core.editor &quot;code --wait&quot;<br/><br/># 设置默认分支名<br/>git config --global init.defaultBranch main<br/><br/># 启用颜色输出<br/>git config --global color.ui true<br/><br/># 设置推送行为<br/>git config --global push.default simple<br/><br/>8. 常见场景处理<br/>8.1 处理合并冲突<br/>拉取最新代码：git pull origin develop<br/>查看冲突文件：git status<br/>手动解决冲突<br/>标记已解决：git add &lt;file&gt;<br/>完成合并：git commit<br/>8.2 紧急修复（Hotfix）<br/># 1. 从 main 创建 hotfix 分支<br/>git checkout main<br/>git pull origin main<br/>git checkout -b hotfix/critical-bug<br/><br/># 2. 修复问题并提交<br/>git add .<br/>git commit -m &quot;fix: 修复紧急问题&quot;<br/>git push origin hotfix/critical-bug<br/><br/># 3. 创建 Pull Request 合并到 main<br/><br/># 4. 合并后同步到 develop<br/>git checkout develop<br/>git merge main<br/>git push origin develop<br/><br/>8.3 撤销误提交<br/># 撤销未推送的提交<br/>git reset --soft HEAD~1&nbsp;&nbsp;# 保留更改在暂存区<br/>git reset HEAD~1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # 保留更改在工作区<br/>git reset --hard HEAD~1&nbsp;&nbsp;# 丢弃所有更改（危险！）<br/><br/># 撤销已推送的提交（推荐使用 revert）<br/>git revert HEAD<br/>git push origin branch-name<br/><br/>8.4 保存临时更改<br/># 保存当前更改<br/>git stash<br/><br/># 查看保存的更改<br/>git stash list<br/><br/># 恢复更改<br/>git stash pop<br/><br/>9. 违规处理<br/>9.1 违规行为<br/>❌ 直接推送到保护分支<br/>❌ 强制推送到共享分支<br/>❌ 提交无法编译的代码<br/>❌ 提交敏感信息<br/>❌ 使用不规范的分支命名<br/>❌ 提交信息不规范<br/>9.2 处理措施<br/>第一次：提醒并指导正确做法<br/>多次违规：团队内讨论，必要时限制权限<br/>严重违规：影响项目安全或稳定性时，立即处理<br/>10. 更新与维护<br/>10.1 规范更新<br/>规范的更新需要团队讨论通过<br/>更新后及时通知所有成员<br/>更新版本号和日期<br/>10.2 培训<br/>新成员入职时进行 Git 规范培训<br/>定期组织 Git 使用技巧分享<br/>提供详细的文档和示例<br/>附录<br/>A. 快速参考<br/># 开始新功能<br/>git checkout develop &amp;&amp; git pull &amp;&amp; git checkout -b feature/name<br/><br/># 提交更改<br/>git add . &amp;&amp; git commit -m &quot;feat: 描述&quot; &amp;&amp; git push<br/><br/># 同步主分支<br/>git checkout develop &amp;&amp; git pull origin develop<br/><br/># 查看状态<br/>git status &amp;&amp; git log --oneline -5<br/><br/>B. 相关文档<br/>Git 基础入门<br/>团队协作基础<br/>团队协作注意事项<br/>进阶技巧与最佳实践<br/>推荐团队实践<br/>C. 联系方式<br/>如有问题或建议，请联系：<br/><br/>团队负责人：xxx<br/>技术负责人：xxx<br/>文档维护：xxx<br/>
]]>
</description>
</item><item>
<link>https://www.heckjj.com/post/683/</link>
<title><![CDATA[Git多分支规范]]></title> 
<author>Heck &lt;@hecks.tk&gt;</author>
<category><![CDATA[运维管理]]></category>
<pubDate>Mon, 18 May 2026 08:17:27 +0000</pubDate> 
<guid>https://www.heckjj.com/post/683/</guid> 
<description>
<![CDATA[ 
	一、什么是Git分支管理？<br/>Git分支管理是指在Git版本控制系统中，通过创建和管理多个分支来组织代码开发流程，支持并行开发、代码隔离和版本控制。<br/>简单说，就像一棵树的主干和分支，master分支是主干，feature分支是枝叶，每个分支都可以独立生长，最后再合并到主干。<br/>其核心作用包括：<br/>&nbsp;&nbsp;<br/>• 并行开发：多个功能可以同时开发而不相互干扰。<br/>&nbsp;&nbsp;<br/>• 代码隔离：开发分支、测试分支、生产分支相互隔离。<br/>&nbsp;&nbsp;<br/>• 版本管理：支持版本回退、热修复和发布管理。<br/>&nbsp;&nbsp;<br/>• 团队协作：多人协作时减少代码冲突。<br/>&nbsp;&nbsp;<br/>二、分支类型说明<br/>2.1 长期存在分支（核心基础分支）<br/>master 主分支<br/>&nbsp;&nbsp;<br/>• 定位：生产环境分支，存放已发布的稳定、可靠版本代码。<br/>&nbsp;&nbsp;<br/>• 核心规则：仅用于发布新版本，禁止直接修改或提交新功能。<br/>&nbsp;&nbsp;<br/>develop 开发分支<br/>&nbsp;&nbsp;<br/>• 定位：日常开发主分支，汇总当前所有正在推进的功能和任务。<br/>&nbsp;&nbsp;<br/>• 核心规则：所有新功能开发、改进、优化均从该分支发起，完成后最终合并回此分支。<br/>&nbsp;&nbsp;<br/>2.2 临时创建分支（辅助开发/发布分支，完成后删除）<br/>feature 功能分支<br/>&nbsp;&nbsp;<br/>• 创建来源：从 develop 分支创建，功能分支的名字，可以采用feature-*的形式命名<br/>&nbsp;&nbsp;<br/>• 用途：单独开发某一个新功能（一个功能对应一个分支）<br/>&nbsp;&nbsp;<br/>• 流转终点：功能实现、测试完成后，合并回 develop 分支<br/>&nbsp;&nbsp;<br/>release 发布分支（不一定用）<br/>&nbsp;&nbsp;<br/>• 创建来源：从 develop 分支创建<br/>&nbsp;&nbsp;<br/>• 用途：为即将发布的版本做最终准备，仅开展测试、bug修复、文档检查等工作（不新增功能）<br/>&nbsp;&nbsp;<br/>• 流转终点：准备完成且测试通过后，同时合并回 master 分支（作为新发布版本）和 develop 分支（同步发布前的修复内容）<br/>&nbsp;&nbsp;<br/>hotfix 紧急修复分支<br/>&nbsp;&nbsp;<br/>• 创建来源：从 master 分支创建<br/>&nbsp;&nbsp;<br/>• 用途：紧急修复生产环境（master 分支对应版本）中出现的问题<br/>&nbsp;&nbsp;<br/>• 流转终点：修复完成后，同时合并回 master 分支（更新生产版本）和 develop 分支（同步修复内容，避免后续版本复现问题）<br/>&nbsp;&nbsp;<br/>三、业务流程图<br/>sequenceDiagram<br/>&nbsp;&nbsp;&nbsp;&nbsp;participant M as Master分支<br/>&nbsp;&nbsp;&nbsp;&nbsp;participant D as Develop分支<br/>&nbsp;&nbsp;&nbsp;&nbsp;participant F as Features功能分支<br/>&nbsp;&nbsp;&nbsp;&nbsp;participant B as Bugfix缺陷分支<br/>&nbsp;&nbsp;&nbsp;&nbsp;participant DT as 开发测试环境<br/>&nbsp;&nbsp;&nbsp;&nbsp;participant PT as 生产测试环境<br/>&nbsp;&nbsp;&nbsp;&nbsp;%% 功能开发流程（标注关键测试节点）<br/>&nbsp;&nbsp;&nbsp;&nbsp;note over M,D: 功能开发阶段<br/>&nbsp;&nbsp;&nbsp;&nbsp;M->>D: 从master初始化develop分支<br/>&nbsp;&nbsp;&nbsp;&nbsp;D->>F: 基于develop创建功能分支<br/>&nbsp;&nbsp;&nbsp;&nbsp;F->>DT: 开发完成→直接发布到开发测试环境（第一轮测试）<br/>&nbsp;&nbsp;&nbsp;&nbsp;note over F,DT: 开发联调阶段<br/>&nbsp;&nbsp;&nbsp;&nbsp;DT->>F: 反馈联调问题<br/>&nbsp;&nbsp;&nbsp;&nbsp;F->>F: 在功能分支修复问题<br/>&nbsp;&nbsp;&nbsp;&nbsp;F->>D: 修复完成→合并到develop分支<br/>&nbsp;&nbsp;&nbsp;&nbsp;D->>DT: 合并后→再次发布到开发测试环境（第二轮验证）<br/>&nbsp;&nbsp;&nbsp;&nbsp;DT->>F: 开发测试通过<br/>&nbsp;&nbsp;&nbsp;&nbsp;F->>M: 功能分支合并到master分支<br/>&nbsp;&nbsp;&nbsp;&nbsp;M->>PT: master发布到生产测试环境<br/>&nbsp;&nbsp;&nbsp;&nbsp;%% 缺陷修复流程（标注合并develop再测试）<br/>&nbsp;&nbsp;&nbsp;&nbsp;note over M,PT: 缺陷修复阶段<br/>&nbsp;&nbsp;&nbsp;&nbsp;PT->>M: 反馈生产测试缺陷问题<br/>&nbsp;&nbsp;&nbsp;&nbsp;M->>B: 基于master创建Bugfix缺陷分支<br/>&nbsp;&nbsp;&nbsp;&nbsp;B->>B: 在Bugfix分支修复缺陷问题<br/>&nbsp;&nbsp;&nbsp;&nbsp;B->>D: Bugfix分支→合并缺陷修复到develop<br/>&nbsp;&nbsp;&nbsp;&nbsp;D->>DT: 合并后→发布到开发测试环境联调<br/>&nbsp;&nbsp;&nbsp;&nbsp;DT->>D: 缺陷联调测试通过<br/>&nbsp;&nbsp;&nbsp;&nbsp;D->>M: develop→合并缺陷修复到master<br/>&nbsp;&nbsp;&nbsp;&nbsp;M->>PT: master再次发布到生产测试验收<br/>&nbsp;&nbsp;&nbsp;&nbsp;M->>M: 验收通过，创建版本标签<br/><a href="https://www.heckjj.com/attachment.php?fid=269" target="_blank"><img src="https://www.heckjj.com/attachment.php?fid=269" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/>四、常见分支策略<br/>&nbsp;&nbsp;<br/>• master：生产环境代码，标签标记版本<br/>&nbsp;&nbsp;<br/>• develop：开发主分支，集成功能分支<br/>&nbsp;&nbsp;<br/>• feature：功能开发分支，从develop创建<br/>&nbsp;&nbsp;<br/>• release：发布准备分支，从develop/master创建<br/>&nbsp;&nbsp;<br/>• hotfix：紧急修复分支，从master创建<br/>&nbsp;&nbsp;<br/>五、分支命名规范<br/>&nbsp;&nbsp;<br/>• 功能分支：feature/功能名称 或 feature/issue-id-功能描述<br/>&nbsp;&nbsp;<br/>• 发布分支：release/v1.2.0 或 release/2027-01-01<br/>&nbsp;&nbsp;<br/>• 热修复分支：hotfix/bug-id 或 hotfix/紧急修复描述<br/>&nbsp;&nbsp;<br/>• 开发分支：develop 或 development<br/>&nbsp;&nbsp;<br/>六、互联网大厂Git工作流实战 devops<br/><a href="https://www.heckjj.com/attachment.php?fid=270" target="_blank"><img src="https://www.heckjj.com/attachment.php?fid=270" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/>七、分支管理最佳实践<br/>&nbsp;&nbsp;<br/>• 分支生命周期管理：及时删除已合并的分支<br/>&nbsp;&nbsp;<br/>• 保护主分支：通过分支保护规则防止直接推送<br/>• 代码审查：所有合并都需要Pull Request和审查<br/>• 定期同步：保持分支与主分支的同步<br/>&nbsp;&nbsp;<br/>• 标签管理：重要版本打tag标记<br/>&nbsp;&nbsp;<br/>八、Git多分支实战和代码合并规范讲解<br/>8.1 Git分支基本操作实战<br/># 查看当前分支<br/>git branch<br/># 创建新分支（基于当前分支）<br/>git branch feature/user-login<br/># 创建并切换到新分支<br/>git checkout -b feature/user-login<br/># 基于指定分支创建新分支<br/>git checkout -b feature/payment develop<br/># 查看所有分支（包括远程）<br/>git branch -a<br/>8.2 分支工作流完整演练<br/>功能开发工作流<br/># 1. 从develop分支创建功能分支<br/>git checkout develop<br/>git pull origin develop<br/>git checkout -b feature/user-registration<br/># 2. 开发功能并提交<br/># ... 开发代码 ...<br/>git add .<br/>git commit -m "feat: 增加用户注册功能"<br/># 3. 推送分支到远程<br/>git push origin feature/user-registration<br/># 4. 创建Pull Request/Merge Request<br/># 在GitHub/GitLab上创建PR<br/># 5. 同步最新代码<br/>git checkout develop<br/>git pull origin develop<br/>git checkout feature/user-registration<br/># 6. 解决可能的冲突<br/># ... 解决冲突 ...<br/># 7. 推送更新后的分支<br/>git push origin feature/user-registration --force-with-lease<br/>紧急修复工作流<br/># 1. 从master创建热修复分支<br/>git checkout master<br/>git pull origin master<br/>git checkout -b hotfix/critical-bug-fix<br/># 2. 修复bug<br/># ... 修复代码 ...<br/>git add .<br/>git commit -m "fix: 解决严重的授权问题"<br/># 3. 同时合并到master和develop<br/>git checkout master<br/>git merge hotfix/critical-bug-fix<br/>git push origin master<br/>git checkout develop<br/>#将热修复代码合并到develop分支，同步修复逻辑到开发分支。<br/>git merge hotfix/critical-bug-fix<br/>git push origin develop<br/># 4. 删除热修复分支<br/>git branch -d hotfix/critical-bug-fix<br/>代码合并规范说明<br/>提交信息规范<br/># 格式：type(scope): description<br/>git commit -m "feat(授权): 增加JWT授权验证"<br/># 常用type：<br/># feat: 新功能<br/># fix: 修复bug<br/># docs: 文档更新<br/># style: 代码格式调整<br/># refactor: 代码重构<br/># test: 测试相关<br/>分支命名规范<br/>&nbsp;&nbsp;<br/>• 功能分支：feature/功能名称 或 feature/issue-123-user-login<br/>&nbsp;&nbsp;<br/>• 修复分支：fix/bug描述 或 fix/issue-456-data-validation<br/>&nbsp;&nbsp;<br/>• 发布分支：release/v1.2.0<br/>&nbsp;&nbsp;<br/>• 热修复：hotfix/紧急修复描述<br/>&nbsp;&nbsp;<br/>合并请求规范<br/>• 标题清晰描述变更内容<br/>&nbsp;&nbsp;<br/>• 详细描述变更原因和影响<br/>&nbsp;&nbsp;<br/>• 关联相关issue或需求<br/>&nbsp;&nbsp;<br/>• 提供测试说明和验证步骤<br/>Tags - <a href="https://www.heckjj.com/tags/git/" rel="tag">git</a>
]]>
</description>
</item><item>
<link>https://www.heckjj.com/post/682/</link>
<title><![CDATA[从 JDK 8 到 JDK 21 的“握手”血泪史]]></title> 
<author>Heck &lt;@hecks.tk&gt;</author>
<category><![CDATA[编程杂谈]]></category>
<pubDate>Thu, 09 Apr 2026 09:02:37 +0000</pubDate> 
<guid>https://www.heckjj.com/post/682/</guid> 
<description>
<![CDATA[ 
	随着 Java 生态的演进，我们将核心项目从 JDK 8 迁移至 JDK 21。然而，在升级过程中，我们遇到了一个令人费解的现象：原本在 JDK 8 上运行正常的第三方接口调用，在 JDK 21 上却频繁抛出 SSLHandshakeException: Received fatal alert: handshake_failure。本文将详细复盘这次排查过程，揭示 JDK 21 在 SSL/TLS 握手层面的底层变化，并提供终极解决方案。<br/>一、 故障现象：版本升级后的“断连”<br/>在将开发环境切换至 JDK 21 后，我们的应用在调用特定政府网站接口（https://www.xxx.gov.cn）时发生了故障。<br/>错误日志：<br/>javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure<br/>诡异现象：<br/>JDK 8： 运行完美，无任何报错。<br/>JDK 21： 死活连不上，且不报证书错误（CertificateException），直接握手失败。<br/>浏览器/Postman： 可以正常访问。<br/>这种“代码没变，环境变了”的差异，直接指向了 JDK 版本间的底层安全策略差异。<br/>二、 排查之路：层层递进的“破案”过程<br/>为了定位问题，我们开启 -Djavax.net.debug=ssl:handshake 调试模式，通过分析握手日志，我们经历了三个阶段的认知升级。<br/>第一阶段：误判为“弱加密算法” —— 方案失效<br/>直觉： JDK 21 更安全，默认禁用了弱算法。我们猜测是服务器使用了 MD5 或 1024 位密钥。<br/>行动： 修改 java.security 文件，删除 jdk.tls.disabledAlgorithms 中的限制，甚至加上了 ECDH（误以为是禁用了 ECDH 导致的）。<br/>结果： 无效。 即使放宽了所有限制，握手依然失败。这说明问题不在“禁用列表”，而在“协商过程”。<br/>第二阶段：聚焦“椭圆曲线” —— 关键线索<br/>在仔细比对 ClientHello（客户端发起）和 ServerHello（服务器回复）的日志时，我们发现了异常。<br/>在服务器的 ECDHServerKeyExchange 消息中，出现了如下关键字段：<br/><br/>&quot;ECDH ServerKeyExchange&quot;: &#123;<br/>&nbsp;&nbsp;&quot;parameters&quot;: &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&quot;named group&quot;: &quot;x448&quot;&nbsp;&nbsp;// 服务器强制要求使用 x448 曲线<br/>&nbsp;&nbsp;&#125;<br/>&#125;<br/>分析：<br/>JDK 21 的 ClientHello： 默认优先发送 x25519 和 secp256r1（P-256）。<br/>服务器的回应： 该政府服务器配置较为特殊（可能为了高性能或特定合规），它无视了客户端的偏好，强制选择了 x448 (Curve448) 算法进行密钥交换。<br/>矛盾点： 虽然 JDK 21 理论上支持 x448，但在某些构建版本或特定的握手上下文中，客户端无法处理服务器强制下发的 x448 参数，导致计算共享密钥失败。<br/>三、 根本原因 (Root Cause)<br/>这次故障的根本原因并非简单的“证书错误”或“协议不支持”，而是“算法偏好不匹配”：<br/>服务器端的“死板”： 目标服务器（szpsq.gov.cn）在握手时，强制指定了 named group 为 x448。<br/>客户端的“不适”： JDK 21 客户端在收到此指令后，由于环境配置或算法库实现的细微差异，无法完成基于 x448 的密钥计算。<br/>JDK 8 为什么能行？ Java 8 根本不认识 x448（Java 11+ 才引入），服务器检测到 JDK 8 的 ClientHello 后，会自动降级使用传统的 secp256r1，从而避开了这个坑。<br/>四、 解决方案：强制“降级”协商<br/>既然问题出在服务器强制使用 x448，那么解决方案就是不让服务器有机会选择 x448。我们通过 JVM 参数，强制客户端只支持通用的 secp256r1。<br/>✅ 最终生效方案<br/>在 IDEA 运行配置或 Tomcat 启动脚本的 VM Options 中，添加以下参数：<br/>-Djdk.tls.namedGroups=&quot;secp256r1&quot;<br/>方案解析<br/>原理： 该参数强制 JVM 在发送 ClientHello 时，只在 supported_groups 扩展中声明支持 secp256r1。<br/>效果： 服务器收到请求后，发现自己想用的 x448 客户端不支持，无奈之下只能选择次优但通用的 secp256r1 进行握手。<br/>结果： 握手成功，数据正常获取。<br/>五、 经验总结与建议<br/>不要盲目放宽限制： 遇到 handshake_failure，不要第一时间去修改 java.security 里的 disabledAlgorithms，这往往是性能或兼容性问题，而非安全性拦截。<br/>善用 Debug 日志： -Djavax.net.debug=ssl:handshake 是排查 SSL 问题的瑞士军刀。重点关注 ClientHello 发了什么，ServerHello 回了什么，以及 named group 的协商过程。<br/>老旧服务器的兼容性： 国内部分政府或银行网站（.gov.cn）服务器配置更新滞后或使用了特殊算法（如 x448 或国密），在迁移到 JDK 11/17/21 时，大概率需要通过 -Djdk.tls.namedGroups 或代码层定制 SSLParameters 来强制兼容。<br/><br/>注： 技术升级往往伴随着“暗坑”，这次排查虽然曲折，但也让我们更深入理解了 TLS 握手的底层细节。希望这篇复盘能帮后来者节省几个小时的排查时间。
]]>
</description>
</item><item>
<link>https://www.heckjj.com/post/681/</link>
<title><![CDATA[限时活动，免费白嫖Nano Banana Pro、Gemini3.0、GPT5.2等最新模型]]></title> 
<author>Heck &lt;@hecks.tk&gt;</author>
<category><![CDATA[资源共享]]></category>
<pubDate>Thu, 05 Feb 2026 03:55:27 +0000</pubDate> 
<guid>https://www.heckjj.com/post/681/</guid> 
<description>
<![CDATA[ 
	限时活动，免费白嫖Nano Banana Pro、Gemini3.0、GPT5.2等最新模型，在问AI出的活动，估计也是为了推广，白嫖付费ai，基本无限用gemini3.0pro，完全无限使用nanobanana和即梦4.0绘图。<br/><a href="https://www.heckjj.com/attachment.php?fid=268" target="_blank"><img src="https://www.heckjj.com/attachment.php?fid=268" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><a href="https://www.zaiwenai.com?channel-code=69841486f2d7933d88f0b551" target="_blank">点此跳转注册</a><br/>邀请链接注册后，你我都可以获得99999点数，用来Ai文本对话或Ai绘图，你有体验无限时卡。
]]>
</description>
</item><item>
<link>https://www.heckjj.com/post/680/</link>
<title><![CDATA[编程初学者实用代码整洁入门指南]]></title> 
<author>Heck &lt;@hecks.tk&gt;</author>
<category><![CDATA[Web开发]]></category>
<pubDate>Mon, 02 Feb 2026 05:14:32 +0000</pubDate> 
<guid>https://www.heckjj.com/post/680/</guid> 
<description>
<![CDATA[ 
	编写干净、易于理解且可维护的代码是每位开发者必须掌握的技能。我们将探讨提高代码质量的最重要原则，并为每个原则提供代码示例。<br/><br/>如何命名变量（以及其他事物）<br/><br/>我们不用内存地址而使用名称的原因是：名称更容易记忆。更重要的是，它们能提供更多关于变量的信息，以便其他人理解其意义。<br/><br/>找到一个好的名字可能需要一些时间，但这将在未来为你和你的团队节省更多时间。而且我确信大多数读者都遇到过这种情况：几个月后再次访问自己的代码时，很难理解之前做了什么。<br/><br/><br/>如何创建有意义的名字<br/>不要用注释来解释变量的用途。如果一个名字需要注释，那么你应该花时间重命名那个变量，而不是写注释。<br/><br/>差：<br/><br/>var d; // elapsed time in days<br/>我见过这种代码无数次。人们普遍认为应该用注释来隐藏代码的混乱，但这是一种常见的误解。除非有充分理由，否则不要使用 x、y、a 或 b 等字母作为变量名（循环变量除外）。<br/><br/>好：<br/><br/>var elapsedTimeInDays;<br/>var daysSinceCreation;<br/>var daysSinceModification;<br/>这些名称要好得多。它们告诉你被测量的内容以及该测量的单位。<br/><br/><br/><br/>避免错误信息<br/>注意那些有特定含义的词语。除非其类型确实是 List，否则不要将一组账户称为 accountList。这个词有特定的含义，可能会导致错误的结论。<br/><br/>即使类型是列表，accounts 也是一个更简单、更好的名称。<br/><br/>差：<br/><br/>var accountList = [];<br/>好：<br/><br/>var accounts = [];<br/><br/><br/>避免噪音词<br/>噪声词是指那些不提供任何关于变量额外信息的词。它们是冗余的，应该被删除。<br/><br/>一些常见的噪声词有：<br/><br/>The (prefix)<br/><br/>Info<br/><br/>Data<br/><br/>Variable<br/><br/>Object<br/><br/>Manager<br/><br/>如果你的类名是 UserInfo，你只需去掉 Info，直接用 User。将类名用 BookData 代替 Book 是毋庸置疑的，因为类本来就是为了存储数据而存在的。<br/><br/><br/>使用发音友好的名称<br/>如果你不会读一个名字，讨论它时就会显得很愚蠢。<br/><br/>差：<br/><br/>const yyyymmdstr = moment().format(&quot;YYYY/MM/DD&quot;);<br/>好：<br/><br/>const currentDate = moment().format(&quot;YYYY/MM/DD&quot;);<br/><br/><br/>使用可搜索的名称<br/>避免在代码中使用魔法数字。选择可搜索的、命名的常量。不要为常量使用单个字母的名称，因为它们可能出现在很多地方，因此不易搜索。<br/><br/>差：<br/><br/>if (student.classes.length &lt; 7) &#123;<br/>&nbsp;&nbsp; // Do something<br/>&#125;<br/>好：<br/><br/>if (student.classes.length &lt; MAX_CLASSES_PER_STUDENT) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;// Do something<br/>&#125;<br/>这样更好，因为 MAX_CLASSES_PER_STUDENT 可以在代码的许多地方使用。如果将来需要将其改为 6，我们只需更改常量即可。<br/><br/>糟糕的例子会在读者脑海中产生疑问，比如 7 的重要性是什么？<br/><br/>你也应该使用你语言的常量命名和声明约定，例如 Java 中的 private static final 或 JavaScript 中的 const。<br/><br/><br/>保持一致性<br/>遵循每个概念用一个词的规则。不要在不同的类中对同一操作使用 fetch、retrieve 和 get。选择其中一个并在整个项目中统一使用，这样维护代码库的人员或你的 API 客户可以轻松找到他们正在寻找的方法。<br/><br/><br/><br/>如何编写函数<br/>保持它们简短<br/>函数应该很小，真的很小。它们很少会是 20 行长。一个函数越长，它就越可能做很多事情并产生副作用。<br/><br/><br/><br/>确保它们只做一件事<br/>你的函数应该只做一件事情。如果你遵循这个规则，它们一定会很小。函数所做的一切都应该体现在它的名字中。<br/><br/>有时候很难从函数名来判断它是否做了多件事情。一个很好的检查方法是尝试提取一个具有不同名字的另一个函数。如果你能找到，那就意味着它应该是一个不同的函数。<br/><br/>这可能是本文中最重要的概念，需要一些时间来适应。但一旦你掌握了它，你的代码看起来会更加成熟，而且肯定会更容易重构、理解和测试。<br/><br/><br/><br/>将条件语句封装在函数中<br/>重构条件并将其放入命名函数中是使你的条件语句更易读的好方法。<br/><br/>这是我从学校项目里的一段代码。这段代码负责在 Connect4 游戏的棋盘上插入芯片。<br/><br/>isValidInsertion 方法负责检查列号的有效性，让我们可以专注于插入芯片的逻辑。<br/><br/>public void insertChipAt(int column) throws Exception &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;if (isValidInsertion(column)) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insertChip(column);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boardConfiguration += column;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;currentPlayer = currentPlayer == Chip.RED ? Chip.YELLOW : Chip.RED;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125; else &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!columnExistsAt(column))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new IllegalArgumentException();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else if (isColumnFull(column - 1) &#124;&#124; getWinner() != Chip.NONE)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new RuntimeException();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&#125;<br/>如果你感兴趣，这里是 isValidInsertion 的代码。<br/><br/>&nbsp;&nbsp;private boolean isValidInsertion(int column) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;boolean columnIsAvailable = column &lt;= NUM_COLUMNS &amp;&amp; column &gt;= 1 &amp;&amp; numberOfItemsInColumn[column - 1] &lt; NUM_ROWS;<br/>&nbsp;&nbsp;&nbsp;&nbsp;boolean gameIsOver = getWinner() != Chip.NONE;<br/>&nbsp;&nbsp;&nbsp;&nbsp;return columnIsAvailable &amp;&amp; !gameIsOver;<br/>&#125;<br/>如果没有方法，if 条件将如下所示：<br/><br/>if (column &lt;= NUM_COLUMNS<br/> &amp;&amp; column &gt;= 1<br/> &amp;&amp; numberOfItemsInColumn[column - 1] &lt; NUM_ROWS <br/> &amp;&amp; getWinner() != Chip.NONE)<br/>恶心，对吧？我同意。<br/><br/><br/><br/>减少参数<br/>函数应该有两个或更少的参数，越少越好。尽量避免有三个或更多参数。<br/><br/>参数使得函数更难阅读和理解。从测试的角度来看，它们甚至更难，因为它们需要为每个参数组合编写测试用例。<br/><br/><br/><br/>不要使用标志参数<br/>标志参数是一个传递给函数的布尔值参数。根据这个参数的值，会采取两种不同的操作。<br/><br/>例如，假设有一个负责预订音乐会门票的函数，并且有两种类型的用户：高级和普通。你可以编写如下代码：<br/><br/>public Booking book (Customer aCustomer, boolean isPremium) &#123;<br/>&nbsp;&nbsp;if(isPremium) <br/>&nbsp;&nbsp; // logic for premium book<br/>&nbsp;&nbsp;else<br/>&nbsp;&nbsp; // logic for regular booking<br/>&#125;<br/>标志参数天然地违背了单一职责原则。当你看到它们时，应该考虑将函数拆分成两个。<br/><br/><br/><br/>不要有副作用<br/>副作用是你的代码的意外后果。它们可能是改变传递的参数，在按引用传递的情况下，或者可能改变一个全局变量。<br/><br/>关键点在于，它们承诺做另一件事，你需要仔细阅读代码才能注意到副作用。它们可能导致一些棘手的错误。<br/><br/>public class UserValidator &#123;<br/>&nbsp;&nbsp;private Cryptographer cryptographer;<br/>&nbsp;&nbsp;public boolean checkPassword(String userName, String password) &#123; <br/>&nbsp;&nbsp;&nbsp;&nbsp;User user = UserGateway.findByName(userName);<br/>&nbsp;&nbsp;&nbsp;&nbsp;if (user != User.NULL) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String codedPhrase = user.getPhraseEncodedByPassword();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String phrase = cryptographer.decrypt(codedPhrase, password);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (&quot;Valid Password&quot;.equals(phrase)) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Session.initialize();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;return false; <br/>&nbsp;&nbsp;&#125;<br/>&#125;<br/>你能看到这个函数的副作用吗？<br/><br/>它在检查密码，但当密码有效时，它还会初始化会话，这是一个副作用。<br/><br/>你可以将函数的名称改为类似 checkPasswordAndInitializeSession，以使这种效果显式化。但当你这样做时，你应该注意到你的函数实际上在处理两件事，你不应该在这里初始化会话。<br/><br/><br/><br/>不要重复自己<br/>代码重复可能是软件中所有邪恶的根源。重复的代码意味着在逻辑发生变化时需要在多个地方进行修改，而且非常容易出错。<br/><br/>使用你的 IDE 的重构功能，每当遇到重复的代码片段时，提取一个方法。<br/><br/><br/><br/>其他<br/>不要在代码注释中留下代码<br/>请勿如此。这一点很严重，因为看到代码的其他人会因为不知道它是否有什么用而不敢删除它。那些被注释掉的代码会停留很长时间。然后当变量名或方法名改变时，它变得无关紧要，但仍然没有人删除它。<br/><br/>干脆删除它。即使它很重要，也有版本控制可以找回。<br/><br/><br/><br/>了解你语言的规范<br/>你应该了解你语言在空格、注释和命名方面的规范。许多语言都有可用的风格指南。<br/><br/>例如，你应该在 Java 中使用 camelCase，但在 Python 中使用 snake_case。在 C#中，你应该将开括号放在新行，但在 Java 和 JavaScript 中，你应该将它们放在同一行。<br/><br/>这些事情因语言而异，没有统一的标准。<br/><br/><br/>结论<br/>编写干净代码并非一蹴而就的技能，它是一种需要时刻牢记这些原则并在编写代码时加以应用的习惯。<br/><br/>感谢您抽出时间阅读，希望对您有所帮助。
]]>
</description>
</item><item>
<link>https://www.heckjj.com/post/679/</link>
<title><![CDATA[Sublime Text 激活注册方法]]></title> 
<author>Heck &lt;@hecks.tk&gt;</author>
<category><![CDATA[资源共享]]></category>
<pubDate>Thu, 29 Jan 2026 01:25:38 +0000</pubDate> 
<guid>https://www.heckjj.com/post/679/</guid> 
<description>
<![CDATA[ 
	Sublime Text V4200及以上版本激活注册方法另请参阅：<br/><a href="https://www.heckjj.com/post/678/" target="_blank">https://www.heckjj.com/post/678/</a><br/><br/>问题描述<br/>2025.01.20 Sublime Text更新了最新版本V4192，本文介绍该版本的激活注册方法<br/>本文激活注册方法同样适用于V4192及以下版本(已实测版本：V4180~V4192)<br/>激活过程无需使用第三方软件<br/><br/>下载地址<br/>官方网址：<a href="https://www.sublimetext.com" target="_blank">https://www.sublimetext.com</a><br/>更新日志：<a href="https://www.sublimetext.com/download" target="_blank">https://www.sublimetext.com/download</a><br/>下载地址(V4200 64位)：<a href="https://download.sublimetext.com/sublime_text_build_4192_x64_setup.exe" target="_blank">https://download.sublimetext.com/sublime_text_build_4192_x64_setup.exe</a><br/>未激活表现显示为unregisted<br/><br/><br/>激活方法<br/>找到Sublime Text安装路径<br/>右键快捷方式→打开文件所在的位置<br/>默认安装路径：C:&#92;Program Files&#92;Sublime Text<br/>找到sublime_text.exe，拷贝一份副本，使用Sublime Text打开副本文件<br/>也可以使用其它能够以十六进制打开exe文件的编辑软件<br/>另外推荐一个基于浏览器的在线十六进制编辑工具：https://hexed.it/<br/><br/><br/>使用快捷键Ctrl + H打开搜索替换功能<br/>查找以下十六进制字段<br/>8079 0500 0f94 c2<br/>替换为<br/>c641 0501 b200 90<br/><br/><br/><br/>替换完成后使用快捷键Ctrl + S保存并关闭<br/>移除原sublime_text.exe文件(或改为其它名称备份)，然后将编辑后的副本文件名称修改为sublime_text.exe<br/>激活后表现<br/>
]]>
</description>
</item><item>
<link>https://www.heckjj.com/post/678/</link>
<title><![CDATA[Sublime Text 激活注册方法(同步更新：V4200 2026.01.28)]]></title> 
<author>Heck &lt;@hecks.tk&gt;</author>
<category><![CDATA[资源共享]]></category>
<pubDate>Tue, 27 Jan 2026 17:21:05 +0000</pubDate> 
<guid>https://www.heckjj.com/post/678/</guid> 
<description>
<![CDATA[ 
	Sublime Text V4192及以下版本激活注册方法另请参阅：<br/><a href="https://www.heckjj.com/post/679/" target="_blank">https://www.heckjj.com/post/679/</a><br/><br/>问题描述<br/>2025.05.21 Sublime Text更新了最新版本V4200，本文介绍该版本的激活注册方法<br/>激活过程无需使用第三方软件<br/><br/>下载地址<br/>官方网址：<a href="https://www.sublimetext.com" target="_blank">https://www.sublimetext.com</a><br/>更新日志：<a href="https://www.sublimetext.com/download" target="_blank">https://www.sublimetext.com/download</a><br/>下载地址(V4200 64位)：<a href="https://download.sublimetext.com/sublime_text_build_4200_x64_setup.exe" target="_blank">https://download.sublimetext.com/sublime_text_build_4200_x64_setup.exe</a><br/>未激活表现显示为unregisted<br/><br/>激活方法<br/>1、找到Sublime Text安装路径<br/>右键快捷方式→打开文件所在的位置<br/>默认安装路径：C:&#92;Program Files&#92;Sublime Text<br/>2、找到sublime_text.exe，拷贝一份副本，使用Sublime Text打开副本文件<br/>也可以使用其它能够以十六进制打开exe文件的编辑软件<br/>另外推荐一个基于浏览器的在线十六进制编辑工具：https://hexed.it/<br/><br/>使用快捷键Ctrl + H打开搜索替换功能<br/>查找以下十六进制字段<br/>0fb6 5105 83f2 01<br/>替换为(二选其一即可)<br/>c641 0501 b200 90<br/>或<br/>c641 0501 4885 c0<br/><br/>替换完成后使用快捷键Ctrl + S保存并关闭<br/>移除原sublime_text.exe文件(建议改为其它名称留作备份)，然后将编辑后的副本文件名称修改为sublime_text.exe<br/>激活后表现为无unregisted
]]>
</description>
</item><item>
<link>https://www.heckjj.com/post/677/</link>
<title><![CDATA[Win11系统如何跳过联网激活，新笔记本也适用无需登录微软账户]]></title> 
<author>Heck &lt;@hecks.tk&gt;</author>
<category><![CDATA[电脑技术]]></category>
<pubDate>Wed, 21 Jan 2026 05:44:11 +0000</pubDate> 
<guid>https://www.heckjj.com/post/677/</guid> 
<description>
<![CDATA[ 
	由于售后服务条款：已激活windows系统或Ofice的主机，不支持7天无理由退换货。由于windows系统联网时自动激活，请您确认需求后再激活使用。<br/><br/>在Windows 11安装或首次设置过程中跳过联网步骤，可通过命令提示符输入特定指令实现。‌核心方法是：在联网界面按 Shift + F10（笔记本需加 Fn）打开命令提示符，输入 oobe&#92;bypassnro 后回车，重启后选择“我没有Internet连接”选项即可‌。以下是详细步骤：‌‌‌<br/><br/><br/>操作步骤（通用方法）<br/>此方法适用于所有Windows 11版本（24H2及更早），成功率最高：<br/><br/>‌进入联网界面‌：在系统安装或首次开机设置时，到达“连接网络”页面（需输入Wi-Fi或网线连接）。‌<br/><br/>‌打开命令提示符‌：<br/>台式机：直接按 Shift + F10。<br/>笔记本：按 Fn + Shift + F10（部分机型需组合键）。‌<br/><br/>‌输入跳过指令‌：<br/>在弹出窗口中输入：oobe&#92;bypassnro（或 oobe&#92;bypassnro.cmd），按回车。‌<br/>或者先cd oobe再输入bypassnro.cmd回车<br/><br/><br/>系统自动重启（约1-2分钟）。‌<br/><br/>‌选择离线选项‌：<br/>重启后返回联网界面，点击底部 ‌“我没有Internet连接”‌。<br/>后续按提示设置本地账户（无需微软账号）。‌<br/><br/>注意事项<br/>‌网络断开建议‌：若在虚拟机或笔记本操作，提前断开Wi-Fi/网线可提高成功率（非必须）。‌<br/><br/>‌命令无效处理‌：若输入后未重启，检查拼写（如 bypassnro 非 BYPASSNRO），或改用任务管理器结束 OOBE Network Connection Flow 进程。‌<br/>‌后续影响‌：跳过联网后部分功能受限（如OneDrive同步），但基础使用无碍；进入桌面后可重新联网。‌
]]>
</description>
</item>
</channel>
</rss>