<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Engineering on LeoChu Space</title>
    <link>https://leochu.work/blog/tech/engineering/</link>
    <description>Recent content in Engineering on LeoChu Space</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <lastBuildDate>Wed, 08 Apr 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://leochu.work/blog/tech/engineering/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>LDAP 简明科普</title>
      <link>https://leochu.work/blog/tech/engineering/ldap-%E7%AE%80%E6%98%8E%E7%A7%91%E6%99%AE/</link>
      <pubDate>Wed, 08 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/ldap-%E7%AE%80%E6%98%8E%E7%A7%91%E6%99%AE/</guid>
      <description>&lt;h2 id=&#34;1-什么是-ldap&#34;&gt;1. 什么是 LDAP&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;LDAP（Lightweight Directory Access Protocol）&lt;/strong&gt; 是一种用于&lt;strong&gt;查询和管理目录信息的协议&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;简单说：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;LDAP 是一个“按层级组织的用户信息数据库 + 查询方式”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;2-ldap-存什么&#34;&gt;2. LDAP 存什么&lt;/h2&gt;
&lt;p&gt;常见内容包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用户账号（用户名、ID）&lt;/li&gt;
&lt;li&gt;密码（加密存储）&lt;/li&gt;
&lt;li&gt;用户组（权限）&lt;/li&gt;
&lt;li&gt;部门 / 组织结构&lt;/li&gt;
&lt;li&gt;邮箱、电话等信息&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;3-数据结构像树&#34;&gt;3. 数据结构（像树）&lt;/h2&gt;
&lt;p&gt;LDAP 的数据是&lt;strong&gt;树状结构&lt;/strong&gt;：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph TD
A[公司] --&amp;gt; B[技术部]
A --&amp;gt; C[人事部]
B --&amp;gt; D[用户A]
B --&amp;gt; E[用户B]
C --&amp;gt; F[用户C]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;每个节点都有唯一标识（DN）。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;4-ldap-能做什么&#34;&gt;4. LDAP 能做什么&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;用户登录认证（验证账号密码）&lt;/li&gt;
&lt;li&gt;查询用户信息&lt;/li&gt;
&lt;li&gt;管理组织结构&lt;/li&gt;
&lt;li&gt;权限分组管理&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;5-常见使用场景&#34;&gt;5. 常见使用场景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;公司统一账号系统&lt;/li&gt;
&lt;li&gt;内部系统登录（单点登录基础）&lt;/li&gt;
&lt;li&gt;权限集中管理&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;6-常见实现&#34;&gt;6. 常见实现&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;OpenLDAP&lt;/li&gt;
&lt;li&gt;Active Directory（微软）&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;7-一句话总结&#34;&gt;7. 一句话总结&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;LDAP 是一个“按树组织的用户信息数据库 + 查询协议”，用于统一管理账号和组织结构&lt;/p&gt;
&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>SSH、跳板机和隧道</title>
      <link>https://leochu.work/blog/tech/engineering/ssh%E8%B7%B3%E6%9D%BF%E6%9C%BA%E5%92%8C%E9%9A%A7%E9%81%93/</link>
      <pubDate>Wed, 08 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/ssh%E8%B7%B3%E6%9D%BF%E6%9C%BA%E5%92%8C%E9%9A%A7%E9%81%93/</guid>
      <description>&lt;h2 id=&#34;1-ssh-是什么&#34;&gt;1. SSH 是什么&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;SSH（Secure Shell）&lt;/strong&gt; 是一种用于远程登录和通信的加密协议。&lt;/p&gt;
&lt;h3 id=&#34;核心作用&#34;&gt;核心作用&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;远程登录服务器&lt;/li&gt;
&lt;li&gt;执行命令&lt;/li&gt;
&lt;li&gt;安全传输数据&lt;/li&gt;
&lt;li&gt;建立加密通道&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;简单理解&#34;&gt;简单理解&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;就像一根“加密的远程操作线”，你在本地操作，实际在远程执行。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;图示&#34;&gt;图示&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph LR
A[本地电脑] -- SSH连接 --&amp;gt; B[远程服务器]
A --&amp;gt;|输入命令| B
B --&amp;gt;|返回结果| A
&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id=&#34;2-跳板机bastion-host是什么&#34;&gt;2. 跳板机（Bastion Host）是什么&lt;/h2&gt;
&lt;p&gt;跳板机是一台&lt;strong&gt;中间服务器&lt;/strong&gt;，用于访问内网机器。&lt;/p&gt;
&lt;h3 id=&#34;为什么需要&#34;&gt;为什么需要&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;内网服务器不能直接暴露到公网&lt;/li&gt;
&lt;li&gt;提供统一入口（安全控制、审计）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;简单理解-1&#34;&gt;简单理解&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;像“门卫”，必须先经过它，才能进入内部系统。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;图示-1&#34;&gt;图示&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph LR
A[本地电脑] --&amp;gt; B[跳板机]
B --&amp;gt; C[内网服务器]
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;常见连接方式&#34;&gt;常见连接方式&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;ssh -J user@跳板机 user@内网服务器&lt;/code&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;3-隧道ssh-tunnel是什么&#34;&gt;3. 隧道（SSH Tunnel）是什么&lt;/h2&gt;
&lt;p&gt;SSH 隧道是一种通过 SSH 转发网络流量的技术。&lt;/p&gt;
&lt;h3 id=&#34;本质&#34;&gt;本质&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;把本地请求“通过 SSH 转发到远程”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;31-本地端口转发local-forward&#34;&gt;3.1 本地端口转发（Local Forward）&lt;/h2&gt;
&lt;h3 id=&#34;示例&#34;&gt;示例&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;ssh -L 3307:127.0.0.1:3306 user@服务器&lt;/code&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>加密体系</title>
      <link>https://leochu.work/blog/tech/engineering/%E5%8A%A0%E5%AF%86%E4%BD%93%E7%B3%BB/</link>
      <pubDate>Wed, 08 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/%E5%8A%A0%E5%AF%86%E4%BD%93%E7%B3%BB/</guid>
      <description>&lt;h2 id=&#34;1-三个核心问题&#34;&gt;1. 三个核心问题&lt;/h2&gt;
