[{"data":1,"prerenderedAt":425},["ShallowReactive",2],{"content:\u002F2025\u002Fcode-complete-2-notes":3,"surround:\u002F2025\u002Fcode-complete-2-notes":414},{"id":4,"title":5,"body":6,"categories":389,"date":391,"description":392,"draft":393,"extension":394,"image":395,"meta":396,"navigation":398,"path":399,"permalink":400,"published":400,"readingTime":401,"recommend":406,"references":400,"seo":407,"sitemap":408,"stem":409,"tags":410,"type":412,"updated":400,"__hash__":413},"content\u002Fposts\u002F2025\u002Fcode-complete-2-notes.md","读薄《代码大全2》",{"type":7,"value":8,"toc":352},"minimark",[9,14,18,22,32,36,47,50,53,59,63,79,81,87,90,98,101,107,111,118,121,164,168,171,174,205,209,212,217,223,227,231,234,240,244,247,251,254,260,266,270,276,280,286,290,293,299,302,306,312,316,322,326,332,335,339,346],[10,11,13],"h2",{"id":12},"第十四章-组织直线型代码","第十四章 组织直线型代码",[10,15,17],{"id":16},"第十五章-使用条件语句","第十五章 使用条件语句",[19,20,21],"h3",{"id":21},"if-else",[23,24,25,29],"ul",{},[26,27,28],"li",{},"正常情况的处理逻辑放 if 后面，而不是 else 后面",[26,30,31],{},"if 子句后面跟随一个有意义的语句",[33,34,35],"p",{},"不推荐的做法：",[37,38,44],"pre",{"className":39,"code":41,"language":42,"meta":43},[40],"language-go","func processFile(filename string) {\n    \u002F\u002F 检查文件是否存在\n    if _, err := os.Stat(filename); err != nil {\n        \u002F\u002F 如果文件不存在或发生错误，这里是空的，没有有意义的语句\n    } else {\n        \u002F\u002F 实际处理文件的逻辑都在 else 块中\n        fmt.Printf(\"开始处理文件: %s\\n\", filename)\n        \u002F\u002F ... 其他文件处理逻辑\n    }\n}\n","go","",[45,46,41],"code",{"__ignoreMap":43},[33,48,49],{},"代码阅读起来不直观，需要先看一个空的代码块，才能找到核心逻辑。",[33,51,52],{},"推荐的改进方式：",[37,54,57],{"className":55,"code":56,"language":42,"meta":43},[40],"func processFile(filename string) {\n    \u002F\u002F 检查文件是否存在，并处理错误情况\n    if _, err := os.Stat(filename); err != nil {\n        \u002F\u002F 在 if 块中直接处理错误，让它成为一个有意义的语句\n        fmt.Printf(\"文件 %s 不存在或访问出错: %v\\n\", filename, err)\n        return\n    }\n\n    \u002F\u002F 文件存在，可以继续处理，这里就是核心逻辑\n    fmt.Printf(\"开始处理文件: %s\\n\", filename)\n    \u002F\u002F ... 其他文件处理逻辑\n}\n",[45,58,56],{"__ignoreMap":43},[19,60,62],{"id":61},"case-语句","case 语句",[23,64,65,76],{},[26,66,67,68,72,73],{},"根据不同 case 的",[69,70,71],"strong",{},"执行频率","，对它们进行排序。如果各个 case 的执行频率没有明显差异时，",[69,74,75],{},"按照字母顺序进行排列",[26,77,78],{},"default 应作为一种“安全网”（防御性编程的手段），捕获所有未被其他 case 覆盖的输入，而不是处理常见情况",[33,80,35],{},[37,82,85],{"className":83,"code":84,"language":42,"meta":43},[40],"package main\n\nimport \"fmt\"\n\nconst (\n\tVIP      = \"VIP\"\n\tREGULAR  = \"REGULAR\"\n\tGUEST    = \"GUEST\"\n)\n\nfunc getDiscount(userType string) float64 {\n\tswitch userType {\n\tcase VIP:\n\t\treturn 0.2 \u002F\u002F VIP 用户 20% 折扣\n\tcase REGULAR:\n\t\treturn 0.1 \u002F\u002F 普通用户 10% 折扣\n\tdefault: \u002F\u002F 这里处理了最常见的 GUEST 情况\n\t\treturn 0.05 \u002F\u002F 游客 5% 折扣\n\t}\n}\n\nfunc main() {\n\tfmt.Printf(\"VIP 用户折扣: %.2f\\n\", getDiscount(VIP))\n\tfmt.Printf(\"普通用户折扣: %.2f\\n\", getDiscount(REGULAR))\n\tfmt.Printf(\"游客折扣: %.2f\\n\", getDiscount(GUEST))\n\tfmt.Printf(\"未知用户折扣: %.2f\\n\", getDiscount(\"UNKNOWN\"))\n}\n",[45,86,84],{"__ignoreMap":43},[33,88,89],{},"在这个例子中，GUEST 是一个明确定义的常量，也是一个常见的用户类型，但它被放在了 default 子句中。",[23,91,92,95],{},[26,93,94],{},"问题 1：读者需要查看 case 列表，发现没有 GUEST，然后才能在 default 中找到它的逻辑。这与我们预期的“从上到下查找”的阅读习惯相悖",[26,96,97],{},"问题 2：如果未来新增了一种用户类型，比如 PREMIUM，而你忘了添加 case，那么 PREMIUM 用户也会意外地被 default 处理，得到 5% 的折扣，这可能会引发意想不到的错误",[33,99,100],{},"推荐的做法：",[37,102,105],{"className":103,"code":104,"language":42,"meta":43},[40],"package main\n\nimport \"fmt\"\n\nconst (\n\tVIP      = \"VIP\"\n\tREGULAR  = \"REGULAR\"\n\tGUEST    = \"GUEST\"\n)\n\nfunc getDiscount(userType string) float64 {\n\tswitch userType {\n\tcase VIP:\n\t\treturn 0.2\n\tcase REGULAR:\n\t\treturn 0.1\n\tcase GUEST: \u002F\u002F 将 GUEST 作为一个明确的 case\n\t\treturn 0.05\n\tdefault: \u002F\u002F default 只处理未知的、意料之外的情况\n\t\tfmt.Printf(\"警告：未知的用户类型 -> %s\\n\", userType)\n\t\treturn 0.0\n\t}\n}\n\nfunc main() {\n\tfmt.Printf(\"VIP 用户折扣: %.2f\\n\", getDiscount(VIP))\n\tfmt.Printf(\"普通用户折扣: %.2f\\n\", getDiscount(REGULAR))\n\tfmt.Printf(\"游客折扣: %.2f\\n\", getDiscount(GUEST))\n\tfmt.Printf(\"未知用户折扣: %.2f\\n\", getDiscount(\"UNKNOWN\"))\n}\n",[45,106,104],{"__ignoreMap":43},[10,108,110],{"id":109},"第二十五章-代码调整策略","第二十五章 代码调整策略",[33,112,113,114,117],{},"优化性能是一个系统性的工程。解决性能问题要",[69,115,116],{},"从上往下","思考，先审视宏观设计，再考虑微观细节",[19,119,120],{"id":120},"性能和代码调整",[23,122,123,126,129,132,135,138,145],{},[26,124,125],{},"硬件是性能的基础",[26,127,128],{},"选择合适的工具和技术栈",[26,130,131],{},"I\u002FO 是性能瓶颈的常见原因",[26,133,134],{},"聚焦于真正影响用户体验的地方，比如，最常见的操作路径",[26,136,137],{},"关注 90% 用户的体验，不需要为了 10% 的用户去投入大量精力和资源",[26,139,140,141,144],{},"性能问题往往不是某个函数或循环的锅，而是",[69,142,143],{},"整体架构和设计","的产物",[26,146,147,148,151,152,155,156,159,160,163],{},"代码调整是战术性的，而不是战略性的。在",[69,149,150],{},"程序设计","没有明显缺陷、",[69,153,154],{},"编译器","已充分利用、",[69,157,158],{},"I\u002FO 瓶颈","已解决、",[69,161,162],{},"硬件","已足够的情况下，才对具体代码细节进行的微调。",[19,165,167],{"id":166},"pareto-法则","Pareto 法则",[33,169,170],{},"找出性能瓶颈，把你的优化努力集中在这些地方。",[19,172,173],{"id":173},"代码调整方法总结",[175,176,177,180,202],"ol",{},[26,178,179],{},"用设计良好的代码来开发软件。性能优化最好的时机是在项目开始之初",[26,181,182,183,186,187,189,190,192,193,195,196,198,199,201],{},"程序已经存在性能问题时，应该采取的实际行动",[184,185],"br",{},"a. 保存程序的可运行版本",[184,188],{},"b. 对系统进行分析测量，找出瓶颈",[184,191],{},"c. 判断性能低下是否源于设计、数据类型或算法",[184,194],{},"d. 对步骤 c 中所确定的瓶颈代码进行调整",[184,197],{},"e. 每次调整后对性能提升进行测试",[184,200],{},"f. 如果调整没有改进性能，就恢复到步骤 a 的代码",[26,203,204],{},"重复步骤 2",[10,206,208],{"id":207},"第二十六章-代码调整技术","第二十六章 代码调整技术",[19,210,211],{"id":211},"逻辑",[213,214,216],"h4",{"id":215},"_1知道答案后就停止判断即短路求值","1.知道答案后就停止判断，即短路求值",[37,218,221],{"className":219,"code":220,"language":42,"meta":43},[40],"func processUser(user *User) bool {\n    \u002F\u002F 假设 user.IsActive() 是一个快速操作，而 user.CanAccessFeature() 是一个耗时的数据库查询\n    if user != nil && user.IsActive() && user.CanAccessFeature() {\n        \u002F\u002F 如果 user 是 nil，后续的条件就不会被评估，避免了空指针 panic\n        return true\n    }\n    return false\n}\n",[45,222,220],{"__ignoreMap":43},[213,224,226],{"id":225},"_2按结果出现的频率来调整判断顺序","2.按结果出现的频率来调整判断顺序",[213,228,230],{"id":229},"_3用查询表替代复杂表达式","3.用查询表替代复杂表达式",[33,232,233],{},"当你有多个 if-else 语句，并且条件是离散值时，用一个 map来查找会更高效和简洁。",[37,235,238],{"className":236,"code":237,"language":42,"meta":43},[40],"\u002F\u002F 伪代码: 用查询表替代复杂表达式\n\u002F\u002F 原始的 if-else if\nfunc getProductPrice(sku string) float64 {\n    if sku == \"SKU-A\" { return 10.0 }\n    if sku == \"SKU-B\" { return 15.0 }\n    if sku == \"SKU-C\" { return 25.0 }\n    return 0\n}\n\n\u002F\u002F 优化后的查询表\nvar productPrices = map[string]float64{\n    \"SKU-A\": 10.0,\n    \"SKU-B\": 15.0,\n    \"SKU-C\": 25.0,\n}\nfunc getProductPriceOptimized(sku string) float64 {\n    if price, ok := productPrices[sku]; ok {\n        return price\n    }\n    return 0\n}\n",[45,239,237],{"__ignoreMap":43},[213,241,243],{"id":242},"_4当数据真正被需要时才去计算或加载它即惰性求值","4.当数据真正被需要时，才去计算或加载它，即惰性求值",[19,245,246],{"id":246},"循环",[213,248,250],{"id":249},"_1将判断外提","1.将判断外提",[33,252,253],{},"如果循环中的某个判断条件，在循环体内不会改变，就把它提到循环外面，避免每次循环都做重复的判断。",[255,256,257],"blockquote",{},[33,258,259],{},"性能优化的目标不是减少代码行数，而是减少 CPU 执行的指令数。",[37,261,264],{"className":262,"code":263,"language":42,"meta":43},[40],"\u002F\u002F 伪代码: 将判断外提\n\u002F\u002F 原始代码\nfunc processArray(arr []int, reverse bool) {\n    for i := 0; i \u003C len(arr); i++ {\n        if reverse {\n            \u002F\u002F ...\n        } else {\n            \u002F\u002F ...\n        }\n    }\n}\n\n\u002F\u002F 优化后的代码\nfunc processArrayOptimized(arr []int, reverse bool) {\n    if reverse {\n        for i := 0; i \u003C len(arr); i++ {\n            \u002F\u002F ...\n        }\n    } else {\n        for i := 0; i \u003C len(arr); i++ {\n            \u002F\u002F ...\n        }\n    }\n}\n",[45,265,263],{"__ignoreMap":43},[213,267,269],{"id":268},"_2将相似循环合并","2.将相似循环合并",[37,271,274],{"className":272,"code":273,"language":42,"meta":43},[40],"\u002F\u002F 伪代码: 将相似循环合并\n\u002F\u002F 原始代码\nfor i := 0; i \u003C len(users); i++ {\n    users[i].LastLogin = time.Now()\n}\nfor i := 0; i \u003C len(users); i++ {\n    users[i].SessionCount++\n}\n\n\u002F\u002F 优化后的代码\nfor i := 0; i \u003C len(users); i++ {\n    users[i].LastLogin = time.Now()\n    users[i].SessionCount++\n}\n",[45,275,273],{"__ignoreMap":43},[213,277,279],{"id":278},"_3尽可能减少在循环中的工作","3.尽可能减少在循环中的工作",[37,281,284],{"className":282,"code":283,"language":42,"meta":43},[40],"\u002F\u002F 伪代码: 减少循环中的工作\n\u002F\u002F 原始代码\nfunc calculateTotalPrice(items []Item) float64 {\n    total := 0.0\n    for i := 0; i \u003C len(items); i++ {\n        taxRate := 0.08 \u002F\u002F 每次循环都重新定义和赋值\n        total += items[i].Price * (1 + taxRate)\n    }\n    return total\n}\n\n\u002F\u002F 优化后的代码\nfunc calculateTotalPriceOptimized(items []Item) float64 {\n    total := 0.0\n    taxRate := 0.08 \u002F\u002F 移到循环外部\n    for i := 0; i \u003C len(items); i++ {\n        total += items[i].Price * (1 + taxRate)\n    }\n    return total\n}\n",[45,285,283],{"__ignoreMap":43},[213,287,289],{"id":288},"_4将最忙的循环放在最内层","4.将最忙的循环放在最内层",[33,291,292],{},"在嵌套循环中，将执行次数最多的循环放在最内层，可以提高缓存的局部性，并减少外层循环的开销。",[37,294,297],{"className":295,"code":296,"language":42,"meta":43},[40],"\u002F\u002F 伪代码: 最忙的循环放在最内层\n\u002F\u002F 原始代码 (假设 cols >> rows)\nfor i := 0; i \u003C rows; i++ {\n    for j := 0; j \u003C cols; j++ {\n        \u002F\u002F ...\n    }\n}\n\n\u002F\u002F 优化后的代码 (最忙的循环放在内层)\nfor j := 0; j \u003C cols; j++ {\n    for i := 0; i \u003C rows; i++ {\n        \u002F\u002F ...\n    }\n}\n",[45,298,296],{"__ignoreMap":43},[19,300,301],{"id":301},"表达式",[213,303,305],{"id":304},"_1削减运算强度","1.削减运算强度",[37,307,310],{"className":308,"code":309,"language":42,"meta":43},[40],"\u002F\u002F 伪代码: 削减运算强度\nx := 10\n\u002F\u002F 原始代码\ny := x * 2\n\n\u002F\u002F 优化后的代码（对于 2 的幂次乘除法）\ny := x \u003C\u003C 1\n",[45,311,309],{"__ignoreMap":43},[213,313,315],{"id":314},"_2编译初始化","2.编译初始化",[37,317,320],{"className":318,"code":319,"language":42,"meta":43},[40],"\u002F\u002F 伪代码: 编译初始化\n\u002F\u002F 原始代码\nfunc calculate(x int) int {\n    someValue := 1024 * 1024 \u002F\u002F 在每次函数调用时都计算\n    return x * someValue\n}\n\n\u002F\u002F 优化后的代码\nconst someValue = 1024 * 1024 \u002F\u002F 编译时确定\nfunc calculateOptimized(x int) int {\n    return x * someValue\n}\n",[45,321,319],{"__ignoreMap":43},[213,323,325],{"id":324},"_3将需要多次使用的计算结果保存下来","3.将需要多次使用的计算结果保存下来",[37,327,330],{"className":328,"code":329,"language":42,"meta":43},[40],"\u002F\u002F 伪代码: 将计算结果保存下来\n\u002F\u002F 原始代码\nfunc processComplex(a, b float64) float64 {\n    return math.Sin(a)*math.Cos(a) + math.Sin(a)*math.Cos(a) \u002F\u002F 重复计算了 math.Sin(a)*math.Cos(a)\n}\n\n\u002F\u002F 优化后的代码\nfunc processComplexOptimized(a, b float64) float64 {\n    val := math.Sin(a) * math.Cos(a) \u002F\u002F 只计算一次\n    return val + val\n}\n",[45,331,329],{"__ignoreMap":43},[19,333,334],{"id":334},"子程序",[213,336,338],{"id":337},"_1将良好的子程序拆解","1.将良好的子程序拆解",[33,340,341,342,345],{},"Go 语言中的函数调用开销非常小，并且编译器通常会进行",[69,343,344],{},"内联","优化。所以，把大函数拆解成多个小函数，反而可能因为内联而提升性能，同时提高可读性。",[37,347,350],{"className":348,"code":349,"language":42,"meta":43},[40],"\u002F\u002F 伪代码: 将良好的子程序拆解\n\u002F\u002F 原始代码: 一个大函数\nfunc processRequest(req *Request) {\n    \u002F\u002F 1. 验证请求...\n    \u002F\u002F 2. 从数据库获取数据...\n    \u002F\u002F 3. 计算结果...\n    \u002F\u002F 4. 格式化响应...\n}\n\n\u002F\u002F 优化后的代码: 拆解成小函数\nfunc processRequestOptimized(req *Request) {\n    if !validateRequest(req) {\n        return\n    }\n    data := getDataFromDB(req)\n    result := calculateResult(data)\n    response := formatResponse(result)\n    sendResponse(response)\n}\n",[45,351,349],{"__ignoreMap":43},{"title":43,"searchDepth":353,"depth":353,"links":354},4,[355,357,362,367],{"id":12,"depth":356,"text":13},2,{"id":16,"depth":356,"text":17,"children":358},[359,361],{"id":21,"depth":360,"text":21},3,{"id":61,"depth":360,"text":62},{"id":109,"depth":356,"text":110,"children":363},[364,365,366],{"id":120,"depth":360,"text":120},{"id":166,"depth":360,"text":167},{"id":173,"depth":360,"text":173},{"id":207,"depth":356,"text":208,"children":368},[369,375,381,386],{"id":211,"depth":360,"text":211,"children":370},[371,372,373,374],{"id":215,"depth":353,"text":216},{"id":225,"depth":353,"text":226},{"id":229,"depth":353,"text":230},{"id":242,"depth":353,"text":243},{"id":246,"depth":360,"text":246,"children":376},[377,378,379,380],{"id":249,"depth":353,"text":250},{"id":268,"depth":353,"text":269},{"id":278,"depth":353,"text":279},{"id":288,"depth":353,"text":289},{"id":301,"depth":360,"text":301,"children":382},[383,384,385],{"id":304,"depth":353,"text":305},{"id":314,"depth":353,"text":315},{"id":324,"depth":353,"text":325},{"id":334,"depth":360,"text":334,"children":387},[388],{"id":337,"depth":353,"text":338},[390],"技术","2025-08-05 19:53:37","点出书本中的重点概念，并用 Go 语言代码进行示例说明。",false,"md","https:\u002F\u002Fimg2.tofaka.com\u002Fautoupload\u002FZ3wg1auvHGH_fxQcOFgj2SfNcKcqEnRmcljopnyJoMs\u002F20260618\u002FqsBG\u002F2560X1440\u002Fandreas-gucklhorn-mawU2PoJWfU-unsplash.jpg\u002Fwebp",{"slots":397},{},true,"\u002F2025\u002Fcode-complete-2-notes",null,{"text":402,"minutes":403,"time":404,"words":405},"12 min read",11.395,683700,2279,1,{"title":5,"description":392},{"loc":399},"posts\u002F2025\u002Fcode-complete-2-notes",[411],"代码大全2","story","myuSOxGF-Ka2SO38sMoNZyEXrRUbQiz0r2juOCcy1KA",[415,420],{"title":416,"path":417,"stem":418,"date":419,"type":412,"children":-1},"搭建 Redis 主从模式","\u002F2024\u002Fredis_master_slave","posts\u002F2024\u002Fredis_master_slave","2024-11-23 19:53:37",{"title":421,"path":422,"stem":423,"date":424,"type":412,"children":-1},"修复 WaitGroup 送出的 Panic 大礼包","\u002F2026\u002Fsolve-waitgroup-panic","posts\u002F2026\u002Fsolve-waitgroup-panic","2026-03-30 15:59:07",1781779103066]