技術(shù)爭(zhēng)論:架構(gòu)決策的工程化方法)
最近在開發(fā)者社區(qū)刷到一個(gè)挺有話題性的帖子標(biāo)題大概是“A thought leadership battle leads to a drive by”還特意帶了一個(gè)[satire]標(biāo)簽。翻譯過(guò)來(lái)就是“一場(chǎng)思想領(lǐng)導(dǎo)力之爭(zhēng)最后演變成了開車路過(guò)式的偷襲”。雖然它是諷刺段子但技術(shù)圈的朋友應(yīng)該都能會(huì)心一笑技術(shù)選型群里、架構(gòu)評(píng)審會(huì)上、開源項(xiàng)目 issue 區(qū)里這種“嘴上聊方案、實(shí)際搞站隊(duì)”的場(chǎng)面其實(shí)不少見。作為一個(gè)經(jīng)常寫技術(shù)教程、做方案評(píng)審的人我反而覺得這類現(xiàn)象值得認(rèn)真聊一次。技術(shù)圈不缺觀點(diǎn)缺的是把觀點(diǎn)變成可驗(yàn)證、可追溯、可落地的工程方法。所以本文不打算討論那個(gè)諷刺帖子本身而是從“思想領(lǐng)導(dǎo)力之爭(zhēng)為什么容易跑偏”這個(gè)現(xiàn)象出發(fā)分享一套我平時(shí)用來(lái)組織技術(shù)討論、做方案評(píng)審、寫技術(shù)決策記錄的實(shí)操方法包括 ADR架構(gòu)決策記錄、技術(shù)選型對(duì)比矩陣、POC 驗(yàn)證流程、評(píng)審檢查清單以及如何寫出別人愿意認(rèn)真閱讀而不是急著反駁的技術(shù)文章。無(wú)論你是團(tuán)隊(duì)的技術(shù)負(fù)責(zé)人、架構(gòu)師、后端開發(fā)還是正在學(xué)習(xí)如何做技術(shù)輸出的博主這篇文章都能給你一套可以直接拿來(lái)用的框架。1. “思想領(lǐng)導(dǎo)力之爭(zhēng)”背后的技術(shù)溝通問(wèn)題1.1 先理解什么是 Thought LeadershipThought Leadership 在國(guó)內(nèi)技術(shù)圈通常被翻譯成“思想領(lǐng)導(dǎo)力”或“技術(shù)影響力”。它最早是咨詢行業(yè)的概念指的是一家公司或個(gè)人通過(guò)持續(xù)輸出有洞察力的內(nèi)容讓外界認(rèn)為你在某個(gè)領(lǐng)域擁有領(lǐng)先的認(rèn)知從而影響客戶決策。傳到技術(shù)圈后這個(gè)概念被簡(jiǎn)化成了兩種表現(xiàn)一種是正向的長(zhǎng)期寫高質(zhì)量技術(shù)博客、在開源項(xiàng)目里貢獻(xiàn)設(shè)計(jì)文檔、在技術(shù)大會(huì)上分享可落地的實(shí)踐通過(guò)輸出價(jià)值來(lái)建立專業(yè)影響力。另一種是變味的過(guò)度追逐“我有觀點(diǎn)、我要贏”把技術(shù)討論當(dāng)成了辯論賽把“說(shuō)服對(duì)方”當(dāng)成比“找到正確答案”更重要的事。諷刺標(biāo)題里說(shuō)的 drive by本質(zhì)就是對(duì)這種變味文化的夸張吐槽你說(shuō)你的方案我不論證我直接攻擊你的立場(chǎng)打完就撤。技術(shù)人如果陷入第二種狀態(tài)危害是很直接的。團(tuán)隊(duì)內(nèi)部的技術(shù)選型會(huì)從“哪個(gè)方案更適合業(yè)務(wù)”變成“誰(shuí)的聲音更大”跨團(tuán)隊(duì)協(xié)作時(shí)文檔里寫的是結(jié)論評(píng)論區(qū)里全是情緒開源社區(qū)里一個(gè) issue 本來(lái)是討論 bug 的最后變成了維護(hù)者和使用者之間的互相指責(zé)。所以真正值得建設(shè)的思想領(lǐng)導(dǎo)力不是“我能吵贏”而是“我能把復(fù)雜的工程問(wèn)題梳理清楚讓所有參與討論的人基于同一份事實(shí)說(shuō)話”。1.2 為什么技術(shù)爭(zhēng)論容易變成“開車路過(guò)式偷襲”我觀察下來(lái)根本原因有三個(gè)。第一個(gè)原因是缺少共同的事實(shí)基線。很多時(shí)候兩撥人爭(zhēng)論 Redis 和 MemcachedA 組說(shuō)“Redis 快”B 組說(shuō)“Memcached 更快”但誰(shuí)都沒說(shuō)自己用的是哪個(gè)版本、什么數(shù)據(jù)結(jié)構(gòu)、什么樣的請(qǐng)求模型、多少并發(fā)。沒有基線討論就只是感受互換不是方案比較。第二個(gè)原因是缺少結(jié)構(gòu)化的表達(dá)方式。大多數(shù)開發(fā)者習(xí)慣用即時(shí)通訊工具討論架構(gòu)問(wèn)題比如在群里發(fā)一段文字加兩張截圖。這種表達(dá)天然是碎片化的很容易讓人抓住一兩句話開始反駁而不是完整理解方案的全貌。第三個(gè)原因是缺少可回滾、可追溯的決策機(jī)制。當(dāng)團(tuán)隊(duì)里沒有正式的決策記錄文件時(shí)所有決定都靠記憶而記憶是最容易被立場(chǎng)污染的。一旦后來(lái)出現(xiàn)問(wèn)題沒有人記得當(dāng)初為什么做這個(gè)決定于是“甩鍋”就發(fā)生了技術(shù)問(wèn)題開始轉(zhuǎn)向人際關(guān)系問(wèn)題。諷刺貼里的 drive by 之所以出現(xiàn)恰恰是因?yàn)橛懻撜邲]有一套可以“把球停下來(lái)”的機(jī)制。接下來(lái)的章節(jié)我會(huì)圍繞這個(gè)問(wèn)題給出具體的工具和方法。2. 準(zhǔn)備一套支撐理性討論的工程環(huán)境要支撐一場(chǎng)高質(zhì)量的技術(shù)討論我們需要的不只是溝通技巧還需要一套輕量的工程環(huán)境來(lái)承載討論過(guò)程。這套環(huán)境的成本不需要很高通常只需要三樣?xùn)|西一個(gè) Git 倉(cāng)庫(kù)團(tuán)隊(duì)內(nèi)部可用 GitLab/Gitee個(gè)人可用 GitHub用來(lái)存放方案文檔和 ADR。一個(gè) Markdown 編輯器VS Code、Typora、Obsidian 都行或者直接用 Git 倉(cāng)庫(kù)自帶的 Web IDE。一個(gè)命令行終端用于執(zhí)行代碼示例、跑測(cè)試腳本或者生成文檔目錄。核心思路是一切技術(shù)結(jié)論都要落到倉(cāng)庫(kù)里而不是停留在聊天記錄里。下面給出一個(gè)建議的倉(cāng)庫(kù)目錄結(jié)構(gòu)tech-decisions/ ├── docs/ │ ├── proposals/ │ │ ├── 2024-01-cache-selection.md │ │ └── 2024-03-message-queue-selection.md │ └── templates/ │ ├── adr-template.md │ └── review-checklist.md ├── adr/ │ ├── ADR-0001-use-redis-as-cache.md │ ├── ADR-0002-adopt-kafka-for-event-stream.md │ └── README.md ├── experiments/ │ ├── benchmark/ │ │ └── compare_cache.py │ └── poc/ │ └── lua-script-demo/ ├── scripts/ │ └── init-adr.sh └── README.md初始化倉(cāng)庫(kù)時(shí)可以執(zhí)行# 創(chuàng)建目錄結(jié)構(gòu) mkdir -p tech-decisions/{docs/{proposals,templates},adr,experiments,scripts} # 初始化 Git 倉(cāng)庫(kù) cd tech-decisions git init # 如果需要遠(yuǎn)程協(xié)作關(guān)聯(lián)遠(yuǎn)程倉(cāng)庫(kù) git remote add origin gitgithub.com:yourname/tech-decisions.git # 建立 main 分支并提交初始文件 git checkout -b main git add . git commit -m chore: init tech decision repository這一套環(huán)境一旦建立起來(lái)團(tuán)隊(duì)就有了一個(gè)“唯一事實(shí)來(lái)源”Single Source of Truth。以后發(fā)生爭(zhēng)論時(shí)任何一個(gè)人都可以說(shuō)“我們先把各自的方案寫進(jìn)docs/proposals/然后按照評(píng)審流程走一遍而不是在群里空談。”我個(gè)人建議不管團(tuán)隊(duì)規(guī)模多小都從第一天開始做這件事。哪怕只是兩個(gè)人的后端小組有一個(gè)決策倉(cāng)庫(kù)也比微信聊天記錄可靠得多。因?yàn)榧夹g(shù)選型的生命周期往往比任何一個(gè)參與討論的人在公司的時(shí)間都長(zhǎng)。3. 用 ADR 把爭(zhēng)論落成可追溯的技術(shù)決策3.1 ADR 是什么ADR 全稱是 Architecture Decision Record也就是架構(gòu)決策記錄。它最早由 Michael Nygard 在《Release It!》中提出現(xiàn)在已經(jīng)成了很多技術(shù)團(tuán)隊(duì)做架構(gòu)治理的基本單位。一句話概括ADR 是一份簡(jiǎn)短的結(jié)構(gòu)化文檔記錄“在什么背景下我們面臨什么問(wèn)題考慮了哪些方案最終為什么選了 A 而不是 B以及接受了哪些代價(jià)”。ADR 最大的價(jià)值在于它讓決策過(guò)程從口頭爭(zhēng)論變成了文字檔案。以后任何人看代碼都能找到當(dāng)初設(shè)計(jì)時(shí)的上下文。3.2 ADR 標(biāo)準(zhǔn)模板一個(gè)精簡(jiǎn)可用的 ADR 模板我通常寫成這樣保存為templates/adr-template.md# ADR-XXXX: [決策標(biāo)題] - 狀態(tài)提議 / 已接受 / 已拒絕 / 已廢棄 / 被 ADR-YYYY 取代 - 日期YYYY-MM-DD - 決策者[參與決策的核心成員] - 評(píng)審人[需要 review 的人員] ## 背景 [為什么需要做這個(gè)決策業(yè)務(wù)和技術(shù)上面臨什么問(wèn)題] ## 決策 [我們用一句話說(shuō)明最終選擇。] ## 備選方案 ### 方案 A[名稱] - 優(yōu)點(diǎn)... - 缺點(diǎn)... - 驗(yàn)證情況... ### 方案 B[名稱] - 優(yōu)點(diǎn)... - 缺點(diǎn)... - 驗(yàn)證情況... ## 選擇依據(jù) [可以引用性能對(duì)比數(shù)據(jù)、團(tuán)隊(duì)熟悉度、生態(tài)成熟度、運(yùn)維成本等維度。] ## 后果 [接受這個(gè)決策后正面影響是什么負(fù)面影響或額外成本是什么] ## 關(guān)聯(lián)文檔 - [POC 報(bào)告鏈接] - [性能基準(zhǔn)測(cè)試結(jié)果] - [相關(guān) issue 鏈接]3.3 一個(gè)具體示例緩存組件選型假設(shè)團(tuán)隊(duì)在做緩存選型爭(zhēng)論點(diǎn)在 Redis 和 Memcached 之間。傳統(tǒng)討論會(huì)上大家各說(shuō)各話但如果寫成 ADR內(nèi)容會(huì)清晰得多。下面是一個(gè)簡(jiǎn)化示例核心是保留決策依據(jù)而不是爭(zhēng)論過(guò)程中的每一句話# ADR-0001: 使用 Redis 作為業(yè)務(wù)緩存組件 - 狀態(tài)已接受 - 日期2024-06-10 - 決策者張三后端、李四架構(gòu)、王五運(yùn)維 ## 背景 訂單服務(wù)上線后熱點(diǎn)商品詳情接口的 QPS 接近 8000數(shù)據(jù)庫(kù)壓力偏高。 需要在入口層和業(yè)務(wù)層之間增加緩存目標(biāo)是降低 60% 以上的數(shù)據(jù)庫(kù)查詢。 ## 決策 優(yōu)先使用 Redis 7.x 作為緩存層業(yè)務(wù)側(cè)使用 Jedis / Lettuce 接入。 ## 備選方案 ### 方案 AMemcached - 優(yōu)點(diǎn)內(nèi)存利用率高多線程模型成熟在純 KV 緩存場(chǎng)景表現(xiàn)穩(wěn)定。 - 缺點(diǎn)只支持字符串類型無(wú)法覆蓋后續(xù)的排行榜、分布式鎖、Lua 腳本需求。 - 驗(yàn)證情況POC 中 Memcached 讀吞吐約 12w QPS滿足當(dāng)前壓力。 ### 方案 BRedis - 優(yōu)點(diǎn)數(shù)據(jù)結(jié)構(gòu)豐富社區(qū)活躍后續(xù)可擴(kuò)展到分布式鎖和輕量隊(duì)列。 - 缺點(diǎn)RDB/AOF 持久化配置增加運(yùn)維成本大 key 需要規(guī)范約束。 - 驗(yàn)證情況使用 4 核 8G 容器SET/GET 混合讀寫壓測(cè)約 9w QPS。 ## 選擇依據(jù) 1. 當(dāng)前業(yè)務(wù)未來(lái) 6 個(gè)月會(huì)增加排行榜和限量秒殺場(chǎng)景Redis 可以覆蓋。 2. 團(tuán)隊(duì)成員對(duì) Redis 的使用經(jīng)驗(yàn)更豐富故障排查成本低。 3. 運(yùn)維側(cè)已具備 Redis 監(jiān)控和告警面板接入成本低于 Memcached。 ## 后果 - 正向緩存能力可擴(kuò)展部分非核心數(shù)據(jù)可以長(zhǎng)期駐留。 - 負(fù)向必須增加 key 規(guī)范、內(nèi)存上限淘汰策略和慢日志告警 后續(xù)需要補(bǔ)充 Redis Cluster 橫向擴(kuò)容的壓測(cè)報(bào)告。 ## 關(guān)聯(lián)文檔 - experiments/benchmark/compare_cache.py - docs/proposals/2024-06-cache-selection.md可以看到ADR 不追求把所有爭(zhēng)論過(guò)程記錄下來(lái)它只記錄關(guān)鍵結(jié)論和依據(jù)。當(dāng)爭(zhēng)論再次發(fā)生時(shí)新的討論是基于這份文檔的補(bǔ)充和修訂而不是重新吵一遍。4. 用技術(shù)選型矩陣和 POC 代替“我覺得”4.1 評(píng)估矩陣先統(tǒng)一維度再打分ADR 是結(jié)果載體但在寫 ADR 之前我們通常需要先做一輪方案對(duì)比。方案對(duì)比最忌諱上來(lái)就打分因?yàn)槊總€(gè)人心里的權(quán)重不一樣。正確做法是先定維度再討論權(quán)重最后才是打分。下面是一個(gè)常見的緩存方案評(píng)估模板## 技術(shù)選型評(píng)估表緩存組件 | 維度 | 權(quán)重 | Redis | Memcached | 說(shuō)明 | | --- | --- | --- | --- | --- | | 性能表現(xiàn) | 25% | 8 | 9 | 按 POC 壓測(cè)結(jié)果 | | 數(shù)據(jù)結(jié)構(gòu)豐富度 | 20% | 9 | 4 | 是否覆蓋未來(lái)需求 | | 運(yùn)維成熟度 | 15% | 8 | 7 | 監(jiān)控、告警、管理工具 | | 團(tuán)隊(duì)熟悉度 | 15% | 9 | 6 | 團(tuán)隊(duì)成員經(jīng)驗(yàn) | | 生態(tài)與社區(qū)活躍度 | 10% | 9 | 6 | 資料、客戶端、維護(hù)方 | | 擴(kuò)展性 | 15% | 9 | 7 | 集群方案是否成熟 | | 加權(quán)總分 | 100% | 8.60 | 6.60 | 計(jì)算方式見下 | 加權(quán)總分 Σ(維度分 × 權(quán)重)需要特別提醒的是表格中的 8、9 這類數(shù)字必須源于一個(gè)可核驗(yàn)的依據(jù)比如“我們壓測(cè)得到的結(jié)果是 Redis 單實(shí)例 QPS 在目標(biāo)數(shù)據(jù)量下為 9wMemcached 為 12w”。如果只是憑感覺打分這個(gè)表格就沒有意義。4.2 用最小 POC 驗(yàn)證核心假設(shè)評(píng)估矩陣再漂亮也不能替代實(shí)際驗(yàn)證。特別是當(dāng)爭(zhēng)論集中在性能、穩(wěn)定性等技術(shù)指標(biāo)時(shí)最快終結(jié)爭(zhēng)論的方式是寫一個(gè)最小的 POC跑一組可復(fù)現(xiàn)的測(cè)試然后把結(jié)果貼到文檔里。以下是一個(gè)簡(jiǎn)化版緩存對(duì)比腳本使用 Python 標(biāo)準(zhǔn)庫(kù)中的time模塊做的基準(zhǔn)示例不依賴第三方基準(zhǔn)工具。它用來(lái)驗(yàn)證“在某個(gè)數(shù)據(jù)量級(jí)下讀寫耗時(shí)是否滿足業(yè)務(wù)預(yù)期”而不是做完整的壓測(cè)。真實(shí)項(xiàng)目建議使用 wrk、JMeter、k6 或 Gatling 等專業(yè)工具。# 文件路徑experiments/benchmark/compare_cache.py 用于對(duì)比不同緩存客戶端在本地環(huán)境下的讀寫耗時(shí)參考。 說(shuō)明本腳本只是一個(gè)示例思路真實(shí)場(chǎng)景需要結(jié)合業(yè)務(wù)讀寫模型調(diào)整。 運(yùn)行前請(qǐng)先安裝對(duì)應(yīng)客戶端庫(kù)例如 pip install redis pymemcache import time from statistics import mean import redis from pymemcache.client.base import Client def bench_redis(rounds1000): client redis.Redis(host127.0.0.1, port6379, db0) costs [] key bench:key value bench_value * 100 for _ in range(rounds): start time.perf_counter() client.set(key, value) client.get(key) costs.append(time.perf_counter() - start) return mean(costs) def bench_memcached(rounds1000): client Client((127.0.0.1, 11211)) costs [] key bench:key value bench_value * 100 for _ in range(rounds): start time.perf_counter() client.set(key, value) client.get(key) costs.append(time.perf_counter() - start) return mean(costs) if __name__ __main__: # 預(yù)熱并不嚴(yán)謹(jǐn)僅為示例正式測(cè)試請(qǐng)多次運(yùn)行并取中位數(shù) print(fRedis 平均讀寫耗時(shí): {bench_redis():.6f} 秒) print(fMemcached 平均讀寫耗時(shí): {bench_memcached():.6f} 秒)命令示例cd experiments/benchmark pip install redis pymemcache python compare_cache.py輸出類似Redis 平均讀寫耗時(shí): 0.000221 秒 Memcached 平均讀寫耗時(shí): 0.000198 秒這里要強(qiáng)調(diào)一下單機(jī)本地測(cè)試的結(jié)果只能說(shuō)明當(dāng)前網(wǎng)絡(luò)環(huán)境和取值規(guī)模下的大致表現(xiàn)不能作為全局性能結(jié)論。腳本中注解也說(shuō)明了這一點(diǎn)。POC 的目的是驗(yàn)證“方案是否可行”而不是給方案蓋棺定論。真正的選型還需要結(jié)合壓測(cè)環(huán)境、部署架構(gòu)、數(shù)據(jù)量增長(zhǎng)曲線一起看。寫完 POC 后務(wù)必把運(yùn)行環(huán)境、依賴版本、原始輸出記錄到文檔里。這樣當(dāng)有人質(zhì)疑“你的數(shù)據(jù)是不是編的”時(shí)你只需要告訴他“運(yùn)行一下experiments/benchmark里的腳本可以復(fù)現(xiàn)”即可。5. 技術(shù)評(píng)審把“反對(duì)你”變成“反對(duì)你的方案”5.1 評(píng)審檢查清單寫技術(shù)方案文檔時(shí)靠情緒化的爭(zhēng)論是低效的。成熟團(tuán)隊(duì)通常會(huì)準(zhǔn)備一份 Review Checklist讓評(píng)審人按圖索驥。下面是一份精簡(jiǎn)版的后端方案評(píng)審檢查清單保存為docs/templates/review-checklist.md# 技術(shù)方案 Review Checklist - [ ] 背景是否說(shuō)清楚新的讀者能否在 3 分鐘內(nèi)理解為什么做這個(gè)方案 - [ ] 是否列出了至少 2 個(gè)備選方案 - [ ] 備選方案的優(yōu)缺點(diǎn)是否有依據(jù)有沒有 POC 數(shù)據(jù)或引用文檔 - [ ] 是否說(shuō)清了拒絕的方案以及拒絕理由 - [ ] 是否包含失敗場(chǎng)景分析比如中間件宕機(jī)、數(shù)據(jù)超時(shí)、流量突增 - [ ] 是否評(píng)估了運(yùn)維成本包括監(jiān)控、告警、日志、備份 - [ ] 是否明確了上線步驟和回滾方案 - [ ] 是否對(duì)團(tuán)隊(duì)現(xiàn)有代碼結(jié)構(gòu)做了兼容性說(shuō)明建議把這份清單和 PR/MR 模板綁定。當(dāng)有人提交技術(shù)方案文檔時(shí)MR 描述里必須勾選這些項(xiàng)否則不能進(jìn)入評(píng)審流程。5.2 評(píng)審意見的表達(dá)結(jié)構(gòu)Review 過(guò)程里最影響氛圍的是“話術(shù)表達(dá)”。同樣一個(gè)意見用結(jié)論式表達(dá)和用結(jié)構(gòu)化表達(dá)效果完全不同。我先舉一個(gè)反例“這個(gè)方案有問(wèn)題Redis Cluster 在腦裂場(chǎng)景下會(huì)丟數(shù)據(jù)建議再看看?!边@句話可能是對(duì)的但它沒有說(shuō)明問(wèn)題嚴(yán)重到什么程度也沒給出驗(yàn)證路徑。被提意見的人容易覺得對(duì)方在抬杠。正面的表達(dá)結(jié)構(gòu)建議為觀察Observation→ 影響Impact→ 建議Suggestion→ 期望補(bǔ)充的信息Request。改寫后【觀察】方案里提到 Redis Cluster 在故障切換時(shí)表現(xiàn)良好但文檔沒有覆蓋網(wǎng)絡(luò)分區(qū)場(chǎng)景。 【影響】在跨可用區(qū)部署時(shí)如果發(fā)生分區(qū)Cluster 可能進(jìn)入 fail 狀態(tài)期間寫入會(huì)報(bào)錯(cuò)雖然我們目前可以容忍短暫不可用但需要確認(rèn)業(yè)務(wù)對(duì)錯(cuò)誤的處理是否符合預(yù)期。 【建議】補(bǔ)充一段“網(wǎng)絡(luò)分區(qū)下的行為分析”或者用redis-cli在測(cè)試環(huán)境模擬一次節(jié)點(diǎn)宕機(jī)看看客戶端報(bào)錯(cuò)和恢復(fù)耗時(shí)。 【期望補(bǔ)充】如果已經(jīng)做過(guò)類似演練直接把結(jié)果貼到文檔里就可以了。這樣的表達(dá)把“我不認(rèn)同你”轉(zhuǎn)化成了“我需要更多的信息來(lái)確認(rèn)風(fēng)險(xiǎn)”討論焦點(diǎn)保持在方案上而不是個(gè)人能力上。我甚至建議團(tuán)隊(duì)約定下面三條評(píng)審原則可以質(zhì)疑方案不要質(zhì)疑人的動(dòng)機(jī)。指出問(wèn)題的時(shí)候盡量給出一個(gè)可執(zhí)行的最小動(dòng)作。如果自己的信息和對(duì)方不一致先檢查共同基線而不是急著下結(jié)論。6. 技術(shù)寫作用教程型內(nèi)容輸出真正的影響力6.1 為什么教程比觀點(diǎn)更容易建立長(zhǎng)期信任回到思想領(lǐng)導(dǎo)力這個(gè)話題。技術(shù)圈里真正被長(zhǎng)期記住的內(nèi)容往往不是“某某技術(shù)天下第一”這樣的論斷而是可以照著做、做出來(lái)之后驗(yàn)證成功的實(shí)踐內(nèi)容。我寫技術(shù)博客有一個(gè)習(xí)慣每篇文章都盡量保證讀者能復(fù)現(xiàn)。公眾號(hào)和短視頻喜歡“金句”但技術(shù)社區(qū)需要的不是說(shuō)教而是“把配置給我把代碼給我告訴我為什么這樣寫”。一篇好的技術(shù)教程里觀點(diǎn)只是骨架演示步驟、代碼示例、版本說(shuō)明和排錯(cuò)方法才是血肉。6.2 教程型技術(shù)文章的三項(xiàng)基本要求第一必須寫清環(huán)境與版本。比如介紹某個(gè)框架時(shí)不要說(shuō)“新版本支持”要直接列出你用的是什么版本。至少給出以下信息的其中一項(xiàng)操作系統(tǒng)、JDK/Python 版本、依賴版本號(hào)、測(cè)試日期。就像下面這個(gè)示例- 操作系統(tǒng)Ubuntu 22.04 - JDKTemurin 17 - Spring Boot3.2.5 - MySQL8.0.36 - 構(gòu)建工具M(jìn)aven 3.9.6第二示例代碼必須完整且可復(fù)制。不要只貼一個(gè)方法的片段卻不告訴讀者這個(gè)方法應(yīng)該放在哪個(gè)類里。即使只是片段也要注明文件路徑和前后依賴。一個(gè)標(biāo)準(zhǔn)的代碼組織方式是這樣// 文件路徑src/main/java/com/example/service/CacheService.java import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; Service public class CacheService { private final StringRedisTemplate redisTemplate; public CacheService(StringRedisTemplate redisTemplate) { this.redisTemplate redisTemplate; } public void setValue(String key, String value) { redisTemplate.opsForValue().set(key, value); } public String getValue(String key) { return redisTemplate.opsForValue().get(key); } }第三要給出預(yù)期的運(yùn)行結(jié)果或驗(yàn)證方法。比如運(yùn)行命令后期望輸出什么日志或者訪問(wèn)哪個(gè)地址能看到什么效果。有了這一部分讀者才能確認(rèn)自己的操作是否成功。6.3 社區(qū)討論中的內(nèi)容輸出策略如果你希望能參與社區(qū)討論而不是被卷入嘴仗有兩個(gè)建議比較有效。第一個(gè)建議是只回復(fù)有明確問(wèn)題的帖子。對(duì)于那種“XX 已死”之類的標(biāo)題黨內(nèi)容沒必要浪費(fèi)時(shí)間。如果確實(shí)想表達(dá)不同觀點(diǎn)用“XX 在什么場(chǎng)景下適合但需要確認(rèn)……”比“你根本不懂 XX”要容易被人接受。第二個(gè)建議是把有價(jià)值的回復(fù)沉淀成文章。當(dāng)你在評(píng)論區(qū)里寫的內(nèi)容超過(guò)三百字時(shí)其實(shí)就可以考慮把它整理成一篇獨(dú)立博客了。因?yàn)樵u(píng)論區(qū)是單向即時(shí)表達(dá)文章才是可檢索、可收藏、可被搜索的資產(chǎn)。以后再遇到類似的問(wèn)題你只需丟一個(gè)鏈接而不用重復(fù)解釋。7. 常見溝通誤區(qū)和行動(dòng)清單為了把上面幾節(jié)的方法落地這里總結(jié)一份“技術(shù)爭(zhēng)論現(xiàn)場(chǎng)行動(dòng)清單”。下次你再遇到群里討論技術(shù)方案快要吵起來(lái)時(shí)可以按這個(gè)順序做場(chǎng)景常見的踩坑做法建議做法有人提出了明顯不合理的方案直接回復(fù)“不行別扯了”請(qǐng)對(duì)方先把方案寫完說(shuō)明使用場(chǎng)景和可驗(yàn)證結(jié)果兩撥人爭(zhēng)論性能數(shù)據(jù)引用網(wǎng)上文章說(shuō)“XX 就是快”跑一輪小規(guī)模壓測(cè)把環(huán)境和腳本貼出來(lái)與會(huì)者各說(shuō)各話偏離主題順著氣氛繼續(xù)聊提議指定主持人按評(píng)審檢查清單逐項(xiàng)推進(jìn)確定采用某個(gè)方案群里發(fā)個(gè)結(jié)論然后散會(huì)寫一份 ADR明確狀態(tài)、日期、決策人一個(gè)方案被推翻直接把原方案刪除或遺忘保留原 ADR把狀態(tài)改為“已廢棄”寫明原因評(píng)論他人博客或方案只輸出觀點(diǎn)而不給依據(jù)用“觀察-影響-建議-請(qǐng)求補(bǔ)充”的格式表達(dá)自己想輸出技術(shù)內(nèi)容只寫想法不寫代碼盡量寫成帶步驟、帶復(fù)現(xiàn)方式的教程型文章評(píng)審時(shí)發(fā)現(xiàn)同行的低級(jí)失誤在會(huì)議上點(diǎn)名批評(píng)私信溝通或給出修改建議公開場(chǎng)合注重建設(shè)性反饋針對(duì)最常見的“群聊爭(zhēng)論”場(chǎng)景我提供一個(gè)簡(jiǎn)單的流程模板你可以在自己團(tuán)隊(duì)里推廣任何技術(shù)方案討論超過(guò) 30 分鐘沒有結(jié)論馬上停止口頭討論。由發(fā)起人寫一份提案文檔模板參考前文的proposal。在 24 小時(shí)內(nèi)完成 POC至少驗(yàn)證一個(gè)核心風(fēng)險(xiǎn)點(diǎn)。技術(shù)評(píng)審會(huì)上只討論文檔內(nèi)容不做口頭長(zhǎng)篇陳述。結(jié)論用 ADR 固化并關(guān)聯(lián)到代碼倉(cāng)庫(kù)。8. 工程化你的技術(shù)影響力技術(shù)圈最稀缺的能力不是“贏過(guò)一次討論”而是“讓每一次討論都能沉淀為團(tuán)隊(duì)的工程資產(chǎn)”。當(dāng)一個(gè)團(tuán)隊(duì)開始用 ADR 記錄決策、用 POC 驗(yàn)證觀點(diǎn)、用評(píng)審清單統(tǒng)一標(biāo)準(zhǔn)時(shí)所謂的“思想領(lǐng)導(dǎo)力之爭(zhēng)”自然會(huì)減少——因?yàn)榇蠹野l(fā)現(xiàn)與其花力氣讓別人認(rèn)輸不如花力氣讓方案變好。如果你現(xiàn)在才開始動(dòng)手我建議從一件很小的事情開始在下一次技術(shù)方案討論前先建好tech-decisions倉(cāng)庫(kù)放上 ADR 模板。只要一次討論成功落地你就能感受到這套方法帶來(lái)的差異。如果你是一名技術(shù)內(nèi)容創(chuàng)作者也同樣可以借鑒這套思路寫文章時(shí)把版本寫清楚、把復(fù)現(xiàn)路徑寫清楚、把結(jié)論適用范圍寫清楚。長(zhǎng)期看這種“工程化表達(dá)”積累下來(lái)的影響力遠(yuǎn)比某次觀點(diǎn)交鋒里的短暫勝利更扎實(shí)。希望這篇文章能成為你構(gòu)建技術(shù)溝通體系的一份實(shí)用筆記。如果后續(xù)遇到具體的 ADR 編寫問(wèn)題或者想了解某個(gè)場(chǎng)景下的技術(shù)選型對(duì)比歡迎收藏后隨時(shí)回看。