&lt;p&gt;整个体系其实在解决三件事：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;你是谁？（身份认证）&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据能不能被偷看？（加密传输）&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;如何安全地交换密钥？（密钥分发）&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id=&#34;2-非对称加密公钥--私钥&#34;&gt;2. 非对称加密（公钥 / 私钥）&lt;/h2&gt;
&lt;h3 id=&#34;核心定义&#34;&gt;核心定义&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;使用一对密钥：公钥 + 私钥&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;公钥：可以公开&lt;/li&gt;
&lt;li&gt;私钥：必须保密&lt;/li&gt;
&lt;li&gt;二者不可互相推导&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&#34;两种用途关键区分&#34;&gt;两种用途（关键区分）&lt;/h3&gt;
&lt;h4 id=&#34;-加密通信&#34;&gt;① 加密通信&lt;/h4&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph LR
A[发送方] --&amp;gt;|公钥加密| B[密文]
B --&amp;gt; C[接收方]
C --&amp;gt;|私钥解密| D[明文]
&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h4 id=&#34;-身份认证ssh&#34;&gt;② 身份认证（SSH）&lt;/h4&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;sequenceDiagram
participant A as 客户端（私钥）
participant B as 服务器（公钥）

B-&amp;gt;&amp;gt;A: challenge
A-&amp;gt;&amp;gt;B: signature
B-&amp;gt;&amp;gt;B: 公钥验证
B-&amp;gt;&amp;gt;A: 通过/拒绝
&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h3 id=&#34;关键公式&#34;&gt;关键公式&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;signature = Sign(私钥, challenge)&lt;/code&gt;&lt;br&gt;
&lt;code&gt;Verify(公钥, challenge, signature) = true&lt;/code&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;本质总结&#34;&gt;本质总结&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;私钥负责“生成证明”，公钥负责“验证证明”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;3-ssh基于签名的认证机制&#34;&gt;3. SSH：基于签名的认证机制&lt;/h2&gt;
&lt;h3 id=&#34;文件结构&#34;&gt;文件结构&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;~/.ssh/id_ed25519      &lt;span style=&#34;color:#75715e&#34;&gt;# 私钥&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;~/.ssh/id_ed25519.pub  &lt;span style=&#34;color:#75715e&#34;&gt;# 公钥&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;~/.ssh/authorized_keys &lt;span style=&#34;color:#75715e&#34;&gt;# 服务器保存公钥&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id=&#34;免密登录本质&#34;&gt;免密登录本质&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;服务器信任“某个公钥”，允许对应私钥登录&lt;/p&gt;</description>
    </item>
    <item>
      <title>集群常用脚本</title>
      <link>https://leochu.work/blog/tech/engineering/%E9%9B%86%E7%BE%A4%E5%B8%B8%E7%94%A8%E8%84%9A%E6%9C%AC/</link>
      <pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/%E9%9B%86%E7%BE%A4%E5%B8%B8%E7%94%A8%E8%84%9A%E6%9C%AC/</guid>
      <description>&lt;p&gt;多重执行xcall.sh&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/bin/bash

# 遍历所有节点（集群主机列表）
for i in cdhmaster01 cdhmaster02 cdhmaster03 cdhnode01 cdhnode02 cdhnode03
do
  # 打印当前正在操作的主机，方便区分输出
  echo &amp;#34;--------- $i ----------&amp;#34;

  # 通过 ssh 在远程主机执行传入的命令
  # &amp;#34;$*&amp;#34; 表示把所有参数当作一个整体传过去
  # 例如：./xcall.sh pwd
  # 实际执行：ssh cdhmaster01 &amp;#34;pwd&amp;#34;
  ssh $i &amp;#34;$*&amp;#34;
done
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;集群分发xsync.sh&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/bin/bash

