[{"data":1,"prerenderedAt":3263},["ShallowReactive",2],{"post:\u002Fposts\u002Fswdesign\u002Fsw-design-notes-27":3,"posts:ordered":2980},{"id":4,"title":5,"body":6,"category":2962,"cover":2963,"date":2964,"description":2965,"extension":2966,"featured":2967,"meta":2968,"navigation":2151,"path":2969,"seo":2970,"series":2971,"seriesOrder":2972,"stem":2973,"tags":2974,"__hash__":2979},"posts\u002Fposts\u002FswDesign\u002Fsw-design-notes-27.md","软件分析与设计笔记 27：Paper 1 应试：从读案例到交卷的一次完整演算",{"type":7,"value":8,"toc":2899},"minimark",[9,16,33,38,41,48,73,79,83,88,95,173,180,184,187,346,352,360,363,384,388,395,405,479,485,489,496,547,550,556,563,567,573,579,583,604,610,616,620,623,712,716,734,741,745,750,753,757,803,807,810,930,935,948,955,962,966,972,976,983,1050,1056,1060,1090,1094,1101,1104,1175,1181,1188,1192,1201,1205,1208,1226,1230,1236,1239,1273,1277,1280,1354,1358,1372,1376,1384,1387,1411,1415,1421,1425,1428,1448,1454,1458,1464,1468,1473,1479,1500,1504,1511,1517,1521,1539,1543,1550,1554,1563,1567,1606,1610,1617,1792,1796,1802,1806,1835,1839,1847,1854,1858,1861,1899,1903,1909,1913,1961,1967,1971,1975,1981,2014,2024,2028,2031,2281,2292,2296,2302,2332,2337,2343,2346,2422,2426,2432,2440,2443,2447,2451,2532,2536,2543,2566,2569,2601,2604,2677,2680,2895],[10,11,12],"blockquote",{},[13,14,15],"p",{},"这是我在准备 Software Analysis and Design（NUS-ISS，Paper 1 \u002F SA4101）考试时整理的应试笔记。卷面信息全部来自课程放出的 C25 真题与 C25\u002FC26 样卷，图纸规范来自课程讲义与 workshop 的批注。概念部分我按自己的理解写，示例是自己编的。理解有偏差的地方欢迎指出。",[10,17,18],{},[13,19,20,24,25,28,29,32],{},[21,22,23],"strong",{},"配套阅读","：这一篇讲「拿到卷子怎么走完全程」；符号在 draw.io 里具体怎么落笔，见笔记 28。两篇的分工是：这里管",[21,26,27],{},"判断与顺序","，那里管",[21,30,31],{},"落笔与自检","。",[34,35,37],"h2",{"id":36},"_0-开卷考试最反直觉的一点","0 开卷考试最反直觉的一点",[13,39,40],{},"第一次听到「开卷、可以用计算器、可以带纸质资料」，很容易得出一个结论：那就不用背了。",[13,42,43,44,47],{},"真正考过一场模拟之后会发现，开卷改变的不是「要不要记」，而是 ",[21,45,46],{},"「时间花在哪」","：",[49,50,51,59,66],"ul",{},[52,53,54,55,58],"li",{},"3 小时里前 30 分钟是阅读时间，",[21,56,57],{},"不许动笔","，实际答题只有 150 分钟；",[52,60,61,62,65],{},"60 分的卷子里，",[21,63,64],{},"画图题的合计在 38–50 分之间","（用例图、活动图、界面草图、顺序图、类图、重构后重画的类图），画图是没法「现场查着学」的；",[52,67,68,69,72],{},"能查的是术语、符号含义、规范化规则 —— 但这些恰恰是",[21,70,71],{},"翻书最快能找到、却最占时间","的东西。",[13,74,75,76],{},"所以开卷的真正策略是：",[21,77,78],{},"把「查得到的东西」提前压成一页索引，把省下的时间全投到画图和读案例上。",[34,80,82],{"id":81},"_1-卷面结构","1 卷面结构",[84,85,87],"h3",{"id":86},"_11-总体框架","1.1 总体框架",[13,89,90,91,94],{},"三个数字先记住：",[21,92,93],{},"60 分、2 个 Section、150 分钟净答题时间。"," Sections 之间分数对称，各 30 分。",[96,97,98,113],"table",{},[99,100,101],"thead",{},[102,103,104,107,110],"tr",{},[105,106],"th",{},[105,108,109],{},"Section A",[105,111,112],{},"Section B",[114,115,116,127,140,151,162],"tbody",{},[102,117,118,122,125],{},[119,120,121],"td",{},"分",[119,123,124],{},"30",[119,126,124],{},[102,128,129,132,137],{},[119,130,131],{},"组织方式",[119,133,134],{},[21,135,136],{},"一个长案例，串起 4–5 个小问",[119,138,139],{},"2–3 个独立小题",[102,141,142,145,148],{},[119,143,144],{},"案例来源",[119,146,147],{},"一份 1.5 页左右的业务叙述",[119,149,150],{},"一份产品说明 + 用例描述，或一段代码",[102,152,153,156,159],{},[119,154,155],{},"主要考什么",[119,157,158],{},"需求侧产出：用例、活动图、界面、测试",[119,160,161],{},"设计侧产出：顺序图、类图、坏味道与重构",[102,163,164,167,170],{},[119,165,166],{},"对应笔记",[119,168,169],{},"05、08、10、12、14、15",[119,171,172],{},"21、22、24、25",[13,174,175,176,179],{},"Section A 的案例读起来很长，但",[21,177,178],{},"每一个小问只对应案例里的一两句话","。这一点在 §2 会用一张图说清楚。",[84,181,183],{"id":182},"_12-题型与分值的两年对照","1.2 题型与分值的两年对照",[13,185,186],{},"把 C25 真题和 C25\u002FC26 样卷并排放，重复出现的题型就一目了然了：",[96,188,189,205],{},[99,190,191],{},[102,192,193,196,199,202],{},[105,194,195],{},"题型",[105,197,198],{},"C25 真题",[105,200,201],{},"C25\u002FC26 样卷",[105,203,204],{},"分值",[114,206,207,221,235,252,269,281,295,309,322,334],{},[102,208,209,212,215,218],{},[119,210,211],{},"数据驱动分析表（Descriptive \u002F Diagnostic \u002F Predictive \u002F Prescriptive）",[119,213,214],{},"1a（6）",[119,216,217],{},"—",[119,219,220],{},"6",[102,222,223,226,229,232],{},[119,224,225],{},"用例图",[119,227,228],{},"1b（8）",[119,230,231],{},"1a（10）",[119,233,234],{},"8–10",[102,236,237,244,247,249],{},[119,238,239,240,243],{},"活动图（",[21,241,242],{},"要求含实体","）",[119,245,246],{},"1c（8）",[119,248,228],{},[119,250,251],{},"8",[102,253,254,260,263,266],{},[119,255,256,257,243],{},"界面 \u002F 仪表板草图（",[21,258,259],{},"要求用隐喻",[119,261,262],{},"1d（4）",[119,264,265],{},"1c（4）",[119,267,268],{},"4",[102,270,271,274,277,279],{},[119,272,273],{},"测试用例 + 测试数据",[119,275,276],{},"1e（4）",[119,278,217],{},[119,280,268],{},[102,282,283,286,289,292],{},[119,284,285],{},"顺序图（analysis model）",[119,287,288],{},"2（12）",[119,290,291],{},"2a（10）",[119,293,294],{},"10–12",[102,296,297,300,303,306],{},[119,298,299],{},"类图（只画类与关系）",[119,301,302],{},"4b（6）",[119,304,305],{},"2b（10）",[119,307,308],{},"6–10",[102,310,311,314,317,320],{},[119,312,313],{},"坏味道识别 + 重构方案",[119,315,316],{},"4a（6）",[119,318,319],{},"3（10，含改设计）",[119,321,308],{},[102,323,324,327,330,332],{},[119,325,326],{},"用多态满足「可插拔」的非功能需求",[119,328,329],{},"3（6）",[119,331,217],{},[119,333,220],{},[102,335,336,339,341,344],{},[119,337,338],{},"精炼用例图（include \u002F extend \u002F 泛化）",[119,340,217],{},[119,342,343],{},"1d（8）",[119,345,251],{},[13,347,348,349,47],{},"两张卷子的总分都是 60，但小问的切法不一样 —— ",[21,350,351],{},"这就是为什么不能只按样卷的题型准备",[49,353,354,357],{},[52,355,356],{},"C25 真题 Section A 五问（6 + 8 + 8 + 4 + 4），Section B 三问（12 + 6 + 12）；",[52,358,359],{},"样卷 Section A 四问（10 + 8 + 4 + 8），Section B 三问（10 + 10 + 10）。",[13,361,362],{},"三个判断：",[364,365,366,372,378],"ol",{},[52,367,368,371],{},[21,369,370],{},"用例图、活动图、顺序图、类图这四项是硬通货","，任何一张卷子上都会出现，合计 32–40 分；",[52,373,374,377],{},[21,375,376],{},"样卷会换题","。C25 真题把样卷的「精炼用例图」换成了「数据驱动分析表」；",[52,379,380,383],{},[21,381,382],{},"分数最少的题（4 分）反而最容易被写飞"," —— 界面草图只有 4 分，但它要求你同时证明「信息选对了」和「隐喻用对了」两件事。",[84,385,387],{"id":386},"_13-150-分钟怎么切","1.3 150 分钟怎么切",[13,389,390],{},[391,392],"img",{"alt":393,"src":394},"Paper 1 的三小时考场时间轴：0 到 30 分钟阅读时间用于读案例并标出角色与痛点，30 到 100 分钟做 Section A 的用例图、活动图与界面草图，100 到 170 分钟做 Section B 的顺序图、类图与重构题，最后 10 分钟回查箭头方向、系统边界与假设声明","\u002Fimages\u002Fsw-design-notes-27-exam-map.svg",[13,396,397,398,401,402,32],{},"这张图是我给自己定的分配，原则有两条：",[21,399,400],{},"画图题优先，能查书的题垫后","；",[21,403,404],{},"每张图留出 5 分钟检查符号",[96,406,407,420],{},[99,408,409],{},[102,410,411,414,417],{},[105,412,413],{},"时段",[105,415,416],{},"干什么",[105,418,419],{},"为什么这样排",[114,421,422,437,448,459],{},[102,423,424,427,430],{},[119,425,426],{},"0–30 min（阅读）",[119,428,429],{},"通读两份卷子 → 在案例上标出所有角色、痛点、外部系统",[119,431,432,433,436],{},"不许动笔，但可以在",[21,434,435],{},"卷子上","做标记；这半小时决定了后面所有答案的完整度",[102,438,439,442,445],{},[119,440,441],{},"30–100 min",[119,443,444],{},"Section A 的画图题（用例图 → 活动图 → 界面）",[119,446,447],{},"这些是「想清楚才能画」的题，越到后面脑子越乱",[102,449,450,453,456],{},[119,451,452],{},"100–170 min",[119,454,455],{},"Section B（顺序图 → 类图 → 重构）",[119,457,458],{},"顺序图要照着 basic flow 一步步推，需要连续时间",[102,460,461,464,476],{},[119,462,463],{},"170–180 min",[119,465,466,467,471,472,475],{},"回查：箭头方向、系统边界、",[468,469,470],"code",{},"«include»","\u002F",[468,473,474],{},"«extend»"," 有没有画反",[119,477,478],{},"这 10 分钟通常能捞回 2–4 分，是全卷性价比最高的一段",[13,480,481,482],{},"一个反例：先做「坏味道 + 重构」这种文字题，因为它看起来最容易动笔。结果是写了 20 分钟的文字，回过头发现顺序图只剩 15 分钟 —— ",[21,483,484],{},"文字题写多了不会多给分，图没画完一定扣分。",[34,486,488],{"id":487},"_2-演算用的案例","2 演算用的案例",[13,490,491,492,495],{},"从这一节开始，我用",[21,493,494],{},"一份自己编的案例","把整份卷子走完。它刻意做成了真题的形态：一个长叙述，四个小问挂上去。",[10,497,498,503,506,516,522,528,534,541],{},[13,499,500],{},[21,501,502],{},"派单宝 —— 家电维修上门服务平台",[13,504,505],{},"某家电连锁有 6 个片区、约 40 名维修工程师。现在的报修流程全靠电话：客户打客服热线 → 客服在 Excel 里记下地址和故障 → 打电话找有空的工程师 → 再回电话告诉客户几点上门。",[13,507,508,511,512,515],{},[21,509,510],{},"客服小林","每天要接 80 多通电话。她最头疼的是：",[21,513,514],{},"不知道哪个工程师现在有空","，只能一个个打过去问；客户问「能不能明天上午」，她也答不上来。她还在纸上记「谁欠了哪个配件」，经常漏。",[13,517,518,521],{},[21,519,520],{},"工程师老陈","一天跑 4–5 单。他出发前不知道客户家的机器型号和故障描述，到了现场才发现要用的配件没带，只能再跑一趟。他也看不到自己这周的排期，客服临时塞单会打乱他的路线。",[13,523,524,527],{},[21,525,526],{},"仓管小周","管着片区仓库。工程师来领料时她才知道要出什么，经常出现「工程师到了、配件没了」的情况。她也说不清哪些配件快用完了。",[13,529,530,533],{},[21,531,532],{},"片区经理王姐","要向总部报月度数据： completion rate、平均上门时长、客户满意度。她现在靠月底手工汇总 Excel，往往要两三天，且数字对不上。",[13,535,536,537,540],{},"还有一方：",[21,538,539],{},"配件供应商","有开放的库存查询接口，能实时返回某个配件的可售数量。",[13,542,543,544,32],{},"王姐希望系统能自动派单、让客户能看到工程师到哪儿了，并且",[21,545,546],{},"提前预判哪些配件下周会短缺",[13,548,549],{},"先把这份案例读成一张图。下面是它拆出来的四个层次 —— 这正是后面四道小问各自要用的材料：",[13,551,552],{},[391,553],{"alt":554,"src":555},"案例拆解图：上方是案例原文里的三栏信息（五类角色、三个痛点、一个外部系统），下方是它们各自对应到哪一道小问的输出物——角色与目标对应用例图，工程师的故障与配件问题对应活动图，客服的排期痛点对应界面草图，经理的缺料预判对应数据驱动分析表","\u002Fimages\u002Fsw-design-notes-27-case-breakdown.svg",[13,557,558,559,562],{},"这张图的意思是：",[21,560,561],{},"不要逐句精读，要按「谁、什么事、想要什么」三栏去扫","。扫完你就会发现，案例里几乎每一句话都能落到某一道题上；落不上的句子，多半是背景交代。",[34,564,566],{"id":565},"_3-第-1a-题数据驱动分析表6-分","3 第 1a 题：数据驱动分析表（6 分）",[13,568,569,572],{},[21,570,571],{},"题目要求","：针对案例里「不知道哪些配件下周会短缺」这个痛点，用 Descriptive–Diagnostic–Predictive–Prescriptive 四层给出分析方案。",[13,574,575,576,32],{},"题目考的其实不是分析技术，而是",[21,577,578],{},"能不能把一句抱怨翻成「要什么数据、为什么」",[84,580,582],{"id":581},"_31-答题步骤","3.1 答题步骤",[364,584,585,591,598],{},[52,586,587,590],{},[21,588,589],{},"先把痛点原句抄下来","（就一句），写在表格上方当锚点 —— 「说不清哪些配件快用完，只能等工程师到了才发现没货」；",[52,592,593,594,401],{},"逐层回答三个固定问题：",[595,596,597],"em",{},"需要什么数据？用什么分析手段或工具？对业务有什么用？",[52,599,600,603],{},[21,601,602],{},"每一格都要落到这个案例的业务名词上","。「预测」不能写成「用 AI 预测」，要写成「用近 12 个月的配件出库记录，预测下周各片区的配件需求，供仓管提前备货」。",[13,605,606],{},[391,607],{"alt":608,"src":609},"四层分析递进图：从下往上依次是描述性、诊断性、预测性、处方性。每层标出它回答的问题、需要的数据、分析手段以及对业务的作用；右侧用一条上升的阶梯表示难度与价值递增。图上用红字特别标出处方性必须落到「系统替人做的建议或提醒」，否则与前一层没有区别","\u002Fimages\u002Fsw-design-notes-27-analytics-four-layers.svg",[13,611,612,613],{},"四层的分工，一句话版：",[21,614,615],{},"Descriptive 看清发生了什么，Diagnostic 找出为什么，Predictive 猜下一步，Prescriptive 直接给出该做什么动作。",[84,617,619],{"id":618},"_32-成品答案","3.2 成品答案",[13,621,622],{},"把四层落到本例的具体内容上，就是这张表：",[96,624,625,641],{},[99,626,627],{},[102,628,629,632,635,638],{},[105,630,631],{},"类型",[105,633,634],{},"需要的数据",[105,636,637],{},"分析手段",[105,639,640],{},"业务目标",[114,642,643,661,678,695],{},[102,644,645,652,655,658],{},[119,646,647,648,651],{},"Descriptive",[649,650],"br",{},"发生了什么",[119,653,654],{},"近 12 个月每张工单的配件消耗记录、每次领料被拒（缺货）的记录",[119,656,657],{},"按配件 × 片区汇总出库量；统计缺货发生次数",[119,659,660],{},"看清哪些配件经常缺、缺在哪个片区",[102,662,663,669,672,675],{},[119,664,665,666,668],{},"Diagnostic",[649,667],{},"为什么发生",[119,670,671],{},"缺货记录 + 当时的库存快照 + 工单故障类型",[119,673,674],{},"交叉分析：缺货是否集中在某几类故障、是否与工程师领料习惯有关",[119,676,677],{},"找到根因，避免下次同样缺货",[102,679,680,686,689,692],{},[119,681,682,683,685],{},"Predictive",[649,684],{},"可能发生什么",[119,687,688],{},"上述历史消耗 + 季节性因素（如夏季空调维修高峰）+ 供应商交期",[119,690,691],{},"按配件 × 片区的时序预测，给出未来 2 周的预计需求量",[119,693,694],{},"提前知道下周哪些配件会缺",[102,696,697,703,706,709],{},[119,698,699,700,702],{},"Prescriptive",[649,701],{},"该做什么",[119,704,705],{},"预测结果 + 当前库存 + 供应商可售库存",[119,707,708],{},"自动比对，低于安全库存就生成补货建议并推送仓管",[119,710,711],{},"让仓管在缺货前就下单，而不是等到没货",[84,713,715],{"id":714},"_33-两个最容易丢分的地方","3.3 两个最容易丢分的地方",[49,717,718,728],{},[52,719,720,723,724,727],{},[21,721,722],{},"四层写成同一件事的四种说法","。比如 Predictive 和 Prescriptive 都写「预测风险」——区别在",[21,725,726],{},"有没有落到动作","。Prescriptive 必须产生一个「系统替人做的建议或提醒」，本例就是「自动生成补货建议并推送」；",[52,729,730,733],{},[21,731,732],{},"只写数据不写用途","。表格里「业务目标」那一列空着，等于只答了一半。",[13,735,736,737,740],{},"还有一个隐含加分点：本例有一个",[21,738,739],{},"外部系统","（供应商库存接口）。在 Prescriptive 那一行提到「比对供应商可售库存」，说明你读到了案例里的这一句，而不只是套模板。",[34,742,744],{"id":743},"_4-第-1b-题用例图810-分","4 第 1b 题：用例图（8–10 分）",[13,746,747,749],{},[21,748,571],{},"：画出支持全部业务角色的完整用例图。",[13,751,752],{},"这是全卷分值最高的单张图，也是「完整」两个字最贵的一张。",[84,754,756],{"id":755},"_41-答题步骤","4.1 答题步骤",[364,758,759,769,775,785,791,797],{},[52,760,761,764,765,768],{},[21,762,763],{},"先列角色清单。"," 从案例里把每一个「有自己目标的人或外部系统」抄出来。判断依据是",[21,766,767],{},"目标而不是身份","（笔记 08）；",[52,770,771,774],{},[21,772,773],{},"判断哪些是外部系统。"," 本例的「配件供应商库存接口」是一个 actor —— 系统要去查它；",[52,776,777,780,781,784],{},[21,778,779],{},"给每个角色配 2–4 个用例","，用例名用",[21,782,783],{},"动词 + 名词","，不用「管理」这种糊词；",[52,786,787,790],{},[21,788,789],{},"画系统边界框","，把所有用例包进去，actor 一律在外；",[52,792,793,796],{},[21,794,795],{},"连关联线","，注意箭头方向；",[52,798,799,802],{},[21,800,801],{},"补一句假设。"," 题目要求「如有不清楚处写明假设」，写两行就能拿到稳定性分。",[84,804,806],{"id":805},"_42-本例的角色清单","4.2 本例的角色清单",[13,808,809],{},"先做一张表，这张表就是图的骨架：",[96,811,812,825],{},[99,813,814],{},[102,815,816,819,822],{},[105,817,818],{},"角色",[105,820,821],{},"他要达成什么",[105,823,824],{},"对应的用例",[114,826,827,847,866,885,901,917],{},[102,828,829,832,835],{},[119,830,831],{},"客户 Customer",[119,833,834],{},"报修、知道工程师几点到",[119,836,837,840,841,840,844],{},[468,838,839],{},"Report Fault","、",[468,842,843],{},"Track Engineer Arrival",[468,845,846],{},"Rate Service",[102,848,849,852,855],{},[119,850,851],{},"客服 Clerk",[119,853,854],{},"建单、派单、改约",[119,856,857,840,860,840,863],{},[468,858,859],{},"Create Work Order",[468,861,862],{},"Assign Engineer",[468,864,865],{},"Reschedule Visit",[102,867,868,871,874],{},[119,869,870],{},"工程师 Engineer",[119,872,873],{},"接单、现场回填、领料",[119,875,876,840,879,840,882],{},[468,877,878],{},"Accept Assignment",[468,880,881],{},"Update Work Order",[468,883,884],{},"Request Parts",[102,886,887,890,893],{},[119,888,889],{},"仓管 Storekeeper",[119,891,892],{},"出库、补货",[119,894,895,840,898],{},[468,896,897],{},"Issue Parts",[468,899,900],{},"Raise Replenishment",[102,902,903,906,909],{},[119,904,905],{},"片区经理 Manager",[119,907,908],{},"看数据",[119,910,911,840,914],{},[468,912,913],{},"View Dispatch Dashboard",[468,915,916],{},"View Parts Forecast",[102,918,919,922,925],{},[119,920,921],{},"供应商系统 Supplier System",[119,923,924],{},"被查询库存",[119,926,927],{},[468,928,929],{},"Query Supplier Stock",[13,931,932],{},[21,933,934],{},"这张表里有一处需要专门判断：客服与片区经理能不能共用同一个用例？",[13,936,937,938,943,944,947],{},"他们的「看待派单」「看排期」「改约」完全一样（点进去看到同一个界面、走同一套步骤），只是经理多一个看报表的入口。按讲义的标准 —— ",[21,939,940],{},[468,941,942],{},"both will trigger and execute the use case in the same way"," —— ",[21,945,946],{},"可以共用一个用例，画两条线","（或者做参与者泛化）。",[13,949,950,951,954],{},"反过来，「客服派单」与「工程师接单」",[21,952,953],{},"不能","共用：一个发起、一个响应，动作方向都不同。虽然名字都跟「派单」有关，但必须画成两个用例。",[13,956,957,958,961],{},"判据一句话：",[21,959,960],{},"这两个角色点进去之后，看到的是同一个界面、走的是同一套步骤吗","？是 → 一个用例连两根线；不是 → 拆成两个，哪怕名字听起来像。",[84,963,965],{"id":964},"_43-成品图","4.3 成品图",[13,967,968],{},[391,969],{"alt":970,"src":971},"用例图成品：虚线矩形系统边界内十五个用例，按角色分成五组由上到下排列。边界外左侧自上而下是客户、客服、工程师、仓管、片区经理五个参与者，每人只与同高度的用例组相连，所以连线短且不交叉。右下是橙色的「每日排期推送」用例，用一条橙色箭头指向工程师，表示由系统主动触发；再往右下、边界之外是配件供应商库存系统","\u002Fimages\u002Fsw-design-notes-27-usecase-answer.svg",[84,973,975],{"id":974},"_44-如果题目还要求客户旅程图","4.4 如果题目还要求客户旅程图",[13,977,978,979,982],{},"样卷有一个特殊要求：",[21,980,981],{},"「用同一张客户旅程图，标出每个阶段的期望由哪些用例回应」","。这不是画在图上的东西，而是一张两列表：",[96,984,985,998],{},[99,986,987],{},[102,988,989,992,995],{},[105,990,991],{},"旅程阶段",[105,993,994],{},"该阶段的期望",[105,996,997],{},"回应的用例",[114,999,1000,1012,1024,1038],{},[102,1001,1002,1005,1008],{},[119,1003,1004],{},"报修前",[119,1006,1007],{},"想快点找到人",[119,1009,1010],{},[468,1011,839],{},[102,1013,1014,1017,1020],{},[119,1015,1016],{},"等待上门",[119,1018,1019],{},"想知道工程师几点到",[119,1021,1022],{},[468,1023,843],{},[102,1025,1026,1029,1032],{},[119,1027,1028],{},"上门中",[119,1030,1031],{},"希望一次修好",[119,1033,1034,840,1036],{},[468,1035,881],{},[468,1037,884],{},[102,1039,1040,1043,1046],{},[119,1041,1042],{},"上门后",[119,1044,1045],{},"想评价、想查历史",[119,1047,1048],{},[468,1049,846],{},[13,1051,1052,1055],{},[21,1053,1054],{},"这张表比图更容易拿分","，因为它是唯一能证明「你的用例不是凭空想的」的东西。看到题目里出现 journey map，就一定要配这张表。",[84,1057,1059],{"id":1058},"_45-三个扣分点","4.5 三个扣分点",[49,1061,1062,1071,1084],{},[52,1063,1064,1067,1068,1070],{},[21,1065,1066],{},"漏角色。"," 最容易漏的是「外部系统」（供应商接口）和「被通知的人」（客户在 ",[468,1069,843],{}," 里是被系统推送的）；",[52,1072,1073,32,1076,1079,1080,1083],{},[21,1074,1075],{},"用例名写成名词",[468,1077,1078],{},"Appointment"," 不是用例，",[468,1081,1082],{},"Book Appointment"," 才是；",[52,1085,1086,1089],{},[21,1087,1088],{},"满图箭头。"," 只有系统主动推送时才画箭头向 actor，其余画实线。",[84,1091,1093],{"id":1092},"_46-如果题目接着要求精炼","4.6 如果题目接着要求「精炼」",[13,1095,1096,1097,1100],{},"样卷的 1d 是独立一问：「Refine … to show include, extend and generalization of use cases ",[21,1098,1099],{},"and actors","」。注意最后两个词 —— 很多人只做了用例侧，参与者泛化漏掉就丢 2 分。",[13,1102,1103],{},"用例图画完之后，精炼只需要在三处找东西：",[96,1105,1106,1119],{},[99,1107,1108],{},[102,1109,1110,1113,1116],{},[105,1111,1112],{},"找什么",[105,1114,1115],{},"判断",[105,1117,1118],{},"画法",[114,1120,1121,1140,1159],{},[102,1122,1123,1128,1131],{},[119,1124,1125],{},[21,1126,1127],{},"公共步骤",[119,1129,1130],{},"这一步每次都必须做吗？",[119,1132,1133,1134,1136,1137],{},"抽成被包含用例，",[468,1135,470],{}," 箭头",[21,1138,1139],{},"由基用例指向它",[102,1141,1142,1147,1150],{},[119,1143,1144],{},[21,1145,1146],{},"条件行为",[119,1148,1149],{},"只在某些情况下才发生吗？",[119,1151,1152,1153,1136,1155,1158],{},"做成扩展用例，",[468,1154,474],{},[21,1156,1157],{},"由它指向基用例","，条件写箭头旁",[102,1160,1161,1166,1169],{},[119,1162,1163],{},[21,1164,1165],{},"共同角色",[119,1167,1168],{},"两个角色共用一整套用例、只是权限不同吗？",[119,1170,1171,1172],{},"泛化到父角色，空心三角",[21,1173,1174],{},"由子指向父",[13,1176,1177],{},[391,1178],{"alt":1179,"src":1180},"精炼用例图的前后对照：左侧是精炼前，三个用例各画各的，并列出三个可以精炼的地方——校验工单状态在三个用例里都有（用 include）、撤回申请只在提交后五分钟内（用 extend）、客服与片区经理共用一整套用例（用泛化）。右侧是精炼后，三条 include 从基用例指向被包含的校验工单状态，一条 extend 从撤回申请指向申请配件，客服与片区经理泛化到一个抽象的门店员工父角色","\u002Fimages\u002Fsw-design-notes-27-refine-usecase.svg",[13,1182,1183,1184,1187],{},"三条判据里最实用的是第一列的提问法：",[21,1185,1186],{},"「这一步能不做吗？」"," 不能不做 → include；可能不做 → extend。这一句能解决九成的判断。",[34,1189,1191],{"id":1190},"_5-第-1c-题活动图8-分","5 第 1c 题：活动图（8 分）",[13,1193,1194,1196,1197,1200],{},[21,1195,571],{},"：任选两个业务关键用例画活动图，",[21,1198,1199],{},"必须包含实体","，排除登录与生成报表。",[84,1202,1204],{"id":1203},"_51-选哪两个","5.1 选哪两个",[13,1206,1207],{},"挑标准：步骤多、有判断、跨角色。本例最典型的是：",[49,1209,1210,1218],{},[52,1211,1212,1217],{},[21,1213,1214,1216],{},[468,1215,862],{},"（派单）"," —— 有「工程师是否可用」的判断，跨客服与工程师两条泳道；",[52,1219,1220,1225],{},[21,1221,1222,1224],{},[468,1223,884],{},"（申请配件）"," —— 有「库存是否充足」的判断，跨工程师、系统、仓管三条泳道，且要读写多个实体。",[84,1227,1229],{"id":1228},"_52-成品申请配件的活动图","5.2 成品：申请配件的活动图",[13,1231,1232],{},[391,1233],{"alt":1234,"src":1235},"申请配件的活动图：三条竖直泳道分别是工程师、系统、仓管。流程从实心圆开始，经提交备料申请、校验工单状态、查询供应商库存，进入「库存是否充足」的判断菱形；有库存时进入仓管泳道生成出库单，无库存时由系统把工单置为待件挂起，两条分支汇到结束状态。图右侧竖排四个业务实体（工单、库存项、出库单、配件消耗），并用两条橙色箭头示范读与写的相反方向——读是实体指向动作，写是动作指向实体；其余实体的读写已用括号标在动作框里","\u002Fimages\u002Fsw-design-notes-27-activity-answer.svg",[13,1237,1238],{},"这张图有三处是得分点，值得单独说：",[364,1240,1241,1247,1259],{},[52,1242,1243,1246],{},[21,1244,1245],{},"泳道"," —— 一眼看出「这一步谁做」。本例里流程在三条泳道之间来回，正好暴露了协调成本；",[52,1248,1249,943,1252,1255,1256,401],{},[21,1250,1251],{},"判断菱形带方括号条件",[468,1253,1254],{},"[有库存]"," \u002F ",[468,1257,1258],{},"[无库存]",[52,1260,1261,1264,1265,1268,1269,1272],{},[21,1262,1263],{},"实体的读写方向"," —— 查询库存是",[21,1266,1267],{},"读","（实体 → 动作），回填工单是",[21,1270,1271],{},"写","（动作 → 实体）。这一笔写反是这类题最常见的扣分点。",[84,1274,1276],{"id":1275},"_53-配套的活动流程表","5.3 配套的活动流程表",[13,1278,1279],{},"图上只能表达结构，精确的东西要靠表。这一张表是加分项：",[96,1281,1282,1298],{},[99,1283,1284],{},[102,1285,1286,1289,1292,1295],{},[105,1287,1288],{},"活动",[105,1290,1291],{},"执行者",[105,1293,1294],{},"条件",[105,1296,1297],{},"说明",[114,1299,1300,1314,1327,1341],{},[102,1301,1302,1305,1308,1311],{},[119,1303,1304],{},"提交备料申请",[119,1306,1307],{},"工程师",[119,1309,1310],{},"工单状态 = 进行中",[119,1312,1313],{},"填配件编号与数量",[102,1315,1316,1319,1322,1324],{},[119,1317,1318],{},"查询供应商库存",[119,1320,1321],{},"系统",[119,1323,217],{},[119,1325,1326],{},"调供应商库存接口",[102,1328,1329,1332,1335,1338],{},[119,1330,1331],{},"生成出库单",[119,1333,1334],{},"仓管",[119,1336,1337],{},"库存 ≥ 申请量",[119,1339,1340],{},"扣减库存",[102,1342,1343,1346,1348,1351],{},[119,1344,1345],{},"工单置为待件挂起",[119,1347,1321],{},[119,1349,1350],{},"库存 \u003C 申请量",[119,1352,1353],{},"同时通知客户改约",[84,1355,1357],{"id":1356},"_54-两个扣分点","5.4 两个扣分点",[49,1359,1360,1366],{},[52,1361,1362,1365],{},[21,1363,1364],{},"画了确认框和错误提示。"," 讲义明确说这一阶段忽略异常，只保留业务决策；",[52,1367,1368,1371],{},[21,1369,1370],{},"实体箭头全画成一个方向。"," 读和写是相反的，见上表。",[34,1373,1375],{"id":1374},"_6-第-1d-题界面草图-仪表板4-分","6 第 1d 题：界面草图 \u002F 仪表板（4 分）",[13,1377,1378,1380,1381,32],{},[21,1379,571],{},"：画出让客服、工程师、片区经理都能排期与管理工单的仪表板，并",[21,1382,1383],{},"演示如何用隐喻更好地呈现信息",[13,1385,1386],{},"只有 4 分，但判分看三件事：",[364,1388,1389,1395,1405],{},[52,1390,1391,1394],{},[21,1392,1393],{},"信息选对了吗"," —— 题目里提到三个角色，那屏幕上必须能分别回答他们的关切；",[52,1396,1397,1400,1401,1404],{},[21,1398,1399],{},"隐喻在哪"," —— 并",[21,1402,1403],{},"明确标注","出来；",[52,1406,1407,1410],{},[21,1408,1409],{},"是否可读"," —— 区块有标题，有主次。",[84,1412,1414],{"id":1413},"_61-成品图","6.1 成品图",[13,1416,1417],{},[391,1418],{"alt":1419,"src":1420},"派单仪表板草图：屏幕分三块。左上是周历视图，横向周一至周五、纵向上午下午，格子里填工程师姓名与工单号，空格标「空闲」，满档标「请改约」，右上角标注隐喻为日历等于排期。右上是待办请求列表，每条前有红黄绿灯标示紧急度，右上角标注隐喻为红绿灯等于紧急度。下方是四列看板：待派单、进行中、待件挂起、已完成，右上角标注隐喻为看板列等于状态流转。底部一行是本周完成率、平均上门时长、缺料单占比、满意度四个数字","\u002Fimages\u002Fsw-design-notes-27-dashboard-answer.svg",[84,1422,1424],{"id":1423},"_62-三行说明必须写","6.2 三行说明（必须写）",[13,1426,1427],{},"这三行是拿分的关键，写在图下面：",[364,1429,1430,1436,1442],{},[52,1431,1432,1435],{},[21,1433,1434],{},"周历隐喻排期"," —— 客服一眼看出哪个工程师哪个时段空着，不用再一个个打电话问；",[52,1437,1438,1441],{},[21,1439,1440],{},"红绿灯隐喻紧急度"," —— 片区经理扫一眼就知道哪几单快超时了；",[52,1443,1444,1447],{},[21,1445,1446],{},"看板列隐喻状态"," —— 「待件挂起」这一列直接对应用例里的例外流程，让仓管知道该去催货了。",[13,1449,1450,1453],{},[21,1451,1452],{},"三行说明的每一行都要回到题目","。如果题目说「用隐喻更好地呈现信息」，那说明里必须出现「隐喻」两个字，否则阅卷人可能认为你没做到。",[84,1455,1457],{"id":1456},"_63-一个提醒","6.3 一个提醒",[13,1459,1460,1463],{},[21,1461,1462],{},"4 分的题不要画 15 分钟","。十分钟以内画完 + 三行说明，就足够拿分。不要在涂色和图标上花时间。",[34,1465,1467],{"id":1466},"_7-第-1e-题测试用例-测试数据4-分","7 第 1e 题：测试用例 + 测试数据（4 分）",[13,1469,1470,1472],{},[21,1471,571],{},"：给一张界面截图，要求「设计 2 个测试用例和 1 组测试数据」。",[13,1474,1475,1476,47],{},"这道题的答案不是文字，而是一张固定的表。",[21,1477,1478],{},"表头就五个字段，少一个都算不完整",[96,1480,1481],{},[99,1482,1483],{},[102,1484,1485,1488,1491,1494,1497],{},[105,1486,1487],{},"Test ID",[105,1489,1490],{},"测试场景",[105,1492,1493],{},"前置条件",[105,1495,1496],{},"测试数据",[105,1498,1499],{},"预期结果",[84,1501,1503],{"id":1502},"_71-本例的成品答案","7.1 本例的成品答案",[13,1505,1506,1507,1510],{},"被测界面是「申请配件」表单，其中",[21,1508,1509],{},"数量字段限定 1–20","。这个范围就是出题的抓手 —— 等价类天然分成三段：",[13,1512,1513],{},[391,1514],{"alt":1515,"src":1516},"测试用例与测试数据表的填法示例：上方是被测界面的字段清单，其中数量字段限定 1 到 20；中间是三条测试用例，TC-01 是范围内取中间值的有效用例，TC-02 是数量为 0 的下边界外用例，TC-03 是数量为 21 的上边界外用例，三条的数据和预期结果都写成了具体值；下方左块解释为什么这样挑数据（一个有效类加两个无效类），右块列出两个最常见的错误——两条用例都是正常路径、测试数据写成 invalid data","\u002Fimages\u002Fsw-design-notes-27-testcase-table.svg",[84,1518,1520],{"id":1519},"_72-两条铁律","7.2 两条铁律",[49,1522,1523,1533],{},[52,1524,1525,1528,1529,1532],{},[21,1526,1527],{},"一条有效、两条无效","，不要全是正常路径。无效那条优先挑",[21,1530,1531],{},"边界值","（下边界外 0、上边界外 21），命中率最高（笔记 14）；",[52,1534,1535,1538],{},[21,1536,1537],{},"「测试数据」必须是真能填进输入框的值","，不能写「invalid data」。这一列空着或写虚的，这题基本拿不到分。",[84,1540,1542],{"id":1541},"_73-一个易误解的措辞","7.3 一个易误解的措辞",[13,1544,1545,1546,1549],{},"题目说「1 组测试数据」，指的",[21,1547,1548],{},"不是「只写一个数字」","，而是「支撑这些用例所需的整组输入」—— 配件编号 + 数量，一起给全。把它理解成单个值，就会漏掉必填字段。",[34,1551,1553],{"id":1552},"_8-第-2-题顺序图1012-分","8 第 2 题：顺序图（10–12 分）",[13,1555,1556,1558,1559,1562],{},[21,1557,571],{},"：给出某用例的 ",[468,1560,1561],{},"\u003CBasic flow of events>","，要求画 analysis model 的顺序图。",[84,1564,1566],{"id":1565},"_81-本例的-basic-flow","8.1 本例的 basic flow",[10,1568,1569,1574],{},[13,1570,1571],{},[21,1572,1573],{},"Use Case: Request Parts（申请配件）",[364,1575,1576,1579,1582,1585,1588,1591,1594,1597,1600,1603],{},[52,1577,1578],{},"工程师在申请界面选择工单，输入配件编号与数量，提交申请。",[52,1580,1581],{},"系统校验工单状态是否为「进行中」。",[52,1583,1584],{},"系统根据配件编号查询当前库存。",[52,1586,1587],{},"系统调用供应商库存接口，获取该配件的可售数量。",[52,1589,1590],{},"系统比对本地库存与供应商可售量，判断能否满足申请。",[52,1592,1593],{},"若可满足，系统生成出库单，并把库存数量扣减。",[52,1595,1596],{},"系统把申请记录写入工单。",[52,1598,1599],{},"系统通知仓管有新出库单待处理。",[52,1601,1602],{},"系统向工程师显示「申请成功，请到仓库领取」。",[52,1604,1605],{},"Use case terminates.",[84,1607,1609],{"id":1608},"_82-逐行翻译成消息","8.2 逐行翻译成消息",[13,1611,1612,1613,1616],{},"这是全卷",[21,1614,1615],{},"最机械、也最容易拿满分","的题，因为步骤和分数是一一对应的。逐行对照：",[96,1618,1619,1634],{},[99,1620,1621],{},[102,1622,1623,1626,1629,1632],{},[105,1624,1625],{},"flow 步骤",[105,1627,1628],{},"谁来发起",[105,1630,1631],{},"发给谁",[105,1633,1297],{},[114,1635,1636,1654,1671,1691,1709,1724,1740,1760,1776],{},[102,1637,1638,1641,1646,1651],{},[119,1639,1640],{},"1",[119,1642,1643],{},[468,1644,1645],{},":Engineer",[119,1647,1648],{},[468,1649,1650],{},":PartsForm",[119,1652,1653],{},"提交申请",[102,1655,1656,1659,1663,1668],{},[119,1657,1658],{},"2",[119,1660,1661],{},[468,1662,1650],{},[119,1664,1665],{},[468,1666,1667],{},":PartsController",[119,1669,1670],{},"转给控制器",[102,1672,1673,1676,1680,1685],{},[119,1674,1675],{},"3",[119,1677,1678],{},[468,1679,1667],{},[119,1681,1682],{},[468,1683,1684],{},":StockItem",[119,1686,1687,1690],{},[468,1688,1689],{},"getStock()","，虚线返回",[102,1692,1693,1695,1699,1704],{},[119,1694,268],{},[119,1696,1697],{},[468,1698,1667],{},[119,1700,1701],{},[468,1702,1703],{},":SupplierAPI",[119,1705,1706],{},[21,1707,1708],{},"外部系统是边界对象，不是实体",[102,1710,1711,1714,1718,1721],{},[119,1712,1713],{},"5",[119,1715,1716],{},[468,1717,1667],{},[119,1719,1720],{},"自己",[119,1722,1723],{},"比对，自身方法",[102,1725,1726,1728,1732,1737],{},[119,1727,220],{},[119,1729,1730],{},[468,1731,1667],{},[119,1733,1734],{},[468,1735,1736],{},":IssueNote",[119,1738,1739],{},"创建出库单（写）",[102,1741,1742,1745,1749,1754],{},[119,1743,1744],{},"7",[119,1746,1747],{},[468,1748,1667],{},[119,1750,1751],{},[468,1752,1753],{},":WorkOrder",[119,1755,1756,1759],{},[468,1757,1758],{},"addPartUsage()","（写）",[102,1761,1762,1764,1768,1773],{},[119,1763,251],{},[119,1765,1766],{},[468,1767,1667],{},[119,1769,1770],{},[468,1771,1772],{},":Storekeeper",[119,1774,1775],{},"通知（这里是系统主动推送）",[102,1777,1778,1781,1785,1789],{},[119,1779,1780],{},"9",[119,1782,1783],{},[468,1784,1667],{},[119,1786,1787],{},[468,1788,1650],{},[119,1790,1791],{},"返回结果显示",[84,1793,1795],{"id":1794},"_83-成品图","8.3 成品图",[13,1797,1798],{},[391,1799],{"alt":1800,"src":1801},"申请配件的顺序图：五条生命线从左到右依次是工程师（actor）、申请界面（boundary）、配件控制器（control）、库存项（entity）、供应商接口（boundary 外部）。消息按 1 到 9 编号：提交申请、转控制器、查本地库存并以虚线返回、调供应商接口并以虚线返回、控制器自身比对库存、创建出库单、写入工单的配件消耗、通知仓管、最后以虚线返回成功消息给界面。控制器的激活条最长，库存项与供应商接口的短而窄，一眼能看出谁在等谁","\u002Fimages\u002Fsw-design-notes-27-sequence-answer.svg",[84,1803,1805],{"id":1804},"_84-四个细节","8.4 四个细节",[364,1807,1808,1817,1823,1829],{},[52,1809,1810,47,1813,1816],{},[21,1811,1812],{},"生命线顺序",[468,1814,1815],{},":Actor | :Boundary | :Control | :Entity…| :ExternalSystem","。按这个顺序摆，交叉线最少；",[52,1818,1819,1822],{},[21,1820,1821],{},"外部系统是边界对象。"," 第 4 步的供应商接口画成 boundary，不是 entity；",[52,1824,1825,1828],{},[21,1826,1827],{},"「读」和「显示」是两件事。"," 第 3–4 步是控制器去取数据，第 9 步才是界面显示。把显示画成控制器自己完成，是职责错位的典型；",[52,1830,1831,1834],{},[21,1832,1833],{},"消息编号。"," 讲义说编号是可选的，但画了能让「我覆盖了全部 10 步」一眼可见。",[34,1836,1838],{"id":1837},"_9-第-2b-题类图610-分","9 第 2b 题：类图（6–10 分）",[13,1840,1841,1843,1844,32],{},[21,1842,571],{},"：从顺序图导出类图，",[21,1845,1846],{},"不要求定义属性和方法",[13,1848,1849,1850,1853],{},"看到「not required to define the attributes or methods」这句就",[21,1851,1852],{},"别写属性和方法","，只画类名（带构造型）+ 关系，省下的时间检查箭头。",[84,1855,1857],{"id":1856},"_91-导出规则","9.1 导出规则",[13,1859,1860],{},"导出是机械的（笔记 22）：",[96,1862,1863,1873],{},[99,1864,1865],{},[102,1866,1867,1870],{},[105,1868,1869],{},"顺序图里的东西",[105,1871,1872],{},"对应到类图",[114,1874,1875,1883,1891],{},[102,1876,1877,1880],{},[119,1878,1879],{},"每个参与对象",[119,1881,1882],{},"一个类",[102,1884,1885,1888],{},[119,1886,1887],{},"对象收到的消息",[119,1889,1890],{},"该类的一个操作",[102,1892,1893,1896],{},[119,1894,1895],{},"谁调用谁",[119,1897,1898],{},"类之间的关系",[84,1900,1902],{"id":1901},"_92-成品图","9.2 成品图",[13,1904,1905],{},[391,1906],{"alt":1907,"src":1908},"类图成品：全部用虚线加开放箭头的依赖线，因为这是分析模型。最左是工程师参与者指向申请界面边界类，界面指向配件控制器控制类；控制器往右指向供应商接口边界类，往下分出三条依赖分别到库存项、工单、出库单三个实体类。底部两块说明：左边列出三条关系限制（boundary 不直连 entity、actor 只接触 boundary、不同构造型之间不做继承聚合组合），右边是机械的导出规则","\u002Fimages\u002Fsw-design-notes-27-class-answer.svg",[84,1910,1912],{"id":1911},"_93-三条关系限制直接的踩分点","9.3 三条关系限制（直接的踩分点）",[96,1914,1915,1927],{},[99,1916,1917],{},[102,1918,1919,1922,1925],{},[105,1920,1921],{},"关系",[105,1923,1924],{},"能不能用",[105,1926,1297],{},[114,1928,1929,1940,1950],{},[102,1930,1931,1934,1937],{},[119,1932,1933],{},"boundary 直接关联 entity",[119,1935,1936],{},"不推荐",[119,1938,1939],{},"中间应隔着 control",[102,1941,1942,1945,1947],{},[119,1943,1944],{},"actor 与 entity \u002F control 直接关联",[119,1946,1936],{},[119,1948,1949],{},"actor 只与 boundary 交互",[102,1951,1952,1955,1958],{},[119,1953,1954],{},"不同构造型之间做继承 \u002F 聚合 \u002F 组合",[119,1956,1957],{},"无意义",[119,1959,1960],{},"只在同类构造型内部用",[13,1962,1963,1964],{},"如果题目只给一段用例描述、不给顺序图（C25 样卷的 2b），做法反过来：",[21,1965,1966],{},"先在草稿上推几条消息，再从中抽类。",[34,1968,1970],{"id":1969},"_10-第-3-题坏味道-重构612-分","10 第 3 题：坏味道 + 重构（6–12 分）",[84,1972,1974],{"id":1973},"_101-真题的套路","10.1 真题的套路",[13,1976,1977,1978,32],{},"C25 真题和 C25\u002FC26 样卷是同一个套路：给两个类，其中子类",[21,1979,1980],{},"继承了一堆自己用不上的东西",[49,1982,1983,1996],{},[52,1984,1985,1986,1989,1990,840,1993,401],{},"C25 真题：",[468,1987,1988],{},"BlacklistedTrainingProvider extends TrainingProvider"," —— 黑名单机构继承了一个「能开课」的机构，还多出 ",[468,1991,1992],{},"blacklistedReason",[468,1994,1995],{},"blacklistedDate",[52,1997,1998,1999,2002,2003,2006,2007,2010,2011,32],{},"C25\u002FC26 样卷：",[468,2000,2001],{},"SubContractedProject extends Project"," —— 分包项目的成员由分包公司提供，于是父类的 ",[468,2004,2005],{},"addMember()"," 被改写成空方法，",[468,2008,2009],{},"removeMember()"," 直接 ",[468,2012,2013],{},"return null",[13,2015,2016,2017,2020,2021,32],{},"这就是",[21,2018,2019],{},"被拒绝的馈赠（refused bequest）","。它同时暗示了另一个问题 —— ",[21,2022,2023],{},"继承的语义用错了",[84,2025,2027],{"id":2026},"_102-如果换成这个案例","10.2 如果换成这个案例",[13,2029,2030],{},"考试不一定考同一个套路。用本篇的案例试一次，你能看到它在别的形态下也成立：",[2032,2033,2038],"pre",{"className":2034,"code":2035,"language":2036,"meta":2037,"style":2037},"language-java shiki shiki-themes github-light github-dark","public class Engineer {\n    protected String id;\n    protected String name;\n    protected List\u003CSkill> skills;\n    public void accept(WorkOrder order) { ... }\n    public void requestParts(String partNo, int qty) { ... }\n}\n\n\u002F\u002F 外包工程师：不接单、不领料，只做远程技术支持\npublic class OutsourcedEngineer extends Engineer {\n    @Override\n    public void accept(WorkOrder order) {\n        \u002F\u002F Do nothing\n    }\n    @Override\n    public void requestParts(String partNo, int qty) {\n        return;   \u002F\u002F 外包方自行备料\n    }\n    private String vendorName;\n    private String vendorContact;\n}\n","java","",[468,2039,2040,2060,2069,2077,2091,2113,2140,2146,2153,2160,2177,2186,2202,2208,2214,2221,2242,2254,2259,2268,2276],{"__ignoreMap":2037},[2041,2042,2045,2049,2052,2056],"span",{"class":2043,"line":2044},"line",1,[2041,2046,2048],{"class":2047},"szBVR","public",[2041,2050,2051],{"class":2047}," class",[2041,2053,2055],{"class":2054},"sScJk"," Engineer",[2041,2057,2059],{"class":2058},"sVt8B"," {\n",[2041,2061,2063,2066],{"class":2043,"line":2062},2,[2041,2064,2065],{"class":2047},"    protected",[2041,2067,2068],{"class":2058}," String id;\n",[2041,2070,2072,2074],{"class":2043,"line":2071},3,[2041,2073,2065],{"class":2047},[2041,2075,2076],{"class":2058}," String name;\n",[2041,2078,2080,2082,2085,2088],{"class":2043,"line":2079},4,[2041,2081,2065],{"class":2047},[2041,2083,2084],{"class":2058}," List\u003C",[2041,2086,2087],{"class":2047},"Skill",[2041,2089,2090],{"class":2058},"> skills;\n",[2041,2092,2094,2097,2100,2103,2106,2110],{"class":2043,"line":2093},5,[2041,2095,2096],{"class":2047},"    public",[2041,2098,2099],{"class":2047}," void",[2041,2101,2102],{"class":2054}," accept",[2041,2104,2105],{"class":2058},"(WorkOrder ",[2041,2107,2109],{"class":2108},"s4XuR","order",[2041,2111,2112],{"class":2058},") { ... }\n",[2041,2114,2116,2118,2120,2123,2126,2129,2132,2135,2138],{"class":2043,"line":2115},6,[2041,2117,2096],{"class":2047},[2041,2119,2099],{"class":2047},[2041,2121,2122],{"class":2054}," requestParts",[2041,2124,2125],{"class":2058},"(String ",[2041,2127,2128],{"class":2108},"partNo",[2041,2130,2131],{"class":2058},", ",[2041,2133,2134],{"class":2047},"int",[2041,2136,2137],{"class":2108}," qty",[2041,2139,2112],{"class":2058},[2041,2141,2143],{"class":2043,"line":2142},7,[2041,2144,2145],{"class":2058},"}\n",[2041,2147,2149],{"class":2043,"line":2148},8,[2041,2150,2152],{"emptyLinePlaceholder":2151},true,"\n",[2041,2154,2156],{"class":2043,"line":2155},9,[2041,2157,2159],{"class":2158},"sJ8bj","\u002F\u002F 外包工程师：不接单、不领料，只做远程技术支持\n",[2041,2161,2163,2165,2167,2170,2173,2175],{"class":2043,"line":2162},10,[2041,2164,2048],{"class":2047},[2041,2166,2051],{"class":2047},[2041,2168,2169],{"class":2054}," OutsourcedEngineer",[2041,2171,2172],{"class":2047}," extends",[2041,2174,2055],{"class":2054},[2041,2176,2059],{"class":2058},[2041,2178,2180,2183],{"class":2043,"line":2179},11,[2041,2181,2182],{"class":2058},"    @",[2041,2184,2185],{"class":2047},"Override\n",[2041,2187,2189,2191,2193,2195,2197,2199],{"class":2043,"line":2188},12,[2041,2190,2096],{"class":2047},[2041,2192,2099],{"class":2047},[2041,2194,2102],{"class":2054},[2041,2196,2105],{"class":2058},[2041,2198,2109],{"class":2108},[2041,2200,2201],{"class":2058},") {\n",[2041,2203,2205],{"class":2043,"line":2204},13,[2041,2206,2207],{"class":2158},"        \u002F\u002F Do nothing\n",[2041,2209,2211],{"class":2043,"line":2210},14,[2041,2212,2213],{"class":2058},"    }\n",[2041,2215,2217,2219],{"class":2043,"line":2216},15,[2041,2218,2182],{"class":2058},[2041,2220,2185],{"class":2047},[2041,2222,2224,2226,2228,2230,2232,2234,2236,2238,2240],{"class":2043,"line":2223},16,[2041,2225,2096],{"class":2047},[2041,2227,2099],{"class":2047},[2041,2229,2122],{"class":2054},[2041,2231,2125],{"class":2058},[2041,2233,2128],{"class":2108},[2041,2235,2131],{"class":2058},[2041,2237,2134],{"class":2047},[2041,2239,2137],{"class":2108},[2041,2241,2201],{"class":2058},[2041,2243,2245,2248,2251],{"class":2043,"line":2244},17,[2041,2246,2247],{"class":2047},"        return",[2041,2249,2250],{"class":2058},";   ",[2041,2252,2253],{"class":2158},"\u002F\u002F 外包方自行备料\n",[2041,2255,2257],{"class":2043,"line":2256},18,[2041,2258,2213],{"class":2058},[2041,2260,2262,2265],{"class":2043,"line":2261},19,[2041,2263,2264],{"class":2047},"    private",[2041,2266,2267],{"class":2058}," String vendorName;\n",[2041,2269,2271,2273],{"class":2043,"line":2270},20,[2041,2272,2264],{"class":2047},[2041,2274,2275],{"class":2058}," String vendorContact;\n",[2041,2277,2279],{"class":2043,"line":2278},21,[2041,2280,2145],{"class":2058},[13,2282,2283,2284,2287,2288,2291],{},"看出问题了吗？",[21,2285,2286],{},"两个方法被重写成空"," —— 这正是 refused bequest 的典型症状。而且语义上也不对：外包工程师",[21,2289,2290],{},"不是","一种「接单工程师」，只是碰巧也有 id 和 name。",[84,2293,2295],{"id":2294},"_103-答题分两段写","10.3 答题分两段写",[13,2297,2298,2301],{},[21,2299,2300],{},"(a) 指出坏味道 + 用什么手法（通常 6 分）。"," 写成三句话：",[364,2303,2304,2310,2321],{},[52,2305,2306,2307,401],{},"坏味道的名字：",[468,2308,2309],{},"Refused Bequest",[52,2311,2312,2313,2316,2317,2320],{},"证据：",[468,2314,2315],{},"accept()"," 被重写为空、",[468,2318,2319],{},"requestParts()"," 直接 return（「子类拒绝接受父类给的馈赠」）；",[52,2322,2323,2324,2327,2328,2331],{},"手法：",[468,2325,2326],{},"Replace Inheritance with Delegation","（用组合代替继承）+ ",[468,2329,2330],{},"Extract Superclass","（抽出只含公共部分的父类）。",[13,2333,2334],{},[21,2335,2336],{},"(b) 改设计，画类图（不要求写代码）。",[13,2338,2339],{},[391,2340],{"alt":2341,"src":2342},"重构前后的类图对照：左边重构前，外包工程师继承接单工程师，accept 与 requestParts 两个方法都被重写成空，红字标出坏味道为被拒绝的馈赠。右边重构后，抽出只含 id 与 name 的抽象人员类作为父类，接单工程师持有技能列表并能接单领料，外包工程师改为持有一个 Vendor（组合关系，空心菱形贴在外包工程师这一端），不再继承接单工程师。底部一行给出收尾那句话：新增一种工程师类型只需新增一个类","\u002Fimages\u002Fsw-design-notes-27-refactor-answer.svg",[13,2344,2345],{},"三种改法各自的适用条件：",[96,2347,2348,2361],{},[99,2349,2350],{},[102,2351,2352,2355,2358],{},[105,2353,2354],{},"情形",[105,2356,2357],{},"改法",[105,2359,2360],{},"图上的样子",[114,2362,2363,2385,2406],{},[102,2364,2365,2368,2373],{},[119,2366,2367],{},"两者共享大部分状态与行为，只有一小块不同",[119,2369,2370,2372],{},[21,2371,2330],{},"，把共同部分上移",[119,2374,2375,2378,2379,1255,2382],{},[468,2376,2377],{},"Person","（公共）← ",[468,2380,2381],{},"Engineer",[468,2383,2384],{},"OutsourcedEngineer",[102,2386,2387,2390,2395],{},[119,2388,2389],{},"差异是「能力上的有无」（能不能接单）",[119,2391,2392],{},[21,2393,2394],{},"改成组合 + 接口",[119,2396,2397,2399,2400,2403,2404],{},[468,2398,2384],{}," 持有一个 ",[468,2401,2402],{},"Vendor","，不再继承 ",[468,2405,2381],{},[102,2407,2408,2411,2417],{},[119,2409,2410],{},"只是行为契约相同、实现完全不同",[119,2412,2413,2416],{},[21,2414,2415],{},"引入接口","（判断见笔记 24）",[119,2418,2419],{},[468,2420,2421],{},"\u003C\u003Cinterface>> Assignable",[84,2423,2425],{"id":2424},"_104-收尾那一句","10.4 收尾那一句",[13,2427,2428,2429,47],{},"画完图，",[21,2430,2431],{},"再用一句话说明「新结构下新增一种工程师类型要改几个类」",[10,2433,2434],{},[13,2435,2436,2437,2439],{},"改后新增「实习工程师」只需新增一个类，不再需要重写任何空方法；改前则必须先继承 ",[468,2438,2381],{},"，再覆盖两个自己用不上的方法。",[13,2441,2442],{},"这句话是给「为什么这个改法更好」收尾的，几乎每次都能拿到最后一两分。",[34,2444,2446],{"id":2445},"_11-交卷前的自检","11 交卷前的自检",[84,2448,2450],{"id":2449},"_111-五分钟清单","11.1 五分钟清单",[49,2452,2455,2472,2482,2497,2507,2517,2523],{"className":2453},[2454],"contains-task-list",[52,2456,2459,2463,2464,2467,2468,2471],{"className":2457},[2458],"task-list-item",[2460,2461],"input",{"disabled":2151,"type":2462},"checkbox"," 每张图都有",[21,2465,2466],{},"标题","（",[468,2469,2470],{},"Figure 1: Use Case Diagram for Dispatch Platform","），标明对应哪一小问；",[52,2473,2475,2477,2478,2481],{"className":2474},[2458],[2460,2476],{"disabled":2151,"type":2462}," 用例图有",[21,2479,2480],{},"系统边界框","，actor 全在框外；",[52,2483,2485,2487,2488,2490,2491,2493,2494,401],{"className":2484},[2458],[2460,2486],{"disabled":2151,"type":2462}," ",[468,2489,470],{}," 指向被包含的用例，",[468,2492,474],{}," 指向基用例 —— ",[21,2495,2496],{},"方向没画反",[52,2498,2500,2502,2503,2506],{"className":2499},[2458],[2460,2501],{"disabled":2151,"type":2462}," 活动图里有",[21,2504,2505],{},"实体","，读写箭头方向正确；",[52,2508,2510,2512,2513,2516],{"className":2509},[2458],[2460,2511],{"disabled":2151,"type":2462}," 顺序图里 ",[21,2514,2515],{},"actor \u002F boundary \u002F control \u002F entity 四种生命线","都出现了；",[52,2518,2520,2522],{"className":2519},[2458],[2460,2521],{"disabled":2151,"type":2462}," 类图里的关系都带了正确的符号（虚线箭头 \u002F 实线 \u002F 空心菱形 \u002F 实心菱形 \u002F 空心三角）；",[52,2524,2526,2528,2529,32],{"className":2525},[2458],[2460,2527],{"disabled":2151,"type":2462}," 所有「不确定」的地方都写了 ",[21,2530,2531],{},"Assumption",[84,2533,2535],{"id":2534},"_112-开卷考试的操作细节","11.2 开卷考试的操作细节",[13,2537,2538,2539,2542],{},"讲义里那句「Please make sure that you know how to draw all the UML diagrams using ",[21,2540,2541],{},"online tool","」是硬要求：答案要交电子稿，图必须现场用工具画。所以考前一定要把这件事演练成肌肉记忆：",[49,2544,2545,2554,2560],{},[52,2546,2547,2550,2551,2553],{},[21,2548,2549],{},"选定一个工具并练熟","（draw.io \u002F WhiteStarUML \u002F StarUML \u002F Visual Paradigm 都行），知道它在哪里画 ",[468,2552,470],{},"、空心菱形、空心三角；",[52,2555,2556,2559],{},[21,2557,2558],{},"知道怎么导出成图片并贴进答题文档","，不要等到最后一刻才发现导出糊了；",[52,2561,2562,2565],{},[21,2563,2564],{},"准备好一张符号速查卡","（一页纸，开卷允许带）。内容就是笔记 28 那张图的打印版。",[34,2567,2568],{"id":2568},"本节自测",[364,2570,2571,2574,2577,2580,2583,2586,2589,2595],{},[52,2572,2573],{},"150 分钟的答题时间，投放顺序应该遵守哪两条原则？为什么「先做文字题」是坏策略？",[52,2575,2576],{},"拿到长案例，按哪三栏去扫？为什么不该逐句精读？",[52,2578,2579],{},"数据驱动分析表里，Predictive 和 Prescriptive 的区别在哪？各举本例中的一个例子。",[52,2581,2582],{},"用例图被要求「complete」时，你怎么保证不漏角色？本例里最容易被漏掉的那个角色是谁？",[52,2584,2585],{},"活动图的题目里「include entities」这一句，具体要你多画什么东西？哪一支箭头最容易画反？",[52,2587,2588],{},"界面题只有 4 分，判分实际看哪三件事？三行说明为什么必须提到「隐喻」？",[52,2590,2591,2592,2594],{},"顺序图的分数是怎么和 ",[468,2593,1561],{}," 的编号对应的？第 4 步「调用供应商接口」应该画成什么对象？",[52,2596,2597,2600],{},[468,2598,2599],{},"OutsourcedEngineer extends Engineer"," 为什么属于 refused bequest？三种改法各自的适用条件是什么？",[84,2602,2603],{"id":2603},"参考答案",[364,2605,2606,2612,2619,2628,2638,2648,2655,2665],{},[52,2607,2608,2611],{},[21,2609,2610],{},"画图题优先、能查书的题垫后","。因为文字题写多了不会多给分（阅卷按要点给分，写长不加分），而图没画完一定扣分（§1.3）。",[52,2613,2614,2615,2618],{},"按 ",[21,2616,2617],{},"「谁、什么事、想要什么」"," 三栏扫。因为案例里几乎每句话都能落到某道题上，逐句精读会把时间花在背景交代上；按三栏扫完，答题材料就成型了（§2）。",[52,2620,2621,2624,2625,2627],{},[21,2622,2623],{},"Predictive 说「下周哪些配件会缺」，Prescriptive 说「现在该做什么动作」","。区别在",[21,2626,726],{}," —— 本例的 Prescriptive 是「自动比对库存与供应商可售量，低于安全库存就生成补货建议并推送仓管」（§3.1）。",[52,2629,2630,2631,2634,2635,2637],{},"按「有自己目标的人或外部系统」逐个抄。本例最容易漏的是",[21,2632,2633],{},"配件供应商库存系统"," —— 它是外部系统，但确实是 actor；其次是「被通知的客户」，他在 ",[468,2636,843],{}," 里有自己的目标（§4.1）。",[52,2639,2640,2641,2644,2645,2647],{},"要",[21,2642,2643],{},"给动作挂上业务实体","，并画出读\u002F写两种方向的箭头。最容易画反的是",[21,2646,1267],{},"：读是「实体 → 动作」，写是「动作 → 实体」（§5.2）。",[52,2649,2650,2651,2654],{},"看",[21,2652,2653],{},"信息是否选对、隐喻是否明确标出、是否可读（有主次）","。三行说明必须提到「隐喻」，因为题目要求的就是「demonstrate how metaphors can be used」，不点明就等于没答（§6.2）。",[52,2656,2657,2660,2661,2664],{},[21,2658,2659],{},"每个编号对应 1–2 条消息","，分数大致按「消息覆盖度 + 职责正确性 + 符号规范」给。第 4 步的供应商接口要画成",[21,2662,2663],{},"边界对象","（boundary），不是实体 —— 判断依据是「你需要写代码去和它对接」（§8.2 \u002F §8.4）。",[52,2666,2667,2668,2467,2671,2673,2674,2676],{},"因为它继承了父类的两个方法却",[21,2669,2670],{},"都重写成空",[468,2672,2315],{}," 空实现、",[468,2675,2319],{}," 直接 return），这就是「子类拒绝接受父类给的馈赠」。三种改法：共享大部分 → Extract Superclass；差异是能力有无 → 组合 + 接口；只有契约相同 → 引入接口（§10.2 \u002F §10.3）。",[34,2678,2679],{"id":2679},"术语表",[96,2681,2682,2695],{},[99,2683,2684],{},[102,2685,2686,2689,2692],{},[105,2687,2688],{},"术语",[105,2690,2691],{},"中文",[105,2693,2694],{},"一句话解释",[114,2696,2697,2708,2719,2730,2741,2752,2763,2774,2785,2796,2807,2818,2829,2840,2851,2862,2873,2884],{},[102,2698,2699,2702,2705],{},[119,2700,2701],{},"basic flow of events",[119,2703,2704],{},"基本事件流",[119,2706,2707],{},"用例描述里「一切顺利」时的编号步骤序列",[102,2709,2710,2713,2716],{},[119,2711,2712],{},"activity flow table",[119,2714,2715],{},"活动流程表",[119,2717,2718],{},"逐行记录活动名与说明的表格，与活动图配套",[102,2720,2721,2724,2727],{},[119,2722,2723],{},"customer journey map",[119,2725,2726],{},"客户旅程图",[119,2728,2729],{},"用户完成目标的阶段、触点与情绪记录",[102,2731,2732,2735,2738],{},[119,2733,2734],{},"metaphor",[119,2736,2737],{},"隐喻",[119,2739,2740],{},"借真实世界的形态组织界面信息，如日历、看板",[102,2742,2743,2746,2749],{},[119,2744,2745],{},"assumption",[119,2747,2748],{},"假设",[119,2750,2751],{},"题目信息不足时自己补的前提，必须写在答案里",[102,2753,2754,2757,2760],{},[119,2755,2756],{},"descriptive analytics",[119,2758,2759],{},"描述性分析",[119,2761,2762],{},"看清过去发生了什么",[102,2764,2765,2768,2771],{},[119,2766,2767],{},"diagnostic analytics",[119,2769,2770],{},"诊断性分析",[119,2772,2773],{},"找出过去为什么发生",[102,2775,2776,2779,2782],{},[119,2777,2778],{},"predictive analytics",[119,2780,2781],{},"预测性分析",[119,2783,2784],{},"推测接下来可能发生什么",[102,2786,2787,2790,2793],{},[119,2788,2789],{},"prescriptive analytics",[119,2791,2792],{},"处方性分析",[119,2794,2795],{},"给出应当采取的动作或提醒",[102,2797,2798,2801,2804],{},[119,2799,2800],{},"use case realization",[119,2802,2803],{},"用例实现",[119,2805,2806],{},"用对象协作把用例流程具体化，产物是顺序图",[102,2808,2809,2812,2815],{},[119,2810,2811],{},"boundary \u002F control \u002F entity",[119,2813,2814],{},"边界 \u002F 控制 \u002F 实体对象",[119,2816,2817],{},"分析模型里三种职责不同的对象",[102,2819,2820,2823,2826],{},[119,2821,2822],{},"refused bequest",[119,2824,2825],{},"被拒绝的馈赠",[119,2827,2828],{},"子类继承了用不上的父类成员，只能空着或返回 null",[102,2830,2831,2834,2837],{},[119,2832,2833],{},"replace inheritance with delegation",[119,2835,2836],{},"用委派代替继承",[119,2838,2839],{},"把「继承」改成「持有 + 转发」的重构手法",[102,2841,2842,2845,2848],{},[119,2843,2844],{},"extract superclass",[119,2846,2847],{},"提取父类",[119,2849,2850],{},"把多个类共有的部分上移成新的父类",[102,2852,2853,2856,2859],{},[119,2854,2855],{},"pull down method",[119,2857,2858],{},"下移方法",[119,2860,2861],{},"把父类里用不上的方法推到真正需要它的子类",[102,2863,2864,2867,2870],{},[119,2865,2866],{},"test case",[119,2868,2869],{},"测试用例",[119,2871,2872],{},"测试场景、前置条件、测试数据与预期结果的组合",[102,2874,2875,2878,2881],{},[119,2876,2877],{},"boundary value analysis",[119,2879,2880],{},"边界值分析",[119,2882,2883],{},"在等价类边界上下取值测试",[102,2885,2886,2889,2892],{},[119,2887,2888],{},"traceability",[119,2890,2891],{},"可追溯性",[119,2893,2894],{},"答案的每一步都能对回题目的某一句话",[2896,2897,2898],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":2037,"searchDepth":2071,"depth":2071,"links":2900},[2901,2902,2907,2908,2913,2921,2927,2932,2937,2943,2948,2954,2958,2961],{"id":36,"depth":2062,"text":37},{"id":81,"depth":2062,"text":82,"children":2903},[2904,2905,2906],{"id":86,"depth":2071,"text":87},{"id":182,"depth":2071,"text":183},{"id":386,"depth":2071,"text":387},{"id":487,"depth":2062,"text":488},{"id":565,"depth":2062,"text":566,"children":2909},[2910,2911,2912],{"id":581,"depth":2071,"text":582},{"id":618,"depth":2071,"text":619},{"id":714,"depth":2071,"text":715},{"id":743,"depth":2062,"text":744,"children":2914},[2915,2916,2917,2918,2919,2920],{"id":755,"depth":2071,"text":756},{"id":805,"depth":2071,"text":806},{"id":964,"depth":2071,"text":965},{"id":974,"depth":2071,"text":975},{"id":1058,"depth":2071,"text":1059},{"id":1092,"depth":2071,"text":1093},{"id":1190,"depth":2062,"text":1191,"children":2922},[2923,2924,2925,2926],{"id":1203,"depth":2071,"text":1204},{"id":1228,"depth":2071,"text":1229},{"id":1275,"depth":2071,"text":1276},{"id":1356,"depth":2071,"text":1357},{"id":1374,"depth":2062,"text":1375,"children":2928},[2929,2930,2931],{"id":1413,"depth":2071,"text":1414},{"id":1423,"depth":2071,"text":1424},{"id":1456,"depth":2071,"text":1457},{"id":1466,"depth":2062,"text":1467,"children":2933},[2934,2935,2936],{"id":1502,"depth":2071,"text":1503},{"id":1519,"depth":2071,"text":1520},{"id":1541,"depth":2071,"text":1542},{"id":1552,"depth":2062,"text":1553,"children":2938},[2939,2940,2941,2942],{"id":1565,"depth":2071,"text":1566},{"id":1608,"depth":2071,"text":1609},{"id":1794,"depth":2071,"text":1795},{"id":1804,"depth":2071,"text":1805},{"id":1837,"depth":2062,"text":1838,"children":2944},[2945,2946,2947],{"id":1856,"depth":2071,"text":1857},{"id":1901,"depth":2071,"text":1902},{"id":1911,"depth":2071,"text":1912},{"id":1969,"depth":2062,"text":1970,"children":2949},[2950,2951,2952,2953],{"id":1973,"depth":2071,"text":1974},{"id":2026,"depth":2071,"text":2027},{"id":2294,"depth":2071,"text":2295},{"id":2424,"depth":2071,"text":2425},{"id":2445,"depth":2062,"text":2446,"children":2955},[2956,2957],{"id":2449,"depth":2071,"text":2450},{"id":2534,"depth":2071,"text":2535},{"id":2568,"depth":2062,"text":2568,"children":2959},[2960],{"id":2603,"depth":2071,"text":2603},{"id":2679,"depth":2062,"text":2679},"学习",null,"2026-11-18","拿一份完整的案例，从头到尾走一遍：怎么读案例列角色、怎么在四个小问之间分配时间、每一张图从哪一句话推出来、两张表怎么填、交卷前拿什么清单自查。附 C25 真题与样卷的题型分值对照。","md",false,{},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-27",{"title":5,"description":2965},"软件分析与设计笔记",27,"posts\u002FswDesign\u002Fsw-design-notes-27",[2975,2976,2977,2978],"应试","软件分析","软件设计","学习笔记","sWsk3iWnmlmnq363o8H7Wy12HgRjS2EPnvyDmAUfy2I",[2981,2987,2988,2994,3000,3006,3012,3018,3023,3028,3033,3038,3043,3048,3053,3058,3063,3068,3073,3078,3083,3088,3093,3098,3103,3108,3113,3118,3123,3129,3133,3137,3141,3145,3149,3153,3157,3161,3165,3169,3173,3179,3183,3189,3193,3197,3201,3205,3209,3213,3217,3222,3226,3230,3235,3240,3246,3250,3255,3259],{"path":2982,"title":2983,"description":2984,"date":2985,"series":2971,"seriesOrder":2986},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-28","软件分析与设计笔记 28：draw.io 作图手册：五张图的符号位置、落笔顺序与自检","不模拟软件界面，只讲清三件事：每个 UML 符号在 draw.io 里搜什么词、一张图该按什么顺序落笔、画完拿什么标准自查。覆盖用例图、活动图、顺序图、类图、界面草图五种图纸，末尾附「最容易画反的十二笔」总检表。","2026-11-19",28,{"path":2969,"title":5,"description":2965,"date":2964,"series":2971,"seriesOrder":2972},{"path":2989,"title":2990,"description":2991,"date":2992,"series":2971,"seriesOrder":2993},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-26","软件分析与设计笔记 26：总结：把整条链路串起来","系列收尾：从需求到代码的完整链路回顾、每一环的产出与验收方式、六条贯穿全系列的原则，以及一份可以直接拿去做项目自查的清单。","2026-11-17",26,{"path":2995,"title":2996,"description":2997,"date":2998,"series":2971,"seriesOrder":2999},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-25","软件分析与设计笔记 25：代码重构：坏味道与手法","重构不改变外部行为、只改善内部结构：四种常见坏味道与对应手法、为什么动手之前必须先有测试、什么时候该重构，以及重构和前面那些设计模型是什么关系。","2026-11-16",25,{"path":3001,"title":3002,"description":3003,"date":3004,"series":2971,"seriesOrder":3005},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-24","软件分析与设计笔记 24：设计原则：内聚、耦合与多态","好设计怎么衡量：内聚与耦合分别在说什么、一次从「差设计」到「多态重设计」的完整对照、抽象类与接口的选择依据，以及复用为什么会从优势变成风险。","2026-11-15",24,{"path":3007,"title":3008,"description":3009,"date":3010,"series":2971,"seriesOrder":3011},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-23","软件分析与设计笔记 23：设计建模：从对象模型到能实现的方案","分析模型能用但还不能直接开工：对象模型怎么映射到关系模型、继承映射的三种方案怎么选、数据访问层与 Data Broker 解决什么问题，以及三层架构与 MVC 的分工。","2026-11-14",23,{"path":3013,"title":3014,"description":3015,"date":3016,"series":2971,"seriesOrder":3017},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-22","软件分析与设计笔记 22：分析建模：边界、实体与控制对象","不经过分析直接写代码会踩什么坑、三种分析对象各管一段、怎么用顺序图完成一次用例实现，以及从顺序图导出类的属性、操作与关系的方法。","2026-11-13",22,{"path":3019,"title":3020,"description":3021,"date":3022,"series":2971,"seriesOrder":2278},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-21","软件分析与设计笔记 21：UML：类图与顺序图","为什么需要一种共同的画法：类符号三格怎么画、五种关系的符号与设计含义、每种关系落到 Java 是什么写法，顺序图的三要素怎么摆；以及这三种最容易找不到的符号在 draw.io 里各搜什么词。","2026-11-12",{"path":3024,"title":3025,"description":3026,"date":3027,"series":2971,"seriesOrder":2270},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-20","软件分析与设计笔记 20：面向对象概念：对象、关系与多态","面向对象不是「用某个语言写代码」：对象与类的区别、封装真正在保护什么、五种关系（依赖、关联、聚合、组合、继承）各自何时用，以及多态为什么能减少条件判断。","2026-11-11",{"path":3029,"title":3030,"description":3031,"date":3032,"series":2971,"seriesOrder":2261},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-19","软件分析与设计笔记 19：规范化与逻辑数据模型","一次改地址引发的数据不一致，讲清规范化的真正动机；UNF 到 3NF 每一步在解决什么问题，派生字段为什么不能存，优化为什么和规范化方向相反，以及逻辑数据模型在 3NF 之上补了什么。","2026-11-10",{"path":3034,"title":3035,"description":3036,"date":3037,"series":2971,"seriesOrder":2256},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-18","软件分析与设计笔记 18：数据库分析：实体、关系与数据字典","为什么不能拿到需求就动手建表：实体与关系怎么判定、基数为什么必须由业务方确认、数据命名要遵守什么规则，以及数据字典四列里最容易被空着的那一列。","2026-11-09",{"path":3039,"title":3040,"description":3041,"date":3042,"series":2971,"seriesOrder":2244},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-17","软件分析与设计笔记 17：用生成式 AI 做设计与开发：能用的场景与要防的坑","生成式 AI 在工作流里真正站得住的三个场景 —— 造示例数据、解释陌生代码、起草初稿；它为什么会复现社会偏见、为什么会编得像真的，以及哪些内容绝不能直接采用。","2026-11-08",{"path":3044,"title":3045,"description":3046,"date":3047,"series":2971,"seriesOrder":2223},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-16","软件分析与设计笔记 16：从 persona 到 URS：一份交付物的完整骨架","把前面十几篇串成一份能交出去的东西：用户需求规格说明书的九个部分、每一章来自哪个环节、由谁确认，以及面向决策者的提案该讲清哪三件事。","2026-11-07",{"path":3049,"title":3050,"description":3051,"date":3052,"series":2971,"seriesOrder":2216},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-15","软件分析与设计笔记 15：非功能需求：把「快、稳、安全」变成数字","为什么「系统要快」不是一条需求：非功能需求怎么量化，决定性能的用户量、交易量、数据量三张表怎么估，安全需求要写清什么，以及可靠性的「不可用」该怎么定义。","2026-11-06",{"path":3054,"title":3055,"description":3056,"date":3057,"series":2971,"seriesOrder":2210},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-14","软件分析与设计笔记 14：软件测试：层级、方法与等价类划分","「我们测过了」这句话问题在哪：为什么静态评审和动态测试缺一不可，五个测试层级各自验证什么，白盒与黑盒的差别，以及用等价类划分和边界值把无限输入变成有限用例的方法。","2026-11-05",{"path":3059,"title":3060,"description":3061,"date":3062,"series":2971,"seriesOrder":2204},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-13","软件分析与设计笔记 13：需求获取：五种调查方法与一场访谈","需求从哪里来：五种事实调查方法各自适合回答什么、代价是什么，访谈从准备到记录的全过程，问卷设计里最容易犯的错，以及访谈记录必须写下来的那几项信息。","2026-11-04",{"path":3064,"title":3065,"description":3066,"date":3067,"series":2971,"seriesOrder":2188},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-12","软件分析与设计笔记 12：前端设计：把流程变成屏幕","界面设计不是「画得好看」：从活动图走到屏幕的三步，CRUD 任务流怎么当检查表，界面必须回答的三个问题，信息架构与五种导航类型，视觉一致性与留白，以及移动端与 Web 端的差别。","2026-11-03",{"path":3069,"title":3070,"description":3071,"date":3072,"series":2971,"seriesOrder":2179},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-11","软件分析与设计笔记 11：Agentic AI 与业务流程自动化","AI agent 到底是什么：五项能力与四个核心组件，什么场景该用定时任务、什么该用程序、什么才值得用 agent，两种实现路径的差别，必须提前防住的四类失败模式，以及设计方法从提示词到编排的演进。","2026-11-02",{"path":3074,"title":3075,"description":3076,"date":3077,"series":2971,"seriesOrder":2162},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-10","软件分析与设计笔记 10：精炼用例模型：include、extend 与泛化","三种精炼用例关系的判断标准：include 什么时候用、它和 extend 的区别到底在哪、参与者泛化与用例泛化各解决什么问题，以及精炼到什么程度就该停手。","2026-11-01",{"path":3079,"title":3080,"description":3081,"date":3082,"series":2971,"seriesOrder":2155},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-09","软件分析与设计笔记 09：功能需求（二）：从流程到业务实体","活动图画完之后，怎么从流程里筛出真正的业务实体：三条判断标准、哪些名词其实不该建实体、属性从哪里来，以及领域模型和后面的数据模型分别负责什么。","2026-10-31",{"path":3084,"title":3085,"description":3086,"date":3087,"series":2971,"seriesOrder":2148},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-08","软件分析与设计笔记 08：功能需求（一）：用例模型与活动图","从用户故事到用例的翻译过程：什么才算「好」的参与者，系统边界怎么划，用例描述必须写清哪四件事，活动图怎么把分支、并行与泳道画清楚，以及这两个图在 draw.io 里各用哪个形状、最容易画错哪一笔。","2026-10-30",{"path":3089,"title":3090,"description":3091,"date":3092,"series":2971,"seriesOrder":2142},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-07","软件分析与设计笔记 07：用户故事：把需求写成可验收的一句话","用户故事的三段结构，怎么从用户画像和数据地图里把它提取出来，一条故事多大算合适、时序为什么也是需求的一部分，以及验收标准怎么写才算真的可验收。","2026-10-29",{"path":3094,"title":3095,"description":3096,"date":3097,"series":2971,"seriesOrder":2115},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-06","软件分析与设计笔记 06：范围界定（数据侧）：用数据校验你的判断","访谈结论和数字对不上时该怎么办：分析的四个层次分别在回答什么问题、为什么不能跳级、数据准备与搜集怎么做成一张应用地图，以及数据最容易在哪几个地方骗你。","2026-10-28",{"path":3099,"title":3100,"description":3101,"date":3102,"series":2971,"seriesOrder":2093},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-05","软件分析与设计笔记 05：范围界定（用户侧）：用户画像与客户旅程图","为什么「所有用户」是一个陷阱，项目边界该怎么划，用户画像要写哪五个要素、最容易写成什么废纸，客户旅程图怎么把阶段、想法和情绪画在同一张纸上，以及怎么从这两样东西一步步推到可验证的需求。","2026-10-27",{"path":3104,"title":3105,"description":3106,"date":3107,"series":2971,"seriesOrder":2079},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-04","软件分析与设计笔记 04：接手陌生案例的第一步：三问与一张表","拿到一个完全陌生的业务案例，怎么从零开始不跑偏：只问 Who、What、Why 三个问题，把「问题—事实—假设—理由」记成一张四列表，说清为什么假设必须写明理由，以及带着问题进访谈为什么比空手去有效得多。","2026-10-26",{"path":3109,"title":3110,"description":3111,"date":3112,"series":2971,"seriesOrder":2071},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-03","软件分析与设计笔记 03：Agile 与 Scrum：迭代、角色与产出物","从「三周做完交付，客户说这不是我要的」讲起，说清瀑布式与迭代式的根本差别，Scrum 的三个角色和三种产出物，一个 sprint 里四次固定活动各自在解决什么问题，以及敏捷里最常见的几个误解。","2026-10-25",{"path":3114,"title":3115,"description":3116,"date":3117,"series":2971,"seriesOrder":2062},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-02","软件分析与设计笔记 02：设计思维、用户驱动与数据驱动","从「客服要一个能一次看完所有排期的界面」这个翻车案例讲起，说清设计思维到底是什么、用户驱动与数据驱动各自能看见什么又看不见什么、为什么真正的落点是把两者合起来的 data-informed design，以及访谈中怎么问出有用的信息。","2026-10-24",{"path":3119,"title":3120,"description":3121,"date":3122,"series":2971,"seriesOrder":2044},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-01","软件分析与设计笔记 01：课程地图与从需求到设计的主干","这一篇不写具体方法，先把整条链路铺开：软件分析与设计到底要解决什么问题，从需求到设计分成哪两段，中间有哪十几个环节，一份完整的交付物里应该有什么，以及后面 27 篇笔记怎么排、新人该按什么顺序读。","2026-10-23",{"path":3124,"title":3125,"description":3126,"date":3127,"series":3128,"seriesOrder":2044},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-01","Spring 学习笔记 01：IoC、依赖注入与第一个 Spring Boot 应用","从「手写 new 出来的三层结构」的痛点讲起，说清 IoC 容器、Bean 与依赖注入是怎么回事，再用 Maven 与 Spring Initializr 跑起第一个能返回 JSON 的应用。","2026-10-15","Spring 学习笔记",{"path":3130,"title":3131,"description":3132,"date":3127,"series":3128,"seriesOrder":2062},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-02","Spring 学习笔记 02：Spring Data JPA 基础——实体映射与 Repository","用 ORM 把类映射到表：@Entity、@Id、@GeneratedValue 怎么用，CrudRepository 三层接口怎么选，H2 与 MySQL 怎么配，以及 ddl-auto 到底该写哪个值。",{"path":3134,"title":3135,"description":3136,"date":3127,"series":3128,"seriesOrder":2071},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-03","Spring 学习笔记 03：JPA 查询——派生方法、JPQL 与分页排序","Repository 自带的方法只够按主键查，这篇讲三种自己造查询的方式：方法名派生、@Query 写 JPQL、原生 SQL，以及 Pageable 分页排序和投影返回。",{"path":3138,"title":3139,"description":3140,"date":3127,"series":3128,"seriesOrder":2079},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-04","Spring 学习笔记 04：JPA 关联映射与仓储测试","一对多、多对多怎么映射，谁负责维护外键，FetchType 与 CascadeType 该怎么选，顺带用 @DataJpaTest 与 AssertJ 把仓储层测起来。",{"path":3142,"title":3143,"description":3144,"date":3127,"series":3128,"seriesOrder":2093},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-05","Spring 学习笔记 05：Spring MVC 与 Thymeleaf 入门","一次页面请求在 Spring MVC 里走了哪几步，@Controller 怎么把数据交给模板，@PathVariable 与 @RequestParam 怎么取参数，以及控制器为什么必须是无状态的。",{"path":3146,"title":3147,"description":3148,"date":3127,"series":3128,"seriesOrder":2115},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-06","Spring 学习笔记 06：表单绑定与服务端校验","把表单字段绑到对象上，用 Bean Validation 注解做服务端校验，把错误信息显示回用户刚填的那一页，再补上自定义校验注解与全局异常处理。",{"path":3150,"title":3151,"description":3152,"date":3127,"series":3128,"seriesOrder":2142},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-07","Spring 学习笔记 07：Thymeleaf 片段复用与国际化","用 th:fragment 与 th:insert\u002Fth:replace 把导航栏、页脚抽成片段，页面套用统一布局，再用 messages.properties 与 LocaleResolver 做中英文切换。",{"path":3154,"title":3155,"description":3156,"date":3127,"series":3128,"seriesOrder":2148},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-08","Spring 学习笔记 08：HTTP Session 与会话状态管理","HTTP 无状态带来的问题，Cookie 与 Session 怎么分工，Spring 里读写会话的几种方式，以及会话固定、超时、多实例共享这些必须想清楚的事。",{"path":3158,"title":3159,"description":3160,"date":3127,"series":3128,"seriesOrder":2155},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-09","Spring 学习笔记 09：拦截器 HandlerInterceptor","登录检查、权限判断、请求耗时统计这类横切逻辑该放哪：HandlerInterceptor 的三个回调各在什么时机执行，怎么注册与排除路径，以及它和过滤器的分工。",{"path":3162,"title":3163,"description":3164,"date":3127,"series":3128,"seriesOrder":2162},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-10","Spring 学习笔记 10：Service 层与事务","一组数据库操作要么全成功要么全失败，靠 @Transactional 怎么做到；传播行为、隔离级别、回滚规则怎么选，以及自调用失效、乐观锁悲观锁这些实战里的坑。",{"path":3166,"title":3167,"description":3168,"date":3127,"series":3128,"seriesOrder":2179},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-11","Spring 学习笔记 11：REST API 基础——把 Service 暴露成接口","同一套 Service 怎么同时服务页面和客户端：@RestController 的路由与方法语义、状态码怎么给、DTO 怎么定，以及 MockMvc 端到端和切片测试的两种写法与各自的坑。",{"path":3170,"title":3171,"description":3172,"date":3127,"series":3128,"seriesOrder":2188},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-12","Spring 学习笔记 12：REST 进阶——版本、更新、跨域与文档化","接口能跑通之后要处理的几件事：URL 与响应结构怎么定、版本怎么演进、更新怎么做到可安全重试、CORS 怎么配、HATEOAS 与 Spring Data REST 该不该用。",{"path":3174,"title":3175,"description":3176,"date":3177,"series":3178,"seriesOrder":2079},"\u002Fposts\u002Fjava\u002Fjava-functionalprogramming-notes","Java 函数式编程笔记：Lambda、函数式接口与 Streams","学习 Java 函数式编程时的个人笔记：Lambda 表达式的五步简写与方法引用、常见函数式接口、Stream 流水线与惰性求值，以及创建流、中间操作、终止操作与收集器的用法。示例代码均为自写，运行结果来自本地实测。","2026-10-13","Java 学习笔记",{"path":3180,"title":3181,"description":3182,"date":3177,"series":3178,"seriesOrder":2071},"\u002Fposts\u002Fjava\u002Fjava-generics-notes","Java 泛型笔记：泛型方法、有界类型与泛型类","学习 Java 泛型时的个人笔记：从重复的重载方法与多态尝试讲起，再到泛型方法与类型推断、有界泛型类型、Comparable 与 Number 边界，以及泛型类在集合中的用法。示例代码均为自写，运行结果来自本地实测。",{"path":3184,"title":3185,"description":3186,"date":3187,"series":3188,"seriesOrder":2079},"\u002Fposts\u002Fmysql\u002Fmysql-learning-04","MySQL 学习笔记 04：数据操纵（增删改）","MySQL 学习笔记第四篇：INSERT 插入（含批量插入与 INSERT ... SELECT）、UPDATE 更新、DELETE 删除，以及各自的坑。","2026-10-10","SQL 学习笔记",{"path":3190,"title":3191,"description":3192,"date":3187,"series":3188,"seriesOrder":2093},"\u002Fposts\u002Fmysql\u002Fmysql-learning-05","MySQL 学习笔记 05：DDL 概览","MySQL 学习笔记第五篇：数据定义语言概览——Schema、Table、View、Index、Constraints 这几类对象分别对应哪些 CREATE \u002F ALTER \u002F DROP 命令。",{"path":3194,"title":3195,"description":3196,"date":3187,"series":3188,"seriesOrder":2115},"\u002Fposts\u002Fmysql\u002Fmysql-learning-06","MySQL 学习笔记 06：CREATE TABLE 与数据类型","MySQL 学习笔记第六篇：CREATE TABLE 的完整语法、常用数据类型的选型建议，以及外键的两种定义方式。",{"path":3198,"title":3199,"description":3200,"date":3187,"series":3188,"seriesOrder":2142},"\u002Fposts\u002Fmysql\u002Fmysql-learning-07","MySQL 学习笔记 07：索引","MySQL 学习笔记第七篇：索引的作用与 B+ 树结构、单列与复合索引的创建、索引的代价与适用场景。",{"path":3202,"title":3203,"description":3204,"date":3187,"series":3188,"seriesOrder":2148},"\u002Fposts\u002Fmysql\u002Fmysql-learning-08","MySQL 学习笔记 08：DROP 与 ALTER","MySQL 学习笔记第八篇：DROP 删除数据库对象、ALTER 修改表结构，以及常见的坑。",{"path":3206,"title":3207,"description":3208,"date":3187,"series":3188,"seriesOrder":2155},"\u002Fposts\u002Fmysql\u002Fmysql-learning-09","MySQL 学习笔记 09：约束与数据完整性","MySQL 学习笔记第九篇：SQL 约束——NOT NULL、CHECK、PRIMARY KEY、FOREIGN KEY 等如何保证数据完整性，以及它们的对比。",{"path":3210,"title":3211,"description":3212,"date":3187,"series":3188,"seriesOrder":2162},"\u002Fposts\u002Fmysql\u002Fmysql-learning-10","MySQL 学习笔记 10：视图","MySQL 学习笔记第十篇：视图（Views）的定义与特性、和表的对比、创建与使用，以及可更新视图的限制。",{"path":3214,"title":3215,"description":3216,"date":3187,"series":3188,"seriesOrder":2179},"\u002Fposts\u002Fmysql\u002Fmysql-learning-11","MySQL 学习笔记 11：存储过程","MySQL 学习笔记第十一篇：存储过程（Stored Procedures）的概念、创建与调用、带参数的写法，以及优缺点。",{"path":3218,"title":3219,"description":3220,"date":3221,"series":3188,"seriesOrder":2044},"\u002Fposts\u002Fmysql\u002Fmysql-learning-01","MySQL 学习笔记 01：MySQL 基础知识","MySQL 学习笔记第一篇：MySQL Server 与 Workbench 的安装，数据库与 DBMS 的基本概念，关系模型、ACID 事务、常见数据类型，以及后续的学习路线。","2026-10-09",{"path":3223,"title":3224,"description":3225,"date":3221,"series":3188,"seriesOrder":2062},"\u002Fposts\u002Fmysql\u002Fmysql-learning-02","MySQL 学习笔记 02：SELECT 查询与过滤","MySQL 学习笔记第二篇：SELECT 的基本语法与逻辑执行顺序，WHERE 过滤（比较、LIKE、IN、BETWEEN、NULL）、各种 JOIN、UNION 与子查询。",{"path":3227,"title":3228,"description":3229,"date":3221,"series":3188,"seriesOrder":2071},"\u002Fposts\u002Fmysql\u002Fmysql-learning-03","MySQL 学习笔记 03：聚合、分组与输出控制","MySQL 学习笔记第三篇：COUNT\u002FSUM\u002FAVG 等聚合函数、GROUP BY 分组、HAVING 过滤、ORDER BY 与 LIMIT，以及一条 SELECT 的完整逻辑执行顺序。",{"path":3231,"title":3232,"description":3233,"date":3234,"series":3178,"seriesOrder":2062},"\u002Fposts\u002Fjava\u002Fjava-oop-notes","Java 面向对象笔记：类、继承、多态与异常","学习 Java 面向对象编程时的个人笔记：类与对象、封装与访问修饰符、继承与多态、集合、抽象类与接口、异常处理。示例代码均为自写，运行结果来自本地实测。","2026-10-06",{"path":3236,"title":3237,"description":3238,"date":3239,"series":3178,"seriesOrder":2044},"\u002Fposts\u002Fjava\u002Fjava-basics-notes","Java 基础语法笔记：从环境安装到方法与数组","学习 Java 基础语法时的个人笔记：JDK 安装、输入输出、变量与运算符、条件与循环、字符串、数组与方法。示例代码均为自写，运行结果来自本地实测。","2026-10-05",{"path":3241,"title":3242,"description":3243,"date":3244,"series":3245,"seriesOrder":2044},"\u002Fposts\u002Fgit\u002Fgit-install-and-basics","Git 安装与基本使用","从装好 Git 到跑通日常提交流程，把最常用的几条命令和它们背后的三个区域讲清楚。","2026-10-04","Git 入门",{"path":3247,"title":3248,"description":3249,"date":3244,"series":3245,"seriesOrder":2062},"\u002Fposts\u002Fgit\u002Flocal-remote-repository","本地远程仓库的部署","用自己的机器当 Git 服务器：建一个裸仓库、走 SSH 连上去，把本地提交推上去。",{"path":3251,"title":3252,"description":3253,"date":3244,"series":3254,"seriesOrder":2044},"\u002Fposts\u002Fguide\u002Fguide-file-layout","文件都放在哪","文章、图片、封面分别放在仓库的什么位置，哪些目录可以放手改、哪些碰了会出问题。","博客使用指南",{"path":3256,"title":3257,"description":3258,"date":3244,"series":3254,"seriesOrder":2062},"\u002Fposts\u002Fguide\u002Fguide-frontmatter","frontmatter 每个字段是什么意思","文章开头那段被横线包住的字段，逐个说明作用、默认行为和写错的后果。",{"path":3260,"title":3261,"description":3262,"date":3244,"series":3254,"seriesOrder":2071},"\u002Fposts\u002Fguide\u002Fguide-markdown","正文怎么写 —— Markdown 与排版效果","标题、链接、图片、代码、表格分别怎么写，以及本站对它们做了哪些自定义处理。",1793268147833]