[{"data":1,"prerenderedAt":960},["ShallowReactive",2],{"post:\u002Fposts\u002Fguide\u002Fguide-markdown":3,"posts:ordered":660},{"id":4,"title":5,"body":6,"category":646,"cover":647,"date":648,"description":649,"extension":363,"featured":650,"meta":651,"navigation":402,"path":652,"seo":653,"series":654,"seriesOrder":55,"stem":655,"tags":656,"__hash__":659},"posts\u002Fposts\u002Fguide\u002Fguide-markdown.md","正文怎么写 —— Markdown 与排版效果",{"type":7,"value":8,"toc":634},"minimark",[9,13,17,29,59,87,90,115,129,138,141,165,172,178,181,184,204,211,217,220,223,237,248,273,276,335,368,371,378,421,423,439,451,454,490,492,542,545,548,554,564,566,572,575,578,589,592,595,598,624,630],[10,11,12],"p",{},"正文用 Markdown 写，绝大部分是标准语法。这一篇既是写法说明，也是效果演示——你看到的\n样子就是写出来直接得到的样子。",[14,15,16],"h2",{"id":16},"标题",[10,18,19,20,24,25,28],{},"用 ",[21,22,23],"code",{},"##"," 到 ",[21,26,27],{},"####"," 表示章节：",[30,31,36],"pre",{"className":32,"code":33,"language":34,"meta":35,"style":35},"language-markdown shiki shiki-themes github-light github-dark","## 二级标题\n### 三级标题\n#### 四级标题\n","markdown","",[21,37,38,47,53],{"__ignoreMap":35},[39,40,43],"span",{"class":41,"line":42},"line",1,[39,44,46],{"class":45},"sq-ep","## 二级标题\n",[39,48,50],{"class":41,"line":49},2,[39,51,52],{"class":45},"### 三级标题\n",[39,54,56],{"class":41,"line":55},3,[39,57,58],{"class":45},"#### 四级标题\n",[10,60,61,73,74,76,77,80,81,83,84,86],{},[62,63,64,65,68,69,72],"strong",{},"文章标题本身用 frontmatter 的 ",[21,66,67],{},"title"," 写，正文里不要再用 ",[21,70,71],{},"#","。"," 正文里的 ",[21,75,23],{}," 和\n",[21,78,79],{},"###"," 会自动出现在左侧的目录里，读者点一下就能跳过去，所以标题层级别乱跳（比如从\n",[21,82,23],{}," 直接到 ",[21,85,27],{},"）。",[14,88,89],{"id":89},"强调",[30,91,93],{"className":32,"code":92,"language":34,"meta":35,"style":35},"**加粗**，*斜体*，`行内代码`\n",[21,94,95],{"__ignoreMap":35},[39,96,97,101,105,109,111],{"class":41,"line":42},[39,98,100],{"class":99},"sIZ1i","**加粗**",[39,102,104],{"class":103},"sVt8B","，",[39,106,108],{"class":107},"s5osK","*斜体*",[39,110,104],{"class":103},[39,112,114],{"class":113},"sj4cs","`行内代码`\n",[10,116,117,118,121,122,121,126,72],{},"效果：",[62,119,120],{},"加粗","、",[123,124,125],"em",{},"斜体",[21,127,128],{},"行内代码",[10,130,131,132,121,135,72],{},"行内代码适合放文件名、字段名、短命令这类内容，比如 ",[21,133,134],{},"content\u002Fposts\u002F",[21,136,137],{},"seriesOrder",[14,139,140],{"id":140},"链接",[30,142,144],{"className":32,"code":143,"language":34,"meta":35,"style":35},"[链接文字](https:\u002F\u002Fexample.com)\n",[21,145,146],{"__ignoreMap":35},[39,147,148,151,155,158,162],{"class":41,"line":42},[39,149,150],{"class":103},"[",[39,152,154],{"class":153},"svl0z","链接文字",[39,156,157],{"class":103},"](",[39,159,161],{"class":160},"s2frl","https:\u002F\u002Fexample.com",[39,163,164],{"class":103},")\n",[10,166,167,168,171],{},"和大多数网站不一样，",[62,169,170],{},"本站的正文链接不加下划线、也不换颜色","，只是加粗，和周围文字保持\n一致的色调——鼠标悬停时才会出现下划线。这是刻意的设计选择，写的时候不用管，正常用\n方括号加圆括号就行。",[10,173,174,175,72],{},"需要放一个纯网址而不带文字时，可以直接写 ",[21,176,177],{},"\u003Chttps:\u002F\u002Fexample.com>",[14,179,180],{"id":180},"图片",[10,182,183],{},"语法和链接很像，前面多一个感叹号：",[30,185,187],{"className":32,"code":186,"language":34,"meta":35,"style":35},"![图片说明](\u002Fimages\u002Fgit-branches.png)\n",[21,188,189],{"__ignoreMap":35},[39,190,191,194,197,199,202],{"class":41,"line":42},[39,192,193],{"class":103},"![",[39,195,196],{"class":153},"图片说明",[39,198,157],{"class":103},[39,200,201],{"class":160},"\u002Fimages\u002Fgit-branches.png",[39,203,164],{"class":103},[10,205,206,207,210],{},"方括号里的说明不会显示在页面上，但",[62,208,209],{},"一定要写","——一是读者看不清图时能看到它，二是搜\n索引擎靠它理解图片内容。图片会自动加圆角，宽度也不会超出正文范围：",[10,212,213],{},[214,215],"img",{"alt":216,"src":201},"两个分支指向同一串提交",[10,218,219],{},"图片放哪里、怎么引用，见本系列第一篇《文件都放在哪》。",[14,221,222],{"id":222},"代码",[10,224,225,226,229,230,233,234,72],{},"行内短代码用",[62,227,228],{},"一个","反引号包住：",[21,231,232],{},"`npm run dev`","，效果是 ",[21,235,236],{},"npm run dev",[10,238,239,240,243,244,247],{},"多行代码用",[62,241,242],{},"三个","反引号，并",[62,245,246],{},"在开头的反引号后面写上语言","：",[30,249,251],{"className":32,"code":250,"language":34,"meta":35,"style":35},"```bash\ngit status\n```\n",[21,252,253,258,268],{"__ignoreMap":35},[39,254,255],{"class":41,"line":42},[39,256,257],{"class":103},"```bash\n",[39,259,260,264],{"class":41,"line":49},[39,261,263],{"class":262},"sScJk","git",[39,265,267],{"class":266},"sZZnC"," status\n",[39,269,270],{"class":41,"line":55},[39,271,272],{"class":103},"```\n",[10,274,275],{},"写上语言后有两个好处：代码会按语法着色，左上角会显示语言名，右上角还有一键复制的\n按钮。",[30,277,281],{"className":278,"code":279,"language":280,"meta":35,"style":35},"language-bash shiki shiki-themes github-light github-dark","git switch -c fix-login-error\ngit add .\ngit commit -m \"修复登录页在空密码时的报错\"\ngit push -u origin fix-login-error\n","bash",[21,282,283,296,306,319],{"__ignoreMap":35},[39,284,285,287,290,293],{"class":41,"line":42},[39,286,263],{"class":262},[39,288,289],{"class":266}," switch",[39,291,292],{"class":113}," -c",[39,294,295],{"class":266}," fix-login-error\n",[39,297,298,300,303],{"class":41,"line":49},[39,299,263],{"class":262},[39,301,302],{"class":266}," add",[39,304,305],{"class":266}," .\n",[39,307,308,310,313,316],{"class":41,"line":55},[39,309,263],{"class":262},[39,311,312],{"class":266}," commit",[39,314,315],{"class":113}," -m",[39,317,318],{"class":266}," \"修复登录页在空密码时的报错\"\n",[39,320,322,324,327,330,333],{"class":41,"line":321},4,[39,323,263],{"class":262},[39,325,326],{"class":266}," push",[39,328,329],{"class":113}," -u",[39,331,332],{"class":266}," origin",[39,334,295],{"class":266},[10,336,337,338,121,340,121,343,121,346,121,349,121,352,121,355,121,358,121,361,364,365,72],{},"常用的语言标识：",[21,339,280],{},[21,341,342],{},"js",[21,344,345],{},"ts",[21,347,348],{},"json",[21,350,351],{},"vue",[21,353,354],{},"yaml",[21,356,357],{},"css",[21,359,360],{},"html",[21,362,363],{},"md","。不写\n语言也能用，只是没有着色，左上角会显示 ",[21,366,367],{},"text",[14,369,370],{"id":370},"列表",[10,372,373,374,377],{},"无序列表用 ",[21,375,376],{},"-","，有序列表用数字：",[30,379,381],{"className":32,"code":380,"language":34,"meta":35,"style":35},"- 第一项\n- 第二项\n\n1. 第一步\n2. 第二步\n",[21,382,383,391,398,404,412],{"__ignoreMap":35},[39,384,385,388],{"class":41,"line":42},[39,386,376],{"class":387},"s4XuR",[39,389,390],{"class":103}," 第一项\n",[39,392,393,395],{"class":41,"line":49},[39,394,376],{"class":387},[39,396,397],{"class":103}," 第二项\n",[39,399,400],{"class":41,"line":55},[39,401,403],{"emptyLinePlaceholder":402},true,"\n",[39,405,406,409],{"class":41,"line":321},[39,407,408],{"class":387},"1.",[39,410,411],{"class":103}," 第一步\n",[39,413,415,418],{"class":41,"line":414},5,[39,416,417],{"class":387},"2.",[39,419,420],{"class":103}," 第二步\n",[10,422,117],{},[424,425,426,433,436],"ul",{},[427,428,429,430],"li",{},"写之前先 ",[21,431,432],{},"git status",[427,434,435],{},"提交说明写清楚为什么改",[427,437,438],{},"不确定就先开分支",[440,441,442,445,448],"ol",{},[427,443,444],{},"新建分支",[427,446,447],{},"改代码",[427,449,450],{},"提交并推送",[14,452,453],{"id":453},"表格",[30,455,457],{"className":32,"code":456,"language":34,"meta":35,"style":35},"| 字段 | 含义 |\n| --- | --- |\n| `date` | 发布日期 |\n| `tags` | 标签 |\n",[21,458,459,464,469,480],{"__ignoreMap":35},[39,460,461],{"class":41,"line":42},[39,462,463],{"class":103},"| 字段 | 含义 |\n",[39,465,466],{"class":41,"line":49},[39,467,468],{"class":103},"| --- | --- |\n",[39,470,471,474,477],{"class":41,"line":55},[39,472,473],{"class":103},"| ",[39,475,476],{"class":113},"`date`",[39,478,479],{"class":103}," | 发布日期 |\n",[39,481,482,484,487],{"class":41,"line":321},[39,483,473],{"class":103},[39,485,486],{"class":113},"`tags`",[39,488,489],{"class":103}," | 标签 |\n",[10,491,117],{},[493,494,495,508],"table",{},[496,497,498],"thead",{},[499,500,501,505],"tr",{},[502,503,504],"th",{},"字段",[502,506,507],{},"含义",[509,510,511,522,532],"tbody",{},[499,512,513,519],{},[514,515,516],"td",{},[21,517,518],{},"date",[514,520,521],{},"发布日期，决定排序",[499,523,524,529],{},[514,525,526],{},[21,527,528],{},"tags",[514,530,531],{},"标签，可以多个",[499,533,534,539],{},[514,535,536],{},[21,537,538],{},"featured",[514,540,541],{},"是否上首页精选",[10,543,544],{},"适合字段说明、参数对照这类内容。",[14,546,547],{"id":547},"引用",[10,549,19,550,553],{},[21,551,552],{},">"," 开头：",[30,555,557],{"className":32,"code":556,"language":34,"meta":35,"style":35},"> 这是一段引用。\n",[21,558,559],{"__ignoreMap":35},[39,560,561],{"class":41,"line":42},[39,562,556],{"class":563},"s9eBZ",[10,565,117],{},[567,568,569],"blockquote",{},[10,570,571],{},"把文件复制成「报告-v2-最终版-真的最终版.docx」是很多人最早的版本管理。",[10,573,574],{},"适合放补充说明、注意事项或者引用的原话。",[14,576,577],{"id":577},"分隔线",[10,579,580,581,584,585,588],{},"单独一行写 ",[21,582,583],{},"---"," 会画一条横线。",[62,586,587],{},"但要注意","：如果它出现在文章最开头，会被当成\nfrontmatter 的开始，所以正文里使用时前面一定要有空行。",[590,591],"hr",{},[10,593,594],{},"像这样，用来分隔差异较大的段落。",[14,596,597],{"id":597},"几个写作建议",[424,599,600,606,612,618],{},[427,601,602,605],{},[62,603,604],{},"段落别太长","。中文在屏幕上连续超过五六行，读起来就会累，该分段就分段。",[427,607,608,611],{},[62,609,610],{},"善用二级标题","。它们会进目录，读者在长文里靠目录跳转；一篇文章里只有两三个二级\n标题，目录的价值就不大。",[427,613,614,617],{},[62,615,616],{},"图片记得写说明","。不是给别人看的，是给读屏软件和搜索引擎看的。",[427,619,620,623],{},[62,621,622],{},"代码块一定要标语言","。多打几个字符，换来的着色和复制按钮很值。",[10,625,626,627,629],{},"写完之后本地跑 ",[21,628,236],{}," 看一眼效果，确认没问题再提交。",[631,632,633],"style",{},"html pre.shiki code .sq-ep, html code.shiki .sq-ep{--shiki-default:#005CC5;--shiki-default-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold}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);}html pre.shiki code .sIZ1i, html code.shiki .sIZ1i{--shiki-default:#24292E;--shiki-default-font-weight:bold;--shiki-dark:#E1E4E8;--shiki-dark-font-weight:bold}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s5osK, html code.shiki .s5osK{--shiki-default:#24292E;--shiki-default-font-style:italic;--shiki-dark:#E1E4E8;--shiki-dark-font-style:italic}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .svl0z, html code.shiki .svl0z{--shiki-default:#032F62;--shiki-default-text-decoration:underline;--shiki-dark:#DBEDFF;--shiki-dark-text-decoration:underline}html pre.shiki code .s2frl, html code.shiki .s2frl{--shiki-default:#24292E;--shiki-default-text-decoration:underline;--shiki-dark:#E1E4E8;--shiki-dark-text-decoration:underline}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}",{"title":35,"searchDepth":55,"depth":55,"links":635},[636,637,638,639,640,641,642,643,644,645],{"id":16,"depth":49,"text":16},{"id":89,"depth":49,"text":89},{"id":140,"depth":49,"text":140},{"id":180,"depth":49,"text":180},{"id":222,"depth":49,"text":222},{"id":370,"depth":49,"text":370},{"id":453,"depth":49,"text":453},{"id":547,"depth":49,"text":547},{"id":577,"depth":49,"text":577},{"id":597,"depth":49,"text":597},"指南","\u002Fimages\u002Fguide-cover.svg","2026-10-04","标题、链接、图片、代码、表格分别怎么写，以及本站对它们做了哪些自定义处理。",false,{},"\u002Fposts\u002Fguide\u002Fguide-markdown",{"title":5,"description":649},"博客使用指南","posts\u002Fguide\u002Fguide-markdown",[657,658],"写作","Markdown","xBDKU2FdDPKbuk1F9yEN2Kw8KngKFiIwFVzZnFYB2i0",[661,668,674,680,686,692,698,704,710,716,722,728,734,740,746,752,758,764,770,776,782,788,794,800,805,810,815,820,825,831,835,839,843,847,851,855,859,863,867,871,875,881,885,891,895,899,903,907,911,915,919,924,928,932,937,942,947,951,955,959],{"path":662,"title":663,"description":664,"date":665,"series":666,"seriesOrder":667},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-28","软件分析与设计笔记 28：draw.io 作图手册：五张图的符号位置、落笔顺序与自检","不模拟软件界面，只讲清三件事：每个 UML 符号在 draw.io 里搜什么词、一张图该按什么顺序落笔、画完拿什么标准自查。覆盖用例图、活动图、顺序图、类图、界面草图五种图纸，末尾附「最容易画反的十二笔」总检表。","2026-11-19","软件分析与设计笔记",28,{"path":669,"title":670,"description":671,"date":672,"series":666,"seriesOrder":673},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-27","软件分析与设计笔记 27：Paper 1 应试：从读案例到交卷的一次完整演算","拿一份完整的案例，从头到尾走一遍：怎么读案例列角色、怎么在四个小问之间分配时间、每一张图从哪一句话推出来、两张表怎么填、交卷前拿什么清单自查。附 C25 真题与样卷的题型分值对照。","2026-11-18",27,{"path":675,"title":676,"description":677,"date":678,"series":666,"seriesOrder":679},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-26","软件分析与设计笔记 26：总结：把整条链路串起来","系列收尾：从需求到代码的完整链路回顾、每一环的产出与验收方式、六条贯穿全系列的原则，以及一份可以直接拿去做项目自查的清单。","2026-11-17",26,{"path":681,"title":682,"description":683,"date":684,"series":666,"seriesOrder":685},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-25","软件分析与设计笔记 25：代码重构：坏味道与手法","重构不改变外部行为、只改善内部结构：四种常见坏味道与对应手法、为什么动手之前必须先有测试、什么时候该重构，以及重构和前面那些设计模型是什么关系。","2026-11-16",25,{"path":687,"title":688,"description":689,"date":690,"series":666,"seriesOrder":691},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-24","软件分析与设计笔记 24：设计原则：内聚、耦合与多态","好设计怎么衡量：内聚与耦合分别在说什么、一次从「差设计」到「多态重设计」的完整对照、抽象类与接口的选择依据，以及复用为什么会从优势变成风险。","2026-11-15",24,{"path":693,"title":694,"description":695,"date":696,"series":666,"seriesOrder":697},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-23","软件分析与设计笔记 23：设计建模：从对象模型到能实现的方案","分析模型能用但还不能直接开工：对象模型怎么映射到关系模型、继承映射的三种方案怎么选、数据访问层与 Data Broker 解决什么问题，以及三层架构与 MVC 的分工。","2026-11-14",23,{"path":699,"title":700,"description":701,"date":702,"series":666,"seriesOrder":703},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-22","软件分析与设计笔记 22：分析建模：边界、实体与控制对象","不经过分析直接写代码会踩什么坑、三种分析对象各管一段、怎么用顺序图完成一次用例实现，以及从顺序图导出类的属性、操作与关系的方法。","2026-11-13",22,{"path":705,"title":706,"description":707,"date":708,"series":666,"seriesOrder":709},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-21","软件分析与设计笔记 21：UML：类图与顺序图","为什么需要一种共同的画法：类符号三格怎么画、五种关系的符号与设计含义、每种关系落到 Java 是什么写法，顺序图的三要素怎么摆；以及这三种最容易找不到的符号在 draw.io 里各搜什么词。","2026-11-12",21,{"path":711,"title":712,"description":713,"date":714,"series":666,"seriesOrder":715},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-20","软件分析与设计笔记 20：面向对象概念：对象、关系与多态","面向对象不是「用某个语言写代码」：对象与类的区别、封装真正在保护什么、五种关系（依赖、关联、聚合、组合、继承）各自何时用，以及多态为什么能减少条件判断。","2026-11-11",20,{"path":717,"title":718,"description":719,"date":720,"series":666,"seriesOrder":721},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-19","软件分析与设计笔记 19：规范化与逻辑数据模型","一次改地址引发的数据不一致，讲清规范化的真正动机；UNF 到 3NF 每一步在解决什么问题，派生字段为什么不能存，优化为什么和规范化方向相反，以及逻辑数据模型在 3NF 之上补了什么。","2026-11-10",19,{"path":723,"title":724,"description":725,"date":726,"series":666,"seriesOrder":727},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-18","软件分析与设计笔记 18：数据库分析：实体、关系与数据字典","为什么不能拿到需求就动手建表：实体与关系怎么判定、基数为什么必须由业务方确认、数据命名要遵守什么规则，以及数据字典四列里最容易被空着的那一列。","2026-11-09",18,{"path":729,"title":730,"description":731,"date":732,"series":666,"seriesOrder":733},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-17","软件分析与设计笔记 17：用生成式 AI 做设计与开发：能用的场景与要防的坑","生成式 AI 在工作流里真正站得住的三个场景 —— 造示例数据、解释陌生代码、起草初稿；它为什么会复现社会偏见、为什么会编得像真的，以及哪些内容绝不能直接采用。","2026-11-08",17,{"path":735,"title":736,"description":737,"date":738,"series":666,"seriesOrder":739},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-16","软件分析与设计笔记 16：从 persona 到 URS：一份交付物的完整骨架","把前面十几篇串成一份能交出去的东西：用户需求规格说明书的九个部分、每一章来自哪个环节、由谁确认，以及面向决策者的提案该讲清哪三件事。","2026-11-07",16,{"path":741,"title":742,"description":743,"date":744,"series":666,"seriesOrder":745},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-15","软件分析与设计笔记 15：非功能需求：把「快、稳、安全」变成数字","为什么「系统要快」不是一条需求：非功能需求怎么量化，决定性能的用户量、交易量、数据量三张表怎么估，安全需求要写清什么，以及可靠性的「不可用」该怎么定义。","2026-11-06",15,{"path":747,"title":748,"description":749,"date":750,"series":666,"seriesOrder":751},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-14","软件分析与设计笔记 14：软件测试：层级、方法与等价类划分","「我们测过了」这句话问题在哪：为什么静态评审和动态测试缺一不可，五个测试层级各自验证什么，白盒与黑盒的差别，以及用等价类划分和边界值把无限输入变成有限用例的方法。","2026-11-05",14,{"path":753,"title":754,"description":755,"date":756,"series":666,"seriesOrder":757},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-13","软件分析与设计笔记 13：需求获取：五种调查方法与一场访谈","需求从哪里来：五种事实调查方法各自适合回答什么、代价是什么，访谈从准备到记录的全过程，问卷设计里最容易犯的错，以及访谈记录必须写下来的那几项信息。","2026-11-04",13,{"path":759,"title":760,"description":761,"date":762,"series":666,"seriesOrder":763},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-12","软件分析与设计笔记 12：前端设计：把流程变成屏幕","界面设计不是「画得好看」：从活动图走到屏幕的三步，CRUD 任务流怎么当检查表，界面必须回答的三个问题，信息架构与五种导航类型，视觉一致性与留白，以及移动端与 Web 端的差别。","2026-11-03",12,{"path":765,"title":766,"description":767,"date":768,"series":666,"seriesOrder":769},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-11","软件分析与设计笔记 11：Agentic AI 与业务流程自动化","AI agent 到底是什么：五项能力与四个核心组件，什么场景该用定时任务、什么该用程序、什么才值得用 agent，两种实现路径的差别，必须提前防住的四类失败模式，以及设计方法从提示词到编排的演进。","2026-11-02",11,{"path":771,"title":772,"description":773,"date":774,"series":666,"seriesOrder":775},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-10","软件分析与设计笔记 10：精炼用例模型：include、extend 与泛化","三种精炼用例关系的判断标准：include 什么时候用、它和 extend 的区别到底在哪、参与者泛化与用例泛化各解决什么问题，以及精炼到什么程度就该停手。","2026-11-01",10,{"path":777,"title":778,"description":779,"date":780,"series":666,"seriesOrder":781},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-09","软件分析与设计笔记 09：功能需求（二）：从流程到业务实体","活动图画完之后，怎么从流程里筛出真正的业务实体：三条判断标准、哪些名词其实不该建实体、属性从哪里来，以及领域模型和后面的数据模型分别负责什么。","2026-10-31",9,{"path":783,"title":784,"description":785,"date":786,"series":666,"seriesOrder":787},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-08","软件分析与设计笔记 08：功能需求（一）：用例模型与活动图","从用户故事到用例的翻译过程：什么才算「好」的参与者，系统边界怎么划，用例描述必须写清哪四件事，活动图怎么把分支、并行与泳道画清楚，以及这两个图在 draw.io 里各用哪个形状、最容易画错哪一笔。","2026-10-30",8,{"path":789,"title":790,"description":791,"date":792,"series":666,"seriesOrder":793},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-07","软件分析与设计笔记 07：用户故事：把需求写成可验收的一句话","用户故事的三段结构，怎么从用户画像和数据地图里把它提取出来，一条故事多大算合适、时序为什么也是需求的一部分，以及验收标准怎么写才算真的可验收。","2026-10-29",7,{"path":795,"title":796,"description":797,"date":798,"series":666,"seriesOrder":799},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-06","软件分析与设计笔记 06：范围界定（数据侧）：用数据校验你的判断","访谈结论和数字对不上时该怎么办：分析的四个层次分别在回答什么问题、为什么不能跳级、数据准备与搜集怎么做成一张应用地图，以及数据最容易在哪几个地方骗你。","2026-10-28",6,{"path":801,"title":802,"description":803,"date":804,"series":666,"seriesOrder":414},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-05","软件分析与设计笔记 05：范围界定（用户侧）：用户画像与客户旅程图","为什么「所有用户」是一个陷阱，项目边界该怎么划，用户画像要写哪五个要素、最容易写成什么废纸，客户旅程图怎么把阶段、想法和情绪画在同一张纸上，以及怎么从这两样东西一步步推到可验证的需求。","2026-10-27",{"path":806,"title":807,"description":808,"date":809,"series":666,"seriesOrder":321},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-04","软件分析与设计笔记 04：接手陌生案例的第一步：三问与一张表","拿到一个完全陌生的业务案例，怎么从零开始不跑偏：只问 Who、What、Why 三个问题，把「问题—事实—假设—理由」记成一张四列表，说清为什么假设必须写明理由，以及带着问题进访谈为什么比空手去有效得多。","2026-10-26",{"path":811,"title":812,"description":813,"date":814,"series":666,"seriesOrder":55},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-03","软件分析与设计笔记 03：Agile 与 Scrum：迭代、角色与产出物","从「三周做完交付，客户说这不是我要的」讲起，说清瀑布式与迭代式的根本差别，Scrum 的三个角色和三种产出物，一个 sprint 里四次固定活动各自在解决什么问题，以及敏捷里最常见的几个误解。","2026-10-25",{"path":816,"title":817,"description":818,"date":819,"series":666,"seriesOrder":49},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-02","软件分析与设计笔记 02：设计思维、用户驱动与数据驱动","从「客服要一个能一次看完所有排期的界面」这个翻车案例讲起，说清设计思维到底是什么、用户驱动与数据驱动各自能看见什么又看不见什么、为什么真正的落点是把两者合起来的 data-informed design，以及访谈中怎么问出有用的信息。","2026-10-24",{"path":821,"title":822,"description":823,"date":824,"series":666,"seriesOrder":42},"\u002Fposts\u002Fswdesign\u002Fsw-design-notes-01","软件分析与设计笔记 01：课程地图与从需求到设计的主干","这一篇不写具体方法，先把整条链路铺开：软件分析与设计到底要解决什么问题，从需求到设计分成哪两段，中间有哪十几个环节，一份完整的交付物里应该有什么，以及后面 27 篇笔记怎么排、新人该按什么顺序读。","2026-10-23",{"path":826,"title":827,"description":828,"date":829,"series":830,"seriesOrder":42},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-01","Spring 学习笔记 01：IoC、依赖注入与第一个 Spring Boot 应用","从「手写 new 出来的三层结构」的痛点讲起，说清 IoC 容器、Bean 与依赖注入是怎么回事，再用 Maven 与 Spring Initializr 跑起第一个能返回 JSON 的应用。","2026-10-15","Spring 学习笔记",{"path":832,"title":833,"description":834,"date":829,"series":830,"seriesOrder":49},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-02","Spring 学习笔记 02：Spring Data JPA 基础——实体映射与 Repository","用 ORM 把类映射到表：@Entity、@Id、@GeneratedValue 怎么用，CrudRepository 三层接口怎么选，H2 与 MySQL 怎么配，以及 ddl-auto 到底该写哪个值。",{"path":836,"title":837,"description":838,"date":829,"series":830,"seriesOrder":55},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-03","Spring 学习笔记 03：JPA 查询——派生方法、JPQL 与分页排序","Repository 自带的方法只够按主键查，这篇讲三种自己造查询的方式：方法名派生、@Query 写 JPQL、原生 SQL，以及 Pageable 分页排序和投影返回。",{"path":840,"title":841,"description":842,"date":829,"series":830,"seriesOrder":321},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-04","Spring 学习笔记 04：JPA 关联映射与仓储测试","一对多、多对多怎么映射，谁负责维护外键，FetchType 与 CascadeType 该怎么选，顺带用 @DataJpaTest 与 AssertJ 把仓储层测起来。",{"path":844,"title":845,"description":846,"date":829,"series":830,"seriesOrder":414},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-05","Spring 学习笔记 05：Spring MVC 与 Thymeleaf 入门","一次页面请求在 Spring MVC 里走了哪几步，@Controller 怎么把数据交给模板，@PathVariable 与 @RequestParam 怎么取参数，以及控制器为什么必须是无状态的。",{"path":848,"title":849,"description":850,"date":829,"series":830,"seriesOrder":799},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-06","Spring 学习笔记 06：表单绑定与服务端校验","把表单字段绑到对象上，用 Bean Validation 注解做服务端校验，把错误信息显示回用户刚填的那一页，再补上自定义校验注解与全局异常处理。",{"path":852,"title":853,"description":854,"date":829,"series":830,"seriesOrder":793},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-07","Spring 学习笔记 07：Thymeleaf 片段复用与国际化","用 th:fragment 与 th:insert\u002Fth:replace 把导航栏、页脚抽成片段，页面套用统一布局，再用 messages.properties 与 LocaleResolver 做中英文切换。",{"path":856,"title":857,"description":858,"date":829,"series":830,"seriesOrder":787},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-08","Spring 学习笔记 08：HTTP Session 与会话状态管理","HTTP 无状态带来的问题，Cookie 与 Session 怎么分工，Spring 里读写会话的几种方式，以及会话固定、超时、多实例共享这些必须想清楚的事。",{"path":860,"title":861,"description":862,"date":829,"series":830,"seriesOrder":781},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-09","Spring 学习笔记 09：拦截器 HandlerInterceptor","登录检查、权限判断、请求耗时统计这类横切逻辑该放哪：HandlerInterceptor 的三个回调各在什么时机执行，怎么注册与排除路径，以及它和过滤器的分工。",{"path":864,"title":865,"description":866,"date":829,"series":830,"seriesOrder":775},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-10","Spring 学习笔记 10：Service 层与事务","一组数据库操作要么全成功要么全失败，靠 @Transactional 怎么做到；传播行为、隔离级别、回滚规则怎么选，以及自调用失效、乐观锁悲观锁这些实战里的坑。",{"path":868,"title":869,"description":870,"date":829,"series":830,"seriesOrder":769},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-11","Spring 学习笔记 11：REST API 基础——把 Service 暴露成接口","同一套 Service 怎么同时服务页面和客户端：@RestController 的路由与方法语义、状态码怎么给、DTO 怎么定，以及 MockMvc 端到端和切片测试的两种写法与各自的坑。",{"path":872,"title":873,"description":874,"date":829,"series":830,"seriesOrder":763},"\u002Fposts\u002Fjavaspring\u002Fspring-notes-12","Spring 学习笔记 12：REST 进阶——版本、更新、跨域与文档化","接口能跑通之后要处理的几件事：URL 与响应结构怎么定、版本怎么演进、更新怎么做到可安全重试、CORS 怎么配、HATEOAS 与 Spring Data REST 该不该用。",{"path":876,"title":877,"description":878,"date":879,"series":880,"seriesOrder":321},"\u002Fposts\u002Fjava\u002Fjava-functionalprogramming-notes","Java 函数式编程笔记：Lambda、函数式接口与 Streams","学习 Java 函数式编程时的个人笔记：Lambda 表达式的五步简写与方法引用、常见函数式接口、Stream 流水线与惰性求值，以及创建流、中间操作、终止操作与收集器的用法。示例代码均为自写，运行结果来自本地实测。","2026-10-13","Java 学习笔记",{"path":882,"title":883,"description":884,"date":879,"series":880,"seriesOrder":55},"\u002Fposts\u002Fjava\u002Fjava-generics-notes","Java 泛型笔记：泛型方法、有界类型与泛型类","学习 Java 泛型时的个人笔记：从重复的重载方法与多态尝试讲起，再到泛型方法与类型推断、有界泛型类型、Comparable 与 Number 边界，以及泛型类在集合中的用法。示例代码均为自写，运行结果来自本地实测。",{"path":886,"title":887,"description":888,"date":889,"series":890,"seriesOrder":321},"\u002Fposts\u002Fmysql\u002Fmysql-learning-04","MySQL 学习笔记 04：数据操纵（增删改）","MySQL 学习笔记第四篇：INSERT 插入（含批量插入与 INSERT ... SELECT）、UPDATE 更新、DELETE 删除，以及各自的坑。","2026-10-10","SQL 学习笔记",{"path":892,"title":893,"description":894,"date":889,"series":890,"seriesOrder":414},"\u002Fposts\u002Fmysql\u002Fmysql-learning-05","MySQL 学习笔记 05：DDL 概览","MySQL 学习笔记第五篇：数据定义语言概览——Schema、Table、View、Index、Constraints 这几类对象分别对应哪些 CREATE \u002F ALTER \u002F DROP 命令。",{"path":896,"title":897,"description":898,"date":889,"series":890,"seriesOrder":799},"\u002Fposts\u002Fmysql\u002Fmysql-learning-06","MySQL 学习笔记 06：CREATE TABLE 与数据类型","MySQL 学习笔记第六篇：CREATE TABLE 的完整语法、常用数据类型的选型建议，以及外键的两种定义方式。",{"path":900,"title":901,"description":902,"date":889,"series":890,"seriesOrder":793},"\u002Fposts\u002Fmysql\u002Fmysql-learning-07","MySQL 学习笔记 07：索引","MySQL 学习笔记第七篇：索引的作用与 B+ 树结构、单列与复合索引的创建、索引的代价与适用场景。",{"path":904,"title":905,"description":906,"date":889,"series":890,"seriesOrder":787},"\u002Fposts\u002Fmysql\u002Fmysql-learning-08","MySQL 学习笔记 08：DROP 与 ALTER","MySQL 学习笔记第八篇：DROP 删除数据库对象、ALTER 修改表结构，以及常见的坑。",{"path":908,"title":909,"description":910,"date":889,"series":890,"seriesOrder":781},"\u002Fposts\u002Fmysql\u002Fmysql-learning-09","MySQL 学习笔记 09：约束与数据完整性","MySQL 学习笔记第九篇：SQL 约束——NOT NULL、CHECK、PRIMARY KEY、FOREIGN KEY 等如何保证数据完整性，以及它们的对比。",{"path":912,"title":913,"description":914,"date":889,"series":890,"seriesOrder":775},"\u002Fposts\u002Fmysql\u002Fmysql-learning-10","MySQL 学习笔记 10：视图","MySQL 学习笔记第十篇：视图（Views）的定义与特性、和表的对比、创建与使用，以及可更新视图的限制。",{"path":916,"title":917,"description":918,"date":889,"series":890,"seriesOrder":769},"\u002Fposts\u002Fmysql\u002Fmysql-learning-11","MySQL 学习笔记 11：存储过程","MySQL 学习笔记第十一篇：存储过程（Stored Procedures）的概念、创建与调用、带参数的写法，以及优缺点。",{"path":920,"title":921,"description":922,"date":923,"series":890,"seriesOrder":42},"\u002Fposts\u002Fmysql\u002Fmysql-learning-01","MySQL 学习笔记 01：MySQL 基础知识","MySQL 学习笔记第一篇：MySQL Server 与 Workbench 的安装，数据库与 DBMS 的基本概念，关系模型、ACID 事务、常见数据类型，以及后续的学习路线。","2026-10-09",{"path":925,"title":926,"description":927,"date":923,"series":890,"seriesOrder":49},"\u002Fposts\u002Fmysql\u002Fmysql-learning-02","MySQL 学习笔记 02：SELECT 查询与过滤","MySQL 学习笔记第二篇：SELECT 的基本语法与逻辑执行顺序，WHERE 过滤（比较、LIKE、IN、BETWEEN、NULL）、各种 JOIN、UNION 与子查询。",{"path":929,"title":930,"description":931,"date":923,"series":890,"seriesOrder":55},"\u002Fposts\u002Fmysql\u002Fmysql-learning-03","MySQL 学习笔记 03：聚合、分组与输出控制","MySQL 学习笔记第三篇：COUNT\u002FSUM\u002FAVG 等聚合函数、GROUP BY 分组、HAVING 过滤、ORDER BY 与 LIMIT，以及一条 SELECT 的完整逻辑执行顺序。",{"path":933,"title":934,"description":935,"date":936,"series":880,"seriesOrder":49},"\u002Fposts\u002Fjava\u002Fjava-oop-notes","Java 面向对象笔记：类、继承、多态与异常","学习 Java 面向对象编程时的个人笔记：类与对象、封装与访问修饰符、继承与多态、集合、抽象类与接口、异常处理。示例代码均为自写，运行结果来自本地实测。","2026-10-06",{"path":938,"title":939,"description":940,"date":941,"series":880,"seriesOrder":42},"\u002Fposts\u002Fjava\u002Fjava-basics-notes","Java 基础语法笔记：从环境安装到方法与数组","学习 Java 基础语法时的个人笔记：JDK 安装、输入输出、变量与运算符、条件与循环、字符串、数组与方法。示例代码均为自写，运行结果来自本地实测。","2026-10-05",{"path":943,"title":944,"description":945,"date":648,"series":946,"seriesOrder":42},"\u002Fposts\u002Fgit\u002Fgit-install-and-basics","Git 安装与基本使用","从装好 Git 到跑通日常提交流程，把最常用的几条命令和它们背后的三个区域讲清楚。","Git 入门",{"path":948,"title":949,"description":950,"date":648,"series":946,"seriesOrder":49},"\u002Fposts\u002Fgit\u002Flocal-remote-repository","本地远程仓库的部署","用自己的机器当 Git 服务器：建一个裸仓库、走 SSH 连上去，把本地提交推上去。",{"path":952,"title":953,"description":954,"date":648,"series":654,"seriesOrder":42},"\u002Fposts\u002Fguide\u002Fguide-file-layout","文件都放在哪","文章、图片、封面分别放在仓库的什么位置，哪些目录可以放手改、哪些碰了会出问题。",{"path":956,"title":957,"description":958,"date":648,"series":654,"seriesOrder":49},"\u002Fposts\u002Fguide\u002Fguide-frontmatter","frontmatter 每个字段是什么意思","文章开头那段被横线包住的字段，逐个说明作用、默认行为和写错的后果。",{"path":652,"title":5,"description":649,"date":648,"series":654,"seriesOrder":55},1793268151021]