if [ $# -eq 0 ]; then
  echo &amp;#34;Usage: $0  [more files_or_dirs]&amp;#34;
  exit 1
fi

hosts=(cdhmaster01 cdhmaster02 cdhmaster03 cdhnode01 cdhnode02 cdhnode03)
user=$(whoami)

for src in &amp;#34;$@&amp;#34;
do
  if [ ! -e &amp;#34;$src&amp;#34; ]; then
    echo &amp;#34;Not found: $src&amp;#34;
    continue
  fi

  abs_src=$(readlink -f &amp;#34;$src&amp;#34;)
  name=$(basename &amp;#34;$abs_src&amp;#34;)
  parent=$(dirname &amp;#34;$abs_src&amp;#34;)

  for host in &amp;#34;${hosts[@]}&amp;#34;
  do
    echo &amp;#34;===== $host =====&amp;#34;

    ssh &amp;#34;$host&amp;#34; &amp;#34;mkdir -p &amp;#39;$parent&amp;#39;&amp;#34;

    if [ -d &amp;#34;$abs_src&amp;#34; ]; then
      rsync -av &amp;#34;$abs_src&amp;#34; &amp;#34;$user@$host:$parent/&amp;#34;
    else
      rsync -av &amp;#34;$abs_src&amp;#34; &amp;#34;$user@$host:$parent/&amp;#34;
    fi
  done
done
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>restful风格</title>
      <link>https://leochu.work/blog/tech/engineering/restful%E9%A3%8E%E6%A0%BC/</link>
      <pubDate>Sat, 13 Apr 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/restful%E9%A3%8E%E6%A0%BC/</guid>
      <description>&lt;h3 id=&#34;一什么是-rest-一种软件架构风格&#34;&gt;一、什么是 REST ？（一种软件架构风格）&lt;/h3&gt;
&lt;p&gt;缩写：REST （不是&amp;quot;rest&amp;quot;这个单词）
外文名：Representational State Transfer，简称REST。
中文名：表现层状态转移。&lt;/p&gt;
&lt;p&gt;提出时间：2000年。
属性：一种软件架构风格。（以Web为平台的。web服务的架构风格，前后端接口时候用到。）&lt;/p&gt;
&lt;p&gt;REST之所以晦涩难懂，是因为前面主语（Resource ）被去掉了。
全称是： Resource Representational State Transfer。
通俗来讲就是：资源在网络中以某种表现形式进行状态转移。&lt;/p&gt;
&lt;p&gt;分解开来讲解:
Resource：资源，即数据（这是网络的核心）；
Representational：某种表现形式，比如用JSON，XML，JPEG等；
State Transfer：状态变化。通过HTTP的动词（get查询、post新增、put修改、delete删除）实现。&lt;/p&gt;
&lt;p&gt;一句话描述 REST 实质：&lt;br&gt;
URL 中只使用名词来定位资源，用 HTTP 协议里的动词（GET、POST、PUT、DELETE）来实现资源的增删改查操作。&lt;/p&gt;
&lt;p&gt;什么意思呢？&lt;/p&gt;
&lt;p&gt;比如，我们有一个 friends 接口，对于 “朋友” 我们有增删改查四种操作，怎么定义 REST 接口？&lt;/p&gt;
&lt;p&gt;增加一个朋友，uri: generalcode.cn/v1/friends 接口类型：POST&lt;br&gt;
删除一个朋友，uri: generalcode.cn/va/friends 接口类型：DELETE（在 http 的 parameter 指定好友 id）&lt;br&gt;
修改一个朋友，uri: generalcode.cn/va/friends 接口类型：PUT（在 http 的 parameter 指定好友 id）&lt;br&gt;
查找一个朋友，uri: generalcode.cn/va/friends 接口类型：GET&lt;/p&gt;
&lt;p&gt;上面我们定义的四个接口就是符合 REST 协议的，请注意，这几个接口都没有动词，只有名词 friends，都是通过 Http 请求的接口类型来判断是什么业务操作。&lt;/p&gt;
&lt;p&gt;举个反例：
generalcode.cn/va/deleteFriends 该接口用来表示删除朋友，这就是不符合REST协议的接口。
不能用deleteFriends ，而应该就用friends + http请求的delete方式。&lt;/p&gt;</description>
    </item>
    <item>
      <title>IDEA常用操作</title>
      <link>https://leochu.work/blog/tech/engineering/idea%E5%B8%B8%E7%94%A8%E6%93%8D%E4%BD%9C/</link>
      <pubDate>Sat, 02 Mar 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/idea%E5%B8%B8%E7%94%A8%E6%93%8D%E4%BD%9C/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;IDEA（IntelliJ IDEA）是业界公认的最好开发工具之一，当然好不好也因人而异，也不要刻意去争谁强谁弱，高手往往不在乎手中的兵器是什么的。个人而言，更高效的工具适合每个开发人员，在编写代码的时候花的时间少，就有更多的时间去设计&amp;hellip;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;目录&#34;&gt;目录&lt;/h2&gt;
&lt;p&gt;[toc]&lt;/p&gt;
&lt;h2 id=&#34;一概述&#34;&gt;一、概述&lt;/h2&gt;
&lt;p&gt;IDEA（IntelliJ IDEA）是业界公认的最好开发工具之一，当然好不好也因人而异，也不要刻意去争谁强谁弱，高手往往不在乎手中的兵器是什么的。个人而言，更高效的工具适合每个开发人员，在编写代码的时候花的时间少，就有更多的时间去设计代码，当然，使用一个陌生的 IDE，效率肯定是比不上自己熟练的 IDE 的，所以为了节省诸君的学习成本，也为了更快地去接纳和熟练 IDEA，所以周末之余，故作此文。&amp;mdash;- 一品江南&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;准备&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;所有的电脑软件都有着相同的 UI 框架、菜单结构，对于每一个开发人员来说，基本的文件操作、项目操作、工作空间操作不成问题，不会讲到。&lt;/li&gt;
&lt;li&gt;涉及的其他工具（Maven、Git 等）不会详细讲，只会讲到如何操作，想要深入学习，关注其他博文。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;二配置&#34;&gt;二、配置&lt;/h2&gt;
&lt;p&gt;在安装软件（JDK、Maven、Git、IDEA）搭建好环境后，要对 IDEA 进行一番配置，才能开始开发，每个人都有每个人的配置习惯，可以自己研究自己喜欢的配置，进入 IDEA 的配置 File | Settings（&lt;code&gt;Ctrl+Alt+S&lt;/code&gt;）开始配置。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;选择菜单或设置步骤使用 “|” 分开，后面操作一样&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;1-主题与行为&#34;&gt;1. 主题与行为&lt;/h3&gt;
&lt;p&gt;选择自己喜欢的主题：Appearance &amp;amp; Behavior | Appearance | Theme&lt;/p&gt;
&lt;p&gt;配置骚气的背景图片：Appearance &amp;amp; Behavior | Appearance | UI Options | Background Image…&lt;/p&gt;
&lt;p&gt;在配置中选择合适的窗口选项：Appearance &amp;amp; Behavior | Appearance | Window Options&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Animate windows：关闭动画效果&lt;/li&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Show memory indicator：显示内存使用情况&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Show tool window bars：关闭工具栏显示，按两次&lt;code&gt;Alt&lt;/code&gt;键可以显示&lt;/li&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Small labels in editor tabs：编辑器显示小标签&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;配置自己想看到的菜单项和工具栏：Appearance &amp;amp; Behavior | Menus and Toolbars&lt;/p&gt;</description>
    </item>
    <item>
      <title>Git配置SSH密钥</title>
      <link>https://leochu.work/blog/tech/engineering/git%E9%85%8D%E7%BD%AEssh%E5%AF%86%E9%92%A5/</link>
      <pubDate>Sat, 17 Feb 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/git%E9%85%8D%E7%BD%AEssh%E5%AF%86%E9%92%A5/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;本文由 &lt;a href=&#34;http://ksria.com/simpread/&#34;&gt;简悦 SimpRead&lt;/a&gt; 转码， 原文地址 &lt;a href=&#34;https://blog.csdn.net/weixin_41990913/article/details/91373362&#34;&gt;blog.csdn.net&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;初次安装 gitgit 需要配置用户名和邮箱，否则 git 会提示：please tell me who you are.&lt;/p&gt;
&lt;p&gt;你需要运行命令来配置你的用户名和邮箱：&lt;br&gt;
$ git config &amp;ndash;&lt;a href=&#34;https://so.csdn.net/so/search?q=global&amp;amp;spm=1001.2101.3001.7020&#34;&gt;global&lt;/a&gt; &lt;a href=&#34;http://user.name&#34;&gt;user.name&lt;/a&gt; “liuhanxia”&lt;br&gt;
$ git config &amp;ndash;global user.email &lt;a href=&#34;mailto:%22liuhanxia@51faguanggao.com&#34;&gt;&amp;ldquo;liuhanxia@51faguanggao.com&lt;/a&gt;&amp;rdquo;&lt;br&gt;
注意：（引号内请输入你自己设置的名字，和你自己的邮箱）此用户名和邮箱是 git 提交代码时用来显示你身份和联系方式的，并不是 &lt;a href=&#34;https://so.csdn.net/so/search?q=github&amp;amp;spm=1001.2101.3001.7020&#34;&gt;github&lt;/a&gt; 用户名和邮箱&lt;br&gt;
&lt;img loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/git_ssh_01.png&#34;&gt;&lt;br&gt;
git 使用 ssh 密钥&lt;br&gt;
git 支持 https 和 git 两种传输协议，github 分享链接时会有两种协议可选：git 协议链接图例、https 协议链接图例&lt;/p&gt;
&lt;p&gt;git 使用 https 协议，每次 pull, push 都会提示要输入密码，&lt;br&gt;
使用 git 协议，然后使用 ssh 密钥，这样免去每次都输密码的麻烦&lt;/p&gt;
&lt;p&gt;初次使用 git 的用户要使用 git 协议大概需要三个步骤：&lt;br&gt;
一、生成密钥对&lt;br&gt;
二、设置远程仓库（本文以 github 为例）上的公钥&lt;br&gt;
三、把 git 的 remote url 修改为 git 协议（以上两个步骤初次设置过以后，以后使用都不需要再次设置，此步骤视以后项目的 remote url 而定，如果以后其他项目的协议为 https 则需要此步骤）&lt;/p&gt;</description>
    </item>
    <item>
      <title>Git命令行</title>
      <link>https://leochu.work/blog/tech/engineering/git%E5%91%BD%E4%BB%A4%E8%A1%8C/</link>
      <pubDate>Sat, 03 Feb 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/git%E5%91%BD%E4%BB%A4%E8%A1%8C/</guid>
      <description>&lt;p&gt;&lt;img alt=&#34;img&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/git-command.jpg&#34;&gt;&lt;/p&gt;
&lt;h5 id=&#34;本地仓库链接远程仓库&#34;&gt;本地仓库链接远程仓库&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;git remote add origin &amp;lt;server&amp;gt;git@github.com:yourName/yourRepo.git&lt;/code&gt;&lt;/p&gt;
&lt;h5 id=&#34;创建一个叫做feature_x的分支并切换过去&#34;&gt;创建一个叫做“feature_x”的分支，并切换过去&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;git checkout -b feature_x&lt;/code&gt;&lt;/p&gt;
&lt;h5 id=&#34;再把新建的分支删掉&#34;&gt;再把新建的分支删掉：&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;git branch -d feature_x&lt;/code&gt;&lt;/p&gt;
&lt;h5 id=&#34;预览差异&#34;&gt;预览差异：&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;git diff &amp;lt;source_branch&amp;gt; &amp;lt;target_branch&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;h5 id=&#34;创建一个叫做-100-的标签&#34;&gt;创建一个叫做 &lt;em&gt;1.0.0&lt;/em&gt; 的标签：&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;git tag 1.0.0 1b2e1d63ff&lt;/code&gt;&lt;/p&gt;
&lt;h5 id=&#34;想commit自动来提交本地修改我们可以使用-a标识&#34;&gt;想commit自动来提交本地修改，我们可以使用-a标识&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;git commit -a -m &amp;quot;Changed some files&amp;quot;&lt;/code&gt;
&lt;em&gt;git commit 命令的-a选项可将所有&lt;strong&gt;被修改或者已删除的且已经被git管理的文档&lt;/strong&gt;提交到仓库中&lt;/em&gt;
&lt;em&gt;千万注意，-a不会造成新文件被提交，只能修改。&lt;/em&gt;&lt;/p&gt;
&lt;h5 id=&#34;内建的图形化-git&#34;&gt;内建的图形化 git：&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;gitk&lt;/code&gt;&lt;/p&gt;
&lt;h5 id=&#34;彩色的-git-输出&#34;&gt;彩色的 git 输出：&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;git config color.ui true&lt;/code&gt;&lt;/p&gt;
&lt;h5 id=&#34;使用git-gui创建sshkey及查看&#34;&gt;使用git gui创建sshkey及查看：&lt;/h5&gt;
&lt;p&gt;&lt;img alt=&#34;image-20230213164607434&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/image-20230213164607434.png&#34;&gt;&lt;/p&gt;
&lt;h5 id=&#34;命令行创建ssh-key&#34;&gt;命令行创建ssh key：&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;ssh-keygen -t rsa -C &amp;quot;your_email@youremail.com&amp;quot;&lt;/code&gt;
&lt;em&gt;后面的&lt;code&gt;your_email@youremail.com&lt;/code&gt;改为你在github上注册的邮箱，之后会要求确认路径和输入密码，我们这使用默认的一路回车就行。成功的话会在&lt;code&gt;~/&lt;/code&gt;下生成&lt;code&gt;.ssh&lt;/code&gt;文件夹，进去，打开&lt;code&gt;id_rsa.pub&lt;/code&gt;，复制里面的&lt;code&gt;key&lt;/code&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;h5 id=&#34;验证是否成功在git-bash下输入&#34;&gt;验证是否成功，在git bash下输入：&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;ssh -T git@github.com&lt;/code&gt;&lt;/p&gt;
&lt;h5 id=&#34;如果要查看指定文件的修改记录可以使用-git-blame-命令格式如下&#34;&gt;如果要查看指定文件的修改记录可以使用 git blame 命令，格式如下：&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;git blame &amp;lt;file&amp;gt;&lt;/code&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Git服务器搭建</title>
      <link>https://leochu.work/blog/tech/engineering/git%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%90%AD%E5%BB%BA/</link>
      <pubDate>Sat, 20 Jan 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/git%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%90%AD%E5%BB%BA/</guid>
      <description>&lt;p&gt;上一章节中我们远程仓库使用了 Github，Github 公开的项目是免费的，2019 年开始 Github 私有存储库也可以无限制使用。&lt;/p&gt;
&lt;p&gt;这当然我们也可以自己搭建一台 Git 服务器作为私有仓库使用。&lt;/p&gt;
&lt;p&gt;接下来我们将以 Centos 为例搭建 Git 服务器。&lt;/p&gt;
&lt;h3 id=&#34;1安装git&#34;&gt;1、安装Git&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-devel
$ yum install git
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;接下来我们 创建一个git用户组和用户，用来运行git服务：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ groupadd git
$ useradd git -g git
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;2创建证书登录&#34;&gt;2、创建证书登录&lt;/h3&gt;
&lt;p&gt;收集所有需要登录的用户的公钥，公钥位于id_rsa.pub文件中，把我们的公钥导入到/home/git/.ssh/authorized_keys文件里，一行一个。&lt;/p&gt;
&lt;p&gt;如果没有该文件创建它：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ cd /home/git/
$ mkdir .ssh
$ chmod 755 .ssh
$ touch .ssh/authorized_keys
$ chmod 644 .ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;3初始化git仓库&#34;&gt;3、初始化Git仓库&lt;/h3&gt;
&lt;p&gt;首先我们选定一个目录作为Git仓库，假定是/home/gitrepo/runoob.git，在/home/gitrepo目录下输入命令：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ cd /home
$ mkdir gitrepo
$ chown git:git gitrepo/
$ cd gitrepo

$ git init --bare runoob.git
Initialized empty Git repository in /home/gitrepo/runoob.git/
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;以上命令Git创建一个空仓库，服务器上的Git仓库通常都以.git结尾。然后，把仓库所属用户改为git：&lt;/p&gt;</description>
    </item>
    <item>
      <title>模块地狱</title>
      <link>https://leochu.work/blog/tech/engineering/%E6%A8%A1%E5%9D%97%E5%9C%B0%E7%8B%B1/</link>
      <pubDate>Sun, 10 Dec 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/%E6%A8%A1%E5%9D%97%E5%9C%B0%E7%8B%B1/</guid>
      <description>&lt;p&gt;个人理解: 有点类似依赖冲突,循环依赖&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;传递性依赖&lt;/li&gt;
&lt;li&gt;遮蔽&lt;/li&gt;
&lt;li&gt;版本冲突&lt;/li&gt;
&lt;li&gt;复杂的类加载&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    <item>
      <title>开源许可证</title>
      <link>https://leochu.work/blog/tech/engineering/%E5%BC%80%E6%BA%90%E8%AE%B8%E5%8F%AF%E8%AF%81/</link>
      <pubDate>Sun, 26 Nov 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/%E5%BC%80%E6%BA%90%E8%AE%B8%E5%8F%AF%E8%AF%81/</guid>
      <description>&lt;p&gt;&lt;img alt=&#34;Pasted image 20230426182936.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230426182936.png&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>开发流程</title>
      <link>https://leochu.work/blog/tech/engineering/%E5%BC%80%E5%8F%91%E6%B5%81%E7%A8%8B/</link>
      <pubDate>Sun, 12 Nov 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/%E5%BC%80%E5%8F%91%E6%B5%81%E7%A8%8B/</guid>
      <description>&lt;h2 id=&#34;1-开发流程&#34;&gt;1. 开发流程&lt;/h2&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20230327103333.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230327103333.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;**说明：**此开发流程符合大部分需求场景，少数需求可能流程会有所增减。&lt;/p&gt;
&lt;h2 id=&#34;2-流程说明&#34;&gt;2. 流程说明&lt;/h2&gt;
&lt;hr&gt;
&lt;h4 id=&#34;21-需求评审&#34;&gt;2.1 需求评审&lt;/h4&gt;
&lt;p&gt;详细了解本次需求的背景和细节，并讨论需求的可行性。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;比如：&lt;/strong&gt;     &lt;/p&gt;
&lt;p&gt;当前需求是否明确? 新需求是什么?&lt;br&gt;
需求背景及解决什么问题?&lt;br&gt;
如果需求复杂程度大，提出是否需要分阶段实施?&lt;br&gt;
需求完成的期望指标是什么? 如何评判? 如何交付?&lt;br&gt;
技术能否实现、逻辑是否有问题？&lt;br&gt;
进入开发阶段测试，遇到问题与谁对接，来协调解决问题?&lt;br&gt;
如果需求复杂请让需求方拆解需求去描述要达到的目的。&lt;br&gt;
如果需求未做到目的明确，清晰合理，请让需求方解决疑问点。&lt;br&gt;
需求对接完，请邮件告知。&lt;/p&gt;
&lt;h4 id=&#34;22-技术评审&#34;&gt;2.2 技术评审&lt;/h4&gt;
&lt;p&gt;阐述详细的技术实现方案，评估一下是否有不合理之处，比如表结构如何设计、接口怎么定义、有没有技术难点等。&lt;/p&gt;
&lt;h4 id=&#34;23-开发--测试排期&#34;&gt;2.3 开发 &amp;amp; 测试排期&lt;/h4&gt;
&lt;p&gt;评估具体的工作量，根据工作量安排各个步骤要完成的截止日期。&lt;/p&gt;
&lt;h4 id=&#34;24-输出开发设计文档&#34;&gt;2.4 输出开发设计文档&lt;/h4&gt;
&lt;p&gt;此文档放在 confluence 上，大致包含需求背景、开发设计（技术方案）、排期计划、开发流程的具体内容、附录等。&lt;strong&gt;需求背景、开发设计（技术方案）、排期计划要在开发测试开始前书写完成，其他部分可以根据进度补充完善。&lt;/strong&gt;&lt;/p&gt;
&lt;h4 id=&#34;25-开发--测试&#34;&gt;2.5 开发 &amp;amp; 测试&lt;/h4&gt;
&lt;p&gt;根据技术方案和排期，具体实现。&lt;/p&gt;
&lt;h4 id=&#34;26-需求方验收&#34;&gt;2.6 需求方验收&lt;/h4&gt;
&lt;p&gt;验收阶段，开发如有 bug 修改 bug，可以提前提供部分样例结果进行预验收。&lt;/p&gt;
&lt;h4 id=&#34;27-生产部署&#34;&gt;2.7 生产部署&lt;/h4&gt;
&lt;p&gt;根据具体环境部署。&lt;/p&gt;
&lt;h4 id=&#34;28-需求复盘总结&#34;&gt;2.8 需求复盘总结&lt;/h4&gt;
&lt;p&gt;复盘一下问题主要出在哪里，以后如何规避，哪些优点可以以后借鉴等。&lt;/p&gt;
&lt;h2 id=&#34;3-其他注意事项&#34;&gt;3. 其他注意事项&lt;/h2&gt;
&lt;hr&gt;
&lt;h4 id=&#34;31-关于对接和验收阶段&#34;&gt;3.1 关于对接和验收阶段&lt;/h4&gt;
&lt;p&gt;首版需求已评审过的前提下，在此阶段如果不可避免出现需求变更频繁和很多不确定的时候，要明确告知需求方批量提供需求点或完善点，避免随时出现一个接一个，导致此需求一直完不成。&lt;/p&gt;
&lt;p&gt;最好补充一次批量提完，如果第两个及以上批次，建议需求当需求变更处理。&lt;/p&gt;
&lt;p&gt;开发要合理评估，尽量避免开发不合理需求。&lt;/p&gt;
&lt;h2 id=&#34;4-附件&#34;&gt;4. 附件&lt;/h2&gt;
&lt;hr&gt;
&lt;p&gt;Java 开发手册:!泰山版.pdf&lt;/p&gt;</description>
    </item>
    <item>
      <title>技术债</title>
      <link>https://leochu.work/blog/tech/engineering/%E6%8A%80%E6%9C%AF%E5%80%BA/</link>
      <pubDate>Sun, 29 Oct 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/%E6%8A%80%E6%9C%AF%E5%80%BA/</guid>
      <description>&lt;p&gt;关于技术债务的文章，尽管实践中会堆积技术债，但这个概念并不在我们的工作中频繁出现。这篇文章就系统性讲讲技术债，让大家避免知其然，不知其所以然。&lt;/p&gt;
&lt;p&gt;一、技术债是什么&lt;/p&gt;
&lt;p&gt;技术负债（英语：Technical debt），又译技术债，也称为设计负债（design debt）、代码负债（code debt），是编程及软件工程中的借鉴了财务债务的系统隐喻。指开发人员为了加速软件开发，在应该采用最佳方案时进行了妥协，改用了短期内能加速软件开发的方案，从而在未来给自己带来的额外开发负担。这种技术上的选择，就像一笔债务一样，虽然眼前看起来可以得到好处，但必须在未来偿还。软件工程师必须付出额外的时间和精力持续修复之前的妥协所造成的问题及副作用，或是进行重构，把架构改善为最佳实现方式。&lt;/p&gt;
&lt;p&gt;1992 年，沃德 · 坎宁安首次将技术的复杂比作为负债。第一次发布代码，就好比借了一笔钱。只要通过不断重写来偿还债务，小额负债便可以加速开发。但久未偿还债务会引发危险。复用马马虎虎的代码，类似于负债的利息。整个部门有可能因为松散的实现，不完全的面向对象的设计或其他诸如此类的负债而陷入窘境。&lt;/p&gt;
&lt;p&gt;二、技术债表现&lt;/p&gt;
&lt;p&gt;技术债与其他债务本身一样，是一种透支行为，通过牺牲未来来满足当下的一些需求。也跟其他债务一样，技术债务也有利息，而且随着时间利滚利，会成为埋在项目里的定时炸弹。如果产品长期的可持续的发展，那么技术债的重要性是毋庸置疑的。&lt;/p&gt;
&lt;p&gt;技术债务的本质是产品的结构阻碍了进步，表现出来的症状有：无法轻易重构产品以满足市场需求；组件之间的依赖性过多，体系结构不良；缺陷太多，结构不良；难以理解，难以改变。&lt;/p&gt;
&lt;p&gt;技术债务的后果有偿还技术债务造成时间浪费，员工满意度降低带来士气低落，因解决遗留代码问题而错过优质项目造成人才流失，产品质量降低造成客户满意度下降，技术债务限制创新能力、扼杀创造性等诸多问题。&lt;/p&gt;
&lt;p&gt;技术债不单单是技术债，它就像一个垃圾堆，久而久之不处理，慢慢周围就会产生更多的垃圾，因此产生的 “破窗效应” 更加是会对未来的项目环境造成很大的影响，大家也会逐渐丧失维护环境的信心。所以在讨论技术债的时候不仅仅是讨论技术债本身，技术债对团队追求质量的信心、对大家维护环境整洁的积极性都会造成很大的影响。&lt;/p&gt;
&lt;p&gt;MartinFowler 把技术债分为四个象限，如下图所示：&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/eac4b74543a98226442e205e821997094b90eb7b.jpeg&#34;&gt;&lt;/p&gt;
&lt;p&gt;三、技术债产生的原因&lt;/p&gt;
&lt;p&gt;●业务压力：为了满足业务的快速要求，在必要的修改并没有完成时就匆匆发布，这些未完成的修改就形成了技术负债。&lt;/p&gt;
&lt;p&gt;●缺少过程和理解：业务人员不清楚不理解技术负债的概念，在决策时就不会考虑到其带来的影响。&lt;/p&gt;
&lt;p&gt;●模块之间解耦不够：功能没有模块化，软件柔性不够，不足适应业务变化的要求。&lt;/p&gt;
&lt;p&gt;●缺少配套的自动化测试：导致鼓励快速而风险很大的 “创可贴” 式的 BUG 修复。&lt;/p&gt;
&lt;p&gt;●缺少必要文档：需求和代码都没有必要的支撑性文档或注释。&lt;/p&gt;
&lt;p&gt;●缺少协作：组织中的知识共享和业务效率较低，或者初级开发者缺少必要的指导。&lt;/p&gt;
&lt;p&gt;●重构延迟：在开发的过程中，某些部分的代码会变得难以控制，这时候就需要进行重构，以适应将来的需求变化。重构越是推迟，这些已有的代码被使用的越多，形成的技术负债就越多，直到重构完成。&lt;/p&gt;
&lt;p&gt;●不遵循标准或最佳实践：忽略了已有的业界标准、框架、技术和最佳实践。&lt;/p&gt;
&lt;p&gt;●缺少相关技能：开发人员有时候技能缺失，并不知道如何编写优雅的代码。&lt;/p&gt;
&lt;p&gt;四、如何 “还债”？&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;技术债可视化&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;尽可能公开技术债，一开始就与团队，利益相关方一起权衡利弊，并明确告知影响与解决方案。平等沟通，相互理解。让技术债在业务层面、技术层面可见。&lt;/p&gt;
&lt;p&gt;可以在组织资产负债表的财产债中新增两列：短期技术债和长期技术债。还可以用用跟踪开发速率的方式体现技术债对于产品的影响。&lt;/p&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;不同的债要对症下药&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;技术债的状态可以分类为偶然技术债、已知技术债和目标技术债。&lt;/p&gt;
&lt;p&gt;偿还技术债时应遵循如下原则：&lt;/p&gt;
&lt;p&gt;1）确定已知技术债必须还。&lt;/p&gt;
&lt;p&gt;2）发现偶然技术债，立即还。&lt;/p&gt;
&lt;p&gt;3）每个冲刺确定一定数量的已知技术债作为目标技术债，在当前冲刺中偿还。&lt;/p&gt;
&lt;p&gt;4）无需偿还的技术债是行将就木的产品、一次性原型和短命产品。&lt;/p&gt;
&lt;p&gt;五、如何避免 “欠债”&lt;/p&gt;
&lt;p&gt;与其后期吭哧吭哧还债填坑，不如从一开始就尽量避免欠下技术债务。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;避免使用过时的技术&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;遗留应用程序、过时的技术以及不同的平台和流程可能会使组织陷入沉重的技术债务，迫使其推迟基本的现代化计划。DNS 和流量管理技术提供商 NS1 的联合创始人兼首席执行官 Kris Beevers 说：“技术债务将大量金钱和宝贵的时间浪费在系统和应用程序上，而这些系统和应用程序并不是为现代企业所需的规模和速度而打造的。”&lt;/p&gt;
&lt;p&gt;旧资产和老方法也往往充斥着安全漏洞，难以集成和自动化，并且很可能不再更新。 Beevers 指出：“寻找人才来管理基于复杂或过时的代码构建的遗留应用程序也是一个日益严峻的难题。坚持采用过时技术不仅会消耗宝贵的预算，而且还会阻碍公司创新和保持竞争力的能力。”&lt;/p&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;参考敏捷实践&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;有越来越多的组织渐渐接受敏捷软件开发，这是将方法交给协作、自行组织的团队和跨职能团队的一系列方法和实践。如果这种方法得到严格应用，敏捷开发使组织可以避免技术债务，其方法是快速且以迭代的方式创建和发布新产品。Dodd 说：“这一过程将新产品和新功能尽快并逐步地交到用户手中。” 随着新版本的交付，各种改进和问题都得到了解决，这使技术债务的积累不太可能产生。&lt;/p&gt;
&lt;p&gt;敏捷方法认识到项目在生命周期中从未真正完成过，并且也从来都不是完美的。“同时，敏捷方法专注于…… 针对能力和质量的简化了的开发”，Dodd 说。重要功能往往要频繁地开发，测试并投入生产。敏捷团队可能不会发布软件的 “全面（Big Bang）” 方法，而是每年发布几次重大升级。Dodd 指出：“这可以使产品保持相当平稳的发展，还可以帮助用户避免重大的中断事件。”&lt;/p&gt;</description>
    </item>
    <item>
      <title>关于maven项目的配置文件</title>
      <link>https://leochu.work/blog/tech/engineering/maven%E9%A1%B9%E7%9B%AE%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6/</link>
      <pubDate>Sun, 15 Oct 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/maven%E9%A1%B9%E7%9B%AE%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6/</guid>
      <description>&lt;p&gt;把项目的配置文件按运行环境做一下区分，比如开发环境和线上环境使用的使用不同的配置文件，这里我们基于项目的 &lt;code&gt;resoures/&lt;/code&gt; 目录来实现：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# resoures 目录
.
├── env
│   ├── config.dev.properties
│   └── config.prod.properties
└── config.properties
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;我们创建了一个 &lt;code&gt;config.properties&lt;/code&gt; 文件来配置项目的常用配置数据，如， &lt;code&gt;kafaka&lt;/code&gt; 、 &lt;code&gt;redis&lt;/code&gt; 等连接配置等。&lt;/p&gt;
&lt;p&gt;然后创建一个 &lt;code&gt;env&lt;/code&gt; 子目录，并创建两个环境对应的配置文件，我们希望不同的环境当中使用不同的配置。当然，光是创建这些文件，是无法让文件实现自动按照运行环境自动实现文件匹配的，我们还需要配置 &lt;code&gt;pom.xml&lt;/code&gt; 文件：&lt;/p&gt;
&lt;p&gt;首先，找到 &lt;code&gt;&amp;lt;build&amp;gt;&lt;/code&gt; 配置字段，添加文件路径：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;build&amp;gt;
    &amp;lt;!-- Loading all ${} --&amp;gt;
    &amp;lt;filters&amp;gt;
        &amp;lt;filter&amp;gt;src/main/resources/env/config.${env}.properties&amp;lt;/filter&amp;gt;
    &amp;lt;/filters&amp;gt;
    &amp;lt;!-- Map ${} into resources --&amp;gt;
    &amp;lt;resources&amp;gt;
        &amp;lt;resource&amp;gt;
            &amp;lt;directory&amp;gt;src/main/resources&amp;lt;/directory&amp;gt;
            &amp;lt;filtering&amp;gt;true&amp;lt;/filtering&amp;gt;
            &amp;lt;includes&amp;gt;
                &amp;lt;include&amp;gt;*.properties&amp;lt;/include&amp;gt;
            &amp;lt;/includes&amp;gt;
        &amp;lt;/resource&amp;gt;
    &amp;lt;/resources&amp;gt;
    &amp;lt;!-- 省略之后若干行 --&amp;gt;
&amp;lt;/build&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上述代码目的是告诉构建工具，在构建的时候需要加载 &lt;code&gt;resoures&lt;/code&gt; 目录的配置文件参与构建，并且使用 &lt;code&gt;${env}&lt;/code&gt; 环境变量来决定具体加载的名称。&lt;/p&gt;
&lt;p&gt;因此，我们还需要指定 &lt;code&gt;${env}&lt;/code&gt; 的环境变量配置，在 &lt;code&gt;&amp;lt;profiles&amp;gt;&lt;/code&gt; 标签下，移除默认的 &lt;code&gt;&amp;lt;profile&amp;gt;&lt;/code&gt; 配置内容，新建两份环境配置 &lt;code&gt;dev&lt;/code&gt; 和 &lt;code&gt;prod&lt;/code&gt; 的 &lt;code&gt;profile&lt;/code&gt; 文件配置：&lt;/p&gt;</description>
    </item>
    <item>
      <title>关于设计模式</title>
      <link>https://leochu.work/blog/tech/engineering/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E6%A6%82%E8%BF%B0/</link>
      <pubDate>Sun, 01 Oct 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E6%A6%82%E8%BF%B0/</guid>
      <description>&lt;h2 id=&#34;策略模式strategy-pattern&#34;&gt;【策略模式】（Strategy Pattern）&lt;/h2&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20230420121518.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230420121518.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;其中的Context是一个所谓的“上下文”，不一定非得是个类，也可以只是一个函数/方法。最关键的是，我们其实根本不需要ConcreteStrategyX类，也不需要它们的对象。我们要的只是一个execute函数而已，我们甚至连execute这个函数名都不需要，只要能执行它就行。&lt;/p&gt;
&lt;p&gt;看看函数式编程是怎么玩的（这里以大家都熟悉的JavaScript为例）：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;context&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;func&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// 做些什么...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;result&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;func&lt;/span&gt;()  &lt;span style=&#34;color:#75715e&#34;&gt;// 有需要的话可以传参
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// 再做些什么...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;context&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// 做些什么...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;123&lt;/span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// 是否需要返回值看需求
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;一个匿名函数参数&lt;code&gt;func&lt;/code&gt;搞定。&lt;/p&gt;
&lt;p&gt;Java能搞出这种类图来，全都是因为Java没有一等公民的函数，所以函数必须依附于类（静态方法）或者对象（非静态方法）。而玩静态方法又没法玩多态，而且类不能当成参数传递给其他函数/方法，所以只能用对象携带方法。而对象的方法必须有个名称，为了统一，就叫execute。由于需要多态，所以我们必须提一个接口出来，在接口里声明execute的方法签名。所有这一切说白了都是为了讨好Java编译器，否则它会给你颜色（red）看。&lt;/p&gt;
&lt;p&gt;当然，自从Java有了函数式接口和lambda后一定程度上也能玩函数式编程了。&lt;/p&gt;
&lt;h2 id=&#34;观察者模式observer-pattern&#34;&gt;【观察者模式】（Observer Pattern）&lt;/h2&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20230420121526.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230420121526.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;这个在JS里大家已经熟悉到不能再熟悉了：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;someButton&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;onclick&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;event&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// 处理点击事件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;又是一个匿名函数搞定！上图里的&lt;code&gt;Subject#attach&lt;/code&gt;在这里就是直接赋值。&lt;code&gt;Subject#detach&lt;/code&gt;就是赋空值。&lt;code&gt;Subject#notify&lt;/code&gt;就是调用一下匿名函数而已。而&lt;code&gt;Observer#update&lt;/code&gt;就是匿名函数本身。&lt;/p&gt;
&lt;h2 id=&#34;访问者模式visitor-pattern&#34;&gt;【访问者模式】（Visitor Pattern）&lt;/h2&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20230420121532.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230420121532.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;能整成这样我也是服了。说白了不就是访问者需要判断一下元素类型嘛。直接套用策略模式，在匿名函数里if-else一下不就行了？（当然还有其他方式，比如引入一个工厂。有模式匹配的函数式编程语言如Haskell、Erlang、Elixir等玩起来更简单）。&lt;/p&gt;
&lt;h2 id=&#34;装饰器模式decorator-pattern&#34;&gt;【装饰器模式】（Decorator Pattern）&lt;/h2&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20230420121538.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230420121538.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;这才是函数式编程的魅力所在！&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;core1&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;arg1&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;arg2&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// 做些啥
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;123&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;core2&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;arg&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// 做些啥
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;456&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;decorate&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;core&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// 做些准备工作
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;// 做些啥，甚至可以改变参数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;ret&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;core&lt;/span&gt;(...&lt;span style=&#34;color:#a6e22e&#34;&gt;arguments&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;// 做些啥，甚至可以改变返回值
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;ret&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;decorated1&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;decorate&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;core1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;decorated2&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;decorate&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;core2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;酷吧？又是匿名函数搞定！只不过这次的匿名函数是返回值。&lt;/p&gt;</description>
    </item>
    <item>
      <title>阿里编程规约</title>
      <link>https://leochu.work/blog/tech/engineering/%E9%98%BF%E9%87%8C%E7%BC%96%E7%A8%8B%E8%A7%84%E7%BA%A6/</link>
      <pubDate>Sun, 20 Aug 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/%E9%98%BF%E9%87%8C%E7%BC%96%E7%A8%8B%E8%A7%84%E7%BA%A6/</guid>
      <description>&lt;p&gt;命名风格&lt;/p&gt;
&lt;ol start=&#34;6&#34;&gt;
&lt;li&gt;
&lt;p&gt;【强制】抽象类命名使用 Abstract 或 Base 开头; 异常类命名使用 Exception 结尾; 测试类 命名以它要测试的类的名称开始，以 Test 结尾。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;【强制】POJO 类中布尔类型变量都不要加 is 前缀，否则部分框架解析会引起序列化错误。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;【强制】包名统一使用小写，点分隔符之间有且仅有一个自然语义的英语单词。包名统一使 用单数形式，但是类名如果有复数含义，类名可以使用复数形式。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;正例: 应用工具类包名为 com.alibaba.ai.util、类名为 MessageUtils&lt;/p&gt;
&lt;ol start=&#34;13&#34;&gt;
&lt;li&gt;【推荐】在常量与变量的命名时，表示类型的名词放在词尾，以提升辨识度。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;正例: startTime / workQueue / nameList / TERMINATED_THREAD_COUNT&lt;/p&gt;
&lt;p&gt;17.【参考】枚举类名带上 Enum 后缀，枚举成员名称需要全大写，单词间用下划线隔开。&lt;/p&gt;
&lt;p&gt;B) 领域模型命名规约&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;数据对象: xxxDO，xxx 即为数据表名。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;数据传输对象: xxxDTO，xxx 为业务领域相关的名称。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;展示对象: xxxVO，xxx 一般为网页名称。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;POJO 是 DO/DTO/BO/VO 的统称，禁止命名成 xxxPOJO。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;常量定义&lt;/p&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;
&lt;p&gt;【推荐】不要使用一个常量类维护所有常量，要按常量功能进行归类，分开维护。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;【推荐】如果变量值仅在一个固定范围内变化用 enum 类型来定义。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;SPRING(1), SUMMER(2), AUTUMN(3), WINTER(4);&lt;/p&gt;
&lt;p&gt;代码格式&lt;/p&gt;
&lt;ol start=&#34;5&#34;&gt;
&lt;li&gt;【强制】采用 4 个空格缩进，禁止使用 tab 字符。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;IDEA 设置 tab 为 4 个空格时，请勿勾选 Use tab character&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
