<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/scripts/pretty-feed-v3.xsl" type="text/xsl"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:h="http://www.w3.org/TR/html4/"><channel><title>WWWeeds&apos; blog</title><description>向无聊宣战</description><link>https://ww-weeds.xyz</link><item><title>杠杆ETF浅析</title><link>https://ww-weeds.xyz/blog/%E6%9D%A0%E6%9D%86etf%E6%B5%85%E6%9E%90</link><guid isPermaLink="true">https://ww-weeds.xyz/blog/%E6%9D%A0%E6%9D%86etf%E6%B5%85%E6%9E%90</guid><description>杀人以梃与刃，有以异乎？</description><pubDate>Wed, 14 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;为了便于叙述，下文均以 TQQQ 作为例子。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;杠杆 ETF 是什么&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;TQQQ 是 QQQ 的三倍日内杠杆 ETF。&lt;/p&gt;
&lt;p&gt;涨跌为 QQQ 每天涨跌的 3 倍。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;与融资融券的比较&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;暂时把融资融券的利息放在一边，对比一下 TQQQ 与借来三倍资金购买 QQQ。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;单边市中，TQQQ 具有较为显著的优势。&lt;/p&gt;
&lt;p&gt;在单边上涨中，TQQQ 涨幅更大。&lt;/p&gt;
&lt;p&gt;第一日，TQQQ 资金为 100x，QQQ 资金为 300x，前者涨幅 3%，后者涨幅 1%。&lt;/p&gt;
&lt;p&gt;第二日，TQQQ 资金为 103x，QQQ 资金为 303x。&lt;/p&gt;
&lt;p&gt;TQQQ / QQQ &gt; 1 / 3，次日涨幅会被扩大。&lt;/p&gt;
&lt;p&gt;单边下跌中，三倍做 QQQ 被扫止损更快。&lt;/p&gt;
&lt;p&gt;第一日，TQQQ 资金为 100x，QQQ 资金为 300x，前者跌幅 3%，后者跌幅 1%。&lt;/p&gt;
&lt;p&gt;第二日，TQQQ 资金为 97x，QQQ 资金为 297x。&lt;/p&gt;
&lt;p&gt;TQQQ / QQQ &amp;#x3C; 1 / 3，次日跌幅会被减小。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;震荡市中，TQQQ 因为平方差公式 (1 + x)(1 - x) = 1 - x^2 导致的损耗磨损被杠杆放大了 9 倍。劣势非常大。&lt;/p&gt;
&lt;p&gt;TQQQ 首日 100x，跌 10%，剩余 90x。&lt;/p&gt;
&lt;p&gt;次日涨 10%，剩余 99x。&lt;/p&gt;
&lt;p&gt;损耗已经到达了 1%，且这个损耗与涨跌先后没有关系，震荡就会损耗。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;融资融券有 5% 以上的利息，TQQQ 有年 1% 的管理费。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;为什么用杠杆&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;为了在不提升资金总量的情况下放大收益。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;关于风险&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;风险当然会增高，但是比起去购买我根本不懂的板块题材，在我确实有所理解的大盘指数上加少量杠杆，更加靠近我的能力圈。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;关于磨损&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;买美股买的就是单边市，如果不再单边了，它也到头了。&lt;/p&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>简单的技术指标择时</title><link>https://ww-weeds.xyz/blog/%E7%AE%80%E5%8D%95%E7%9A%84%E6%8A%80%E6%9C%AF%E6%8C%87%E6%A0%87%E6%8B%A9%E6%97%B6</link><guid isPermaLink="true">https://ww-weeds.xyz/blog/%E7%AE%80%E5%8D%95%E7%9A%84%E6%8A%80%E6%9C%AF%E6%8C%87%E6%A0%87%E6%8B%A9%E6%97%B6</guid><description>聊以自娱也</description><pubDate>Wed, 14 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;大思路是：周 K 定买卖，日 K 定点。&lt;/p&gt;
&lt;p&gt;选取 MACD + BOLL。RSI 和 MACD 重叠，就不看了。&lt;/p&gt;
&lt;p&gt;大略择时，不求精确，让资金不空置更为重要。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;基本原理&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;正态分布决定 BOLL 通道内运行的概率 &gt; 95%。&lt;/li&gt;
&lt;li&gt;MACD 的峰谷往往对应价格的峰谷&lt;/li&gt;
&lt;li&gt;MACD 的单峰单谷形态较多。&lt;/li&gt;
&lt;li&gt;周 K 的合力更显然，噪音显著比日 K 更小。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;具体手法&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;周 K BOLL 中轨下 MACD 反转时可买。&lt;/p&gt;
&lt;p&gt;周 K BOLL 上轨且 MACD 回落可卖。&lt;/p&gt;
&lt;p&gt;日 K BOLL 非上轨，MACD 反转买入。&lt;/p&gt;
&lt;p&gt;日 K BOLL 上轨且 MACD 回落卖出。&lt;/p&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>资产配置策略总纲2026</title><link>https://ww-weeds.xyz/blog/%E8%B5%84%E4%BA%A7%E9%85%8D%E7%BD%AE%E7%AD%96%E7%95%A5%E6%80%BB%E7%BA%B22026</link><guid isPermaLink="true">https://ww-weeds.xyz/blog/%E8%B5%84%E4%BA%A7%E9%85%8D%E7%BD%AE%E7%AD%96%E7%95%A5%E6%80%BB%E7%BA%B22026</guid><description>戒贪戒躁，快乐唯知足而已</description><pubDate>Wed, 14 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;上一篇资产配置的配比，美股配比过高，长债表现不佳且购买渠道受限，又经过数月股海沉浮，现理财投资策略如下。如无意外，这就会是我自己未来实际投入大笔资金的第一版策略了。&lt;/p&gt;
&lt;h2&gt;配置比例&lt;/h2&gt;
&lt;p&gt;美股资产：&lt;/p&gt;
&lt;p&gt;QQQ - 20%&lt;/p&gt;
&lt;p&gt;TQQQ - 10%&lt;/p&gt;
&lt;p&gt;A 股牛市资产（上证估值上升的时间区间）：&lt;/p&gt;
&lt;p&gt;创业板 - 50%&lt;/p&gt;
&lt;p&gt;A股熊市资产（上证估值下降的时间区间）：&lt;/p&gt;
&lt;p&gt;高股息个股 - 30%&lt;/p&gt;
&lt;p&gt;红利低波 ETF A - 10%&lt;/p&gt;
&lt;p&gt;红利低波 ETF 港 - 10%&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;牛市止盈后即进入熊市逻辑。&lt;/p&gt;
&lt;p&gt;在上证、创业板估值到达十年 30 百分位以下，进入牛市逻辑。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;抗通胀资产：&lt;/p&gt;
&lt;p&gt;黄金 - 10%&lt;/p&gt;
&lt;p&gt;bitCoin - 10%&lt;/p&gt;
&lt;p&gt;每年再平衡一次。&lt;/p&gt;
&lt;h2&gt;投资逻辑&lt;/h2&gt;
&lt;h3&gt;美股资产&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;持仓前提&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;纳斯达克估值很高，但是涨得很好，一山更有一山高。既相信，又做好后手，于是就有了这 30% 的美股持仓。&lt;/p&gt;
&lt;p&gt;它充当的就是进攻角色，纳斯达克拥有世界上最好的科技股，在其他配置中不需要再考虑热点题材了。&lt;/p&gt;
&lt;p&gt;其中一半的 TQQQ 就是为了在有限的仓位下通过杠杆来增加收益。&lt;/p&gt;
&lt;p&gt;详细的可以看另一篇：&lt;a href=&quot;https://zhuanlan.zhihu.com/p/1994852051621017545&quot;&gt;杠杆 ETF 浅析&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;具体手法&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;不择时定投 + 每年再平衡。&lt;/p&gt;
&lt;p&gt;每年再平衡可以在上涨年份降低总体杠杆，下跌年份增加总体杠杆。经过回测，近 15 年的数据，每半年或是每年再平衡的收益差距并不大，不妨选择不那么麻烦的，毕竟 TQQQ 的投资并不省事。&lt;/p&gt;
&lt;h3&gt;A 股牛市资产&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;持仓前提&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;不选板块、行业，因为我根本不懂。大盘没有价值陷阱，低估就是低估，低估总会有一天反弹。所以低估就拿好股指，不低估就不买。&lt;/p&gt;
&lt;p&gt;估值正常了就卖掉，现金一部分进红利，一部分拿来做 T，一方面是半高不高的总会震荡，尝试赚点差价，一方面是满足自己的操作欲望。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;具体手法&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在估值 30 以下不择时定投。一半创业板 ETF，一半 XL二博时中创业，即两倍做多创业板。&lt;/p&gt;
&lt;p&gt;估值 50 以上停止定投，止盈 1/3。&lt;/p&gt;
&lt;p&gt;估值 70 再度止盈 1/3（即现有持仓的一半）。&lt;/p&gt;
&lt;p&gt;估值 90 全部止盈。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;创业板估值不建议看 PE 百分位，我选择的是有知有行温度计。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在估值 50 ~ 90 时，止盈出来的资金，一半直接进入红利仓位，另一半用于择时做 T，操作手法可参考另一篇：&lt;a href=&quot;https://zhuanlan.zhihu.com/p/1994852392836027697&quot;&gt;简单的技术指标择时&lt;/a&gt;。标的为两倍做多创业板。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;要说为什么不拿到估值 90 再全部止盈，如果你确实严格执行了策略，有丰厚的利润垫，那么完全可以在估值 70、80、90 时止盈。&lt;/p&gt;
&lt;p&gt;我今年有两次操作失误，导致创业板利润垫非常薄，所以需要早止盈提升信心。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;A 股熊市资产&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;持仓前提&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;本策略的前提就是我根本不懂行业，更不可能懂个股公司。在大盘不低估的时候，我不知道该买什么，但为了资金不空置，我又确实得买点啥。所以我能参考的价值锚只有股息，只有现金分红。&lt;/p&gt;
&lt;p&gt;所以我的策略就是围绕着吃股息，一切操作都是为了提高我的预期股息率，辅助一点价值回归。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;具体手法&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;红利 ETF 择时定投。&lt;/p&gt;
&lt;p&gt;个股先通过基本面选标的：股息率 &gt; 6%，市盈率在 0 ~ 18，净利润三年净增长率 &gt; 0，市值 &gt; 300 亿。推荐使用东方财富。&lt;/p&gt;
&lt;p&gt;然后再筛，浅看一下行业是否具有周期性，看一下财报，这里分析的目的只有一个：公司能否持续分红，未来盈利羸弱导致降低股息可能性大不大，有增长当然更好，然而这往往不可强求，也没法预判。&lt;/p&gt;
&lt;p&gt;每个行业只留一个标的。&lt;/p&gt;
&lt;p&gt;选好标的之后就是具体投资，同时持股不要超过 3 个。&lt;/p&gt;
&lt;p&gt;利用 MA120 和周 K BOLL + MACD 制定买入卖出决策，利用日 K BOLL + MACD 决定具体买卖点。&lt;/p&gt;
&lt;p&gt;记住一件事：所有的操作只是为了更高的股息。&lt;/p&gt;
&lt;p&gt;账上不要留有任何现金。&lt;/p&gt;
&lt;h2&gt;抗通胀资产&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;持仓前提&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;降息宽松是主流，所以稍微多配置一些。像美股一样做就好了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;具体手法&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;不择时定投。优先级最低。优先配低估指数资产，再然后是红利生息资产，最后剩的买抗通胀资产。&lt;/p&gt;
&lt;h2&gt;新增流动资金&lt;/h2&gt;
&lt;p&gt;如果出现：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;QQQ 估值低于 30 百分位，或者高位下跌 20% 以上。&lt;/li&gt;
&lt;li&gt;创业板估值低于 30 百分位。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;两种情况任一，则全部新增资金投入这两个资产。留待第二年再做平衡。&lt;/p&gt;
&lt;h2&gt;为什么不留现金&lt;/h2&gt;
&lt;p&gt;知乎 Mr.Dang 老师的一段话让我醍醐灌顶：&lt;/p&gt;
&lt;p&gt;只有可以持续产生现金流的生产资料才是财富。&lt;/p&gt;
&lt;p&gt;原文：https://zhuanlan.zhihu.com/p/1985014767308531703&lt;/p&gt;
&lt;p&gt;这样一来，积累财富不留现金也就非常合理了。&lt;/p&gt;
&lt;p&gt;当然，应急资金另说，但那不需要占总资产的百分比，一个定额即可。&lt;/p&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>决策的三条建议兼2025秋招反思</title><link>https://ww-weeds.xyz/blog/%E5%86%B3%E7%AD%96---%E7%A7%8B%E6%8B%9B%E5%8F%8D%E6%80%9D</link><guid isPermaLink="true">https://ww-weeds.xyz/blog/%E5%86%B3%E7%AD%96---%E7%A7%8B%E6%8B%9B%E5%8F%8D%E6%80%9D</guid><description>后视镜看到的世界总是不太正确</description><pubDate>Fri, 07 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;日常问题&lt;/h2&gt;
&lt;p&gt;决策是一个极其困扰现代人的问题，至少极为困扰我。&lt;/p&gt;
&lt;p&gt;小到去哪里吃饭，周末做什么；大到就业入职，婚姻生育。这些决策深刻地影响着生活质量，“如何决策”是现代人必须要面对的问题。&lt;/p&gt;
&lt;h2&gt;如何决策&lt;/h2&gt;
&lt;h3&gt;理论总结&lt;/h3&gt;
&lt;p&gt;核心在于两个部分：决策之前，如何提高决策的质量（提升胜率）？决策之后，如何反思决策，提高下一次的决策质量（加速迭代）？&lt;/p&gt;
&lt;p&gt;还有一个附带问题：如何减缓选择困难。&lt;/p&gt;
&lt;p&gt;牢记下面这三句话：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;决策结果不代表决策质量。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;区分重要事件与非重要事件。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;实践优于数据，数据优于评价。&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;下面一一解释。&lt;/p&gt;
&lt;p&gt;“决策结果不代表决策质量”。90%概率获胜的决策，仍然有 10% 的概率会输，假如我们运气不好输了，不能责怪自己“要是不这么决策就好了”，因为从决策质量上看这是一个非常棒的决策。“非战之过也”，不外如是。反之亦然，一个获胜概率 10% 的孤注一掷，即使胜利了也应该后怕，而不是得意。&lt;strong&gt;永远不要从后视镜看自己的决策。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;“区分重要事件与非重要事件”。每一个当下都很重要，但是“今天中午吃什么”和“我要去哪里工作”显然重要性不相等。而”我去哪里工作“和”我和谁结婚“的重要性则略显模糊。那么如何给所有的决策都取一个量化指标用来评价它的重要性？答案在于这个决策对你的生活的影响持续时长。“中午吃什么”的影响最多延宕一周，再难吃的东西，也不会让你在一周后吃午饭时吐出来，“择业”的影响，则影响 5 ~ 10 年（一个经济周期的长度，参考 A 股指数）。根据决策的不同重要性，我们可以采取激进或保守的策略。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;”吃什么“是不太重要的决策，那么就可以很随意，吃昨天吃过的，吃街边左手侧第三家店，吃xx软件推荐榜第2名，都可以。不妨尝试些新东西，因为成本很低。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;“实践优于数据，数据优于评价”。如果决策的每一个选项你自己都选过，那么你不会有任何犹豫，这对你就是开卷考试。但如果你没有选过，那么你就需要依靠别人的实践。别人的实践最好是量化的数据形式，比如说计算机行业应届生的平均月薪是 1.5w 元，食品销售行业应届生的平均月薪是 5k 元，在多个不同的数据源中取平均数之后仍然类似，那么这就是一个合理的决策支撑。如果没有数据，也不要流连于具体网络评价的细节。要么将网络评价转换为数据：“在关于 xx 的 100 个话题中，有 80 个是负面相关的”，要么抛硬币。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如果既没有实践，也没有数据，那么这对你无异于盲选。非重要决策可以直接抛硬币，如果是重要决策，选择最差结果更可以接受的那个。如果连最差结果也不知道，且你还必须当下就做出决策，没法调查研究，那么也抛硬币就好。&lt;/p&gt;
&lt;p&gt;值得思考的是，国内高考到填志愿一般只有 2 ~ 3 周时间。实践各种岗位是不可能的，那下降到数据层面，只有上述平均薪资这类可以量化，诸如爱好、就业环境等却很难。所以报志愿的同学们要么随大流，要么听信割韭菜的砖家，要么盲选。&lt;/p&gt;
&lt;p&gt;除了有条件的人家要尽早开始让小孩接触社会实践、金钱流动与职业内容，更多无条件的人家，则要主动培养小孩的金钱观与人生观，尽快让孩子对各种可以量化的指标有一个概念，根据数据做选择，总比根据偏见来选择更好。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;秋招反思&lt;/h3&gt;
&lt;p&gt;下面是我自己的实践环节。分析我秋招中的各个决策。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;是否保研的决策&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;选项：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;接受保研&lt;/li&gt;
&lt;li&gt;放弃保研&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;决策影响时长：10 年，属于重要决策。&lt;/p&gt;
&lt;p&gt;决策结果：决定保研之后，会略微影响实习转正，可以极大地缓和家庭矛盾，最差结果是秋招落空，保研本校。放弃保研之后，最差结果是秋招落空，前往不知名小厂工作，有极低概率灵活就业。&lt;/p&gt;
&lt;p&gt;额外影响：决定保研之后秋招成功，撕毁保研 offer 会造成本校保研名额以及个人名誉受到影响。&lt;/p&gt;
&lt;p&gt;属于重要决策，秋招成功率未知，应当优先选择最差结果更可接受的那一方。所以我应当接受保研。&lt;/p&gt;
&lt;p&gt;犯错：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;过高地衡量接受保研后又放弃的名誉影响。因为这只可能是我秋招成功进入大厂，而进入大厂后，“同校生”的人脉影响相较于体制内等较小。&lt;/li&gt;
&lt;li&gt;过高地估计秋招成功率。这是由于春招的顺利与舍友的样本，导致我错估了秋招成功率，这犯了“评价高于数据”的过错。提前收集应届毕业生人数、计算机行业的应届供需数据，这才能作为决策支撑。&lt;/li&gt;
&lt;li&gt;没有收集本校本科毕业生的平均薪资，这个数据有利于我在选择放弃保研后缓解家庭矛盾。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;扔掉后视镜：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;当时我并没有规划人生路线，还沉浸在“我喜欢或者不喜欢”，“我想要或者不想要”之类的迷思之中。犯错在所难免。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;何时进行岗位投递的决策&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;选项：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;2025.8.15 离职后立刻开始秋招。&lt;/li&gt;
&lt;li&gt;先学习以及制作 AI 相关项目，2025.9.15 时再开始秋招。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;决策影响时长：10 年，属于重要决策。&lt;/p&gt;
&lt;p&gt;决策结果：2025.8.15 离职后立刻开始秋招，更容易找到开发岗位。2025.9.15 开始秋招，有一定几率增加 AI 岗位的获得。&lt;/p&gt;
&lt;p&gt;犯错：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;错估秋招成功率，同上。&lt;/li&gt;
&lt;li&gt;错估 AI 岗位要求，AI 开发岗位不是我凭借一个略好的本科学历加上仓促完成的个人项目就可以应聘的，我应当找足量的同学历 AI 岗位应聘简历进行观察，才能做出相应的决策。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;扔掉后视镜：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;同上。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;关于秋招结果&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;虽然最终我在经历 2 个月折磨后获取了心仪的岗位 offer，但是&lt;strong&gt;决策结果不代表决策质量&lt;/strong&gt;。这无疑是一场缺乏数据的盲赌，这次我运气好，赌赢了，下一次可能就死无葬身之地了。&lt;/p&gt;
&lt;p&gt;这次终于让我感到自己成长了一点……&lt;/p&gt;
&lt;h2&gt;书籍推荐&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;《对赌（实践版）》（扑克高手带你剖析决策迷思）&lt;/li&gt;
&lt;li&gt;《自私的基因》（现存的比例实际上是自然与社会的博弈选择）&lt;/li&gt;
&lt;li&gt;《博弈与社会》（样例丰富，大开眼界）&lt;/li&gt;
&lt;li&gt;《生活不是掷骰子：理性决策的贝叶斯思维》（用贝叶斯思维优化决策，用公式替代直觉）&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;公众号推荐&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;纯牛马的救赎&lt;/li&gt;
&lt;li&gt;人间罗盘、记忆承载、记忆承载3&lt;/li&gt;
&lt;/ol&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>财富自由之路</title><link>https://ww-weeds.xyz/blog/%E7%90%86%E8%B4%A2%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0</link><guid isPermaLink="true">https://ww-weeds.xyz/blog/%E7%90%86%E8%B4%A2%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0</guid><description>承认自己的愚蠢是一种精明</description><pubDate>Thu, 09 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;策略概述&lt;/h2&gt;
&lt;p&gt;本计划面向程序员以及其他&lt;strong&gt;高薪但不可持续&lt;/strong&gt;的工薪阶层。以简单可理解的方式将财产转化为资产，并在积累一定年限后带来持续的现金流，以获得实质上的人身自由，摆脱因无法接收失业时的现金流断裂而受制于人的困扰。&lt;/p&gt;
&lt;p&gt;以大厂程序员为例，每年存款 20 万元，持续十年后将拥有本息合计 331 万元（年利率 8% ~ 10%，按 9% 计算），若此时退休，则可以每年支取 13.2 万元（4%）进行花销，平均月花销为 11000 元，资产仍然将持续增长。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;本人在二线城市杭州的生活成本约为 4000 元/ 月，300 万元的资产加上 1 万元自由可支配的现金流无疑足够一个人度过富裕且安定的生活。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;实操做法&lt;/h2&gt;
&lt;h3&gt;工作期间&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;资产配置&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;记账，记录最近 6 个月的生活实际平均开销为 x 元。&lt;/p&gt;
&lt;p&gt;开三个账户，日用账户存款 x 元，应急现款账户存款 6 * x 元，投资账户存储剩余的&lt;strong&gt;所有入账，只进不出&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;投资账户资产如下配置：&lt;/p&gt;
&lt;p&gt;20% 国债，可以购买外围基金，可以购买国债 10 年指数。&lt;/p&gt;
&lt;p&gt;10% 黄金，可以直接在支付宝购买黄金基金。&lt;/p&gt;
&lt;p&gt;60% 纳斯达克100 指数，可以在支付宝购买场外基金，但多有限额，可在场内购买ETF基金。&lt;/p&gt;
&lt;p&gt;10% 其他指数，包括创业板、A 股、北证 50、恒生科技、日经指数等，可购买场外/场内基金。&lt;/p&gt;
&lt;p&gt;本投资组合参考了 60/40（60% 标普 500 指数，40% 美国国债） 投资组合，其在 1973 ~ 2013 的 40 年数据中，年化收益率为 9.6%。额外引入的黄金是为了更多元的资产配置，而 10% 其他指数待定，另有他用。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;发薪日&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;优先填满日用账户和应急现款账户，剩余&lt;strong&gt;全部存入&lt;/strong&gt;投资账户。按比例分配。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;再平衡&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;每年一次再平衡，重新计算 x 的值，并将各资产比例复原。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;纳斯达克投资策略&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;永不止盈、估值定投、极端避险&lt;/p&gt;
&lt;p&gt;正常情况下不进行止盈与卖出操作。每月发薪时一次性买入，不要试图挑选时机。&lt;/p&gt;
&lt;p&gt;当市盈率 &gt; 35，暂停买入，持有现金或货币基金，但是一定要保证流动性。市盈率 &amp;#x3C; 25 时，将暂停买入积攒的现金买入。&lt;/p&gt;
&lt;p&gt;极端避险，这是为了规避类似 2002 互联网泡沫暴跌 80% 的情形，在下列条件全部满足时，全部卖出止盈，估值正常后重新买入。&lt;/p&gt;
&lt;p&gt;市盈率 &gt; 45 且在十年百分位 95 以上；消息面有大规模加息、市场财务造假消息频出、大规模传染病、战争爆发等。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;其他指数投资策略&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这并非是为了盈利，而是为了消耗掉个人的投机需求，令计划更可持续。对于创业板、A 股、恒生科技等指数，在市盈率十年百分位 20 以下定投，在十年百分位 85、90、95 处分别卖出 1/3 是我的投资策略。&lt;/p&gt;
&lt;p&gt;若三年内收益率表现不良，将本 10% 直接置换为纳斯达克。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;大额消费&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;对于汽车、旅游等大额消费，建议直接用应急账户 + 当月薪资/年终奖进行消费，不要动投资账户。如果实在无法覆盖，则优先卖出盈利资产，在下一个再平衡日进行平衡。但注意，这会增加计划的不稳定性。&lt;/p&gt;
&lt;h3&gt;过渡期&lt;/h3&gt;
&lt;p&gt;在计划退休时间的 3 ~ 5 年内，可以逐步将资产从股票向债券转移。逐步从 2 1 7 （债：黄金：股）转向 5 1 4，避免退休前的黑天鹅事件影响退休计划。&lt;/p&gt;
&lt;h3&gt;退休之后&lt;/h3&gt;
&lt;p&gt;主要的区别在于我们失去了持续的现金流，而且每年必须赎回一定资产用以生活，对于回撤的忍受程度大幅降低。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;资产配置&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;25% 现金/货币基金/短期国债（5年以下），要求为流动性资产&lt;/p&gt;
&lt;p&gt;25% 标普 500 指数基金&lt;/p&gt;
&lt;p&gt;25% 黄金&lt;/p&gt;
&lt;p&gt;25% 长期国债（10年以上）&lt;/p&gt;
&lt;p&gt;这是哈利布朗的永久投资组合，在 1973 ~ 2013 的 40 年历史数据回测中，最大回撤为 12.73%（同年股票下跌了 50%），年平均收益率为 8.53%。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;消费与再平衡&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;每年从现金中支取消费，每年消费额度不超过资产总数的 4%，每半年重新平衡资产比例。&lt;/p&gt;
&lt;h3&gt;关于房产&lt;/h3&gt;
&lt;p&gt;本策略中并没有配置房产的部分，首先一般意义上的学区房资产与婚姻关系强绑定，若非为了婚姻，实在没有必要加杠杆支付溢价，而如果要结婚生子，则会引入非常多的不确定因素，会给本计划的持续实施带来不可估量的影响。&lt;/p&gt;
&lt;p&gt;值得购买的房产只有一种：租售比 &gt; 6%，可以持续产生现金流收益的&lt;strong&gt;CBD/工业园区附近公寓类资产&lt;/strong&gt;。它们可以作为资产配置的一种补充，增强资产的多元和健壮性，同时是对稳定现金流的一种补充。&lt;/p&gt;
&lt;h2&gt;策略执行核心&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;不要负债，尤其是大规模的房贷，对于一个无法产生现金流的资产，还要加上机会成本。每年的房贷相当于损失了&lt;strong&gt;房贷利率 + 投资收益 - 通货膨胀&lt;/strong&gt;的潜在利润，这对于财富积累是非常大的损失。&lt;/li&gt;
&lt;li&gt;承认自己的愚蠢，不要试图猜测指数基金的涨跌，估值的高低顶多决定定投与否，在一切非极端情况下（如 2002 互联网泡沫，市盈率 100 倍以上），绝不卖出止盈，绝不试图抄底、逃顶。&lt;/li&gt;
&lt;li&gt;记账，把握自己的月支出。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;为什么有效&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;高薪存在红利&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;年存款 20 万元以上对于大部分个人来说是无法达到的，仅仅少数工薪阶层可以完成。这条路不是拥挤的，门槛并不低平。红利会消失，必须尽快将现金置换为资产。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;蠢的人没有这么聪明的，聪明的人没有这么蠢的&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;对于缺乏财务常识，或者被二十年房地产迷昏了头脑的人来说，要将绝大部分身家压在股市是难以想象的。而对于了解各大股市，明白市场的逻辑与原理的人来说，又总被连续涨停、半年翻倍的财富神话所绑架，总希望凭借自己的操作与聪明才智战胜市场、收割韭菜，但我只想赚取企业增长的利润。&lt;/p&gt;
&lt;p&gt;知易行难，能否忍住十年如一？&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;下图是支付宝内随机挑选的一个跟踪纳斯达克指数的外围基金。它的无脑定投（每日等额定投）收益如下：近五年的定投年收益率在 11%，而近十年的定投收益率在 10%，这期间经历过数次大调整，比如 2020 年疫情，2021 年大加息等。这无疑是对这种投资思路的有效佐证。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://typora-images-wwweeds.oss-cn-hangzhou.aliyuncs.com/image-20251012141949411.png&quot; alt=&quot;image-20251012141949411&quot;&gt;&lt;/p&gt;
&lt;h3&gt;如果美股崩塌&lt;/h3&gt;
&lt;p&gt;美股的慢牛趋势自 1940 年至今未变，除了 2002 年那一次调整幅度超过 80%，确实令人胆战心惊，但彼时市盈率超过 100 倍，对于不贪婪的人，未必不可规避。&lt;/p&gt;
&lt;p&gt;英伟达、苹果、特斯拉，这些公司我实在看不出有倒闭或衰退的可能，家底实在雄厚，利益增长几乎是必定的，这是我们赚取年利 9% 的逻辑支撑。而如果发生各种事件，导致未来美股真的一改走势，那么世界格局绝对会发生巨大变化，我想那时也不必考虑财富自由的问题，世界必有新的机遇，入世才是更有趣的选择。&lt;/p&gt;
&lt;h2&gt;书籍推荐&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;《回归投资常识：策略思考的价值》&lt;/li&gt;
&lt;li&gt;《理财就是理生活》&lt;/li&gt;
&lt;li&gt;《简单致富》&lt;/li&gt;
&lt;li&gt;《投资中最简单的事》&lt;/li&gt;
&lt;li&gt;《指数基金投资指南》&lt;/li&gt;
&lt;li&gt;《哈利布朗的永久投资组合》&lt;/li&gt;
&lt;li&gt;《博格论指数基金》&lt;/li&gt;
&lt;li&gt;《经济学通识课》&lt;/li&gt;
&lt;li&gt;《小岛经济学》&lt;/li&gt;
&lt;/ol&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>育儿 - 读书笔记</title><link>https://ww-weeds.xyz/blog/%E8%82%B2%E5%84%BF%E9%98%85%E8%AF%BB%E7%AC%94%E8%AE%B0</link><guid isPermaLink="true">https://ww-weeds.xyz/blog/%E8%82%B2%E5%84%BF%E9%98%85%E8%AF%BB%E7%AC%94%E8%AE%B0</guid><description>若为自由故，一切皆可抛</description><pubDate>Fri, 03 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;育儿书籍的阅读&lt;/h2&gt;
&lt;p&gt;秋招告一段落，能面的几乎面完，剩下的多半是听天由命。&lt;/p&gt;
&lt;p&gt;国庆以来看了许多亲子教育类书籍，具体案例分析的有《少年发声》、《我为孩子打突围战》、《教育的另一种可能》；理论实践的有《正面管教》、《教练式父母》、《笑得出来的养育》等。本是随手翻阅，不曾想真的领略到主题阅读的妙趣。其中&lt;strong&gt;陈瑜&lt;/strong&gt;的书最为推荐，不光是做父母的、做孩子的，其文字内容对于我这种游离于亲子之外的成年人也锥心刺骨，常引我沉思。&lt;/p&gt;
&lt;p&gt;本来微信读书上各种帖子最令我瞧不起的词汇便是&lt;strong&gt;原生家庭&lt;/strong&gt;，我想那实在是懦夫所为，独立且自强的人格应当只归因、不批判，径直去解决问题。但看了这许多书本，我见识了好与差的教育分别是什么样的，更想到自己所受教育确实不是遵从天性、予我自由的。天下父母哪有完人，本人近况又颇不顺，两相对比不免恶念丛生，昨夜恨极时，胃部隐痛不止，肺进气亦艰难，才知道思伤脾、悲伤肺确有其事。再看那些说到原生家庭的帖子，确实是父母孩子均可怜的一对，只愿做父母的，能多听听孩子真正想说的话，做孩子的，也能更韧性皮实些而可以受住这上天所给的折磨吧。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;主题阅读的概念出自《如何阅读一本书》，大概是讲阅读的最终层次便是针对一个问题或者一门学科，做多方对比的、大量且广泛的阅读。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;什么样的教育是好的&lt;/h2&gt;
&lt;p&gt;这就是所有这些书想要解答的问题，这个问题在毕业生增多而岗位减少，全民皆卷而劳而不获的社会背景下显得越发尖锐。若这些书本没有夸大、编造的成分，我想我确实抓到了一些共识。&lt;/p&gt;
&lt;p&gt;最为核心的思想是这样的：&lt;strong&gt;任何孩子都是有向好的天性的，就像任何的生命都有发展自身的本能一样&lt;/strong&gt;。父母长辈要做的，只是顺应这样的天性，不是管理、不是教育、更非打骂。&lt;/p&gt;
&lt;p&gt;具体到实操上，则对应着围绕自由的这三点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;给孩子自由&lt;/strong&gt;：如果孩子不想写作业，那么就不写作业，让它自己面对老师批评、知识掌握不牢固、成绩下降等等一系列后果。真实的世界本来就是这样无可无不可的，每一个选择对应一个结果，从来没有什么应该或者不应该。如果孩子不写作业，却能应付好老师且管理好成绩，那这足以说明作业本身并非必要，这没有什么不好的。同理，夏天冬天增衣减衣，出去玩要玩什么吃什么，都要让孩子自己拿主意，选择然后得到后果，让世界去教会它。&lt;/p&gt;
&lt;p&gt;这里的终点就是让孩子自己决定读什么专业、选什么工作、与谁交友、和谁结婚，如果在小事上不让它多尝试多学习，何以决定大事呢？寒窗苦读十二年，突然要填报专业，一下慌了神，&lt;strong&gt;无自由则无意志，无意志则无目标&lt;/strong&gt;，只能去找某某专家花钱买个心安了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;帮助孩子，拓展孩子自由的边界&lt;/strong&gt;：孩子想做一件事却不知道如何做，比如想要学习绘画或者数学，此时做父母的就可以作为帮助者的角色，寻找网课、咨询老师或者干脆亲身指点。或者干脆父母带孩子参加各类活动，问孩子对哪个最感兴趣，或者观察孩子有什么样的天赋，再去挖掘提高。家长从来没有作为引领者，去干“玉不琢不成器”的这类事情，而是帮助、观察，家长是孩子的投资人，哪有投资人教创业者做事的呢？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;兜底，让自由拥有支点&lt;/strong&gt;：孩子也许喜欢音乐，但没有成长为知名音乐家的才华；孩子也许喜欢烹饪，但没法进驻米其林酒店；孩子也许喜欢编程，却踏不进互联网企业的门槛。那此时家长如何做呢，如何反应呢？否认、怒骂、逼迫，这一辈子就算白费？这正是孩子最需要父母的时候，帮它看到，在这个世界上活着是多么简单的事情，家长又有多么从容地来帮助它活得开心且有价值。&lt;/p&gt;
&lt;p&gt;我看到了帮孩子找教培资源，当音乐老师的家长；我看到了帮孩子联系动漫创业公司，让孩子参与实习的父母；我看到了能让孩子可以选择海外读书的父母；我看到了帮助孩子创业，一起在小区内售卖烘焙点心的父母；更多的，还有无论孩子在外面做什么，总给孩子留一口饭，留一点光的父母。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;此外，真正教育卓有成效的案例中，没有一位家长是全身心铺在孩子身上而没有自己的事业的。这不一定要去赚多少钱，做多大的生意，管多少人，自由职业者有，社会活动家有，勤奋上进的打工仔有，不论家长做什么，&lt;strong&gt;但只有靠着事业，才能展现父母是如何与社会交互的，如何面对工作与生活的，如何学习提高自己的，如何解决问题的&lt;/strong&gt;。言传无益，身教才可。&lt;/p&gt;
&lt;p&gt;一个经典问题：不管，孩子学坏了怎么办？&lt;/p&gt;
&lt;p&gt;我只回答这个好了：不管，孩子一直打游戏怎么办？&lt;/p&gt;
&lt;p&gt;有一个比喻非常好，当一个孩子只能选择冰激凌和吃泥巴的时候，它肯定会去吃冰激凌。但是如果它有可口的饭菜可吃，也许就不会一直吃冰激凌了。&lt;/p&gt;
&lt;p&gt;所以反思两点：父母自己的空闲时间在做什么？父母有没有给孩子提供足够丰富的精神世界（自然科学、科普知识、劳动实践、文学欣赏、伙伴陪伴）？&lt;/p&gt;
&lt;p&gt;哎，父母的行为自不必说，精神世界相关的这些词常令人联想到辅导机构，或者用以应对国外学校面试的那些作秀。可是真实地做一顿饭，到河边钓鱼，到山里挖蘑菇，和朋友逛博物馆，去参与社会活动，这些是多么有趣的事情……算不务正业么？&lt;/p&gt;
&lt;p&gt;如果这些都做到，孩子仍然喜欢玩游戏，那这游戏必然不可能是简单重复的，肯定有一定深度，那么倒要想想，是否可以让孩子将游戏玩出高度了。专注如此，何妨以此为地基去广泛地学习与交游呢？玩竞技的，可以去学心理学、学资源配置、学战争；玩创造的，可以学审美、学建筑、学项目管理……这何尝不是爱好引领学习的康庄大道呢？&lt;/p&gt;
&lt;h2&gt;反思自身所受教育&lt;/h2&gt;
&lt;p&gt;我觉得我所受的压根算不上教育。我对电脑游戏上瘾，除了游戏我的生活就只有刷题考学。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;我像是瘾君子，而我的父母垄断了我的毒源。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;初中、高中，靠着每周固定时间吸一口，支撑我一个周的学习动力。&lt;/p&gt;
&lt;p&gt;我从不会想我要什么，我不会想我活着要做什么，我不会想我未来的职业与人生。我像拉磨的驴，一圈又一圈，只是为了食槽里的糙米。&lt;/p&gt;
&lt;p&gt;若是考得好，这份生活便能维系下去，若考不好，则是天崩地裂。“因为我才不离婚”，我听了许多遍，但年幼的我想的只是要继续打游戏而已。&lt;/p&gt;
&lt;p&gt;幸而运气好，这脆弱的弦只在小学六年级绷断过，那时我尽了力气仍然考不到高分，父母生了气便不给我玩游戏了，我差点寻死。不敢想若初高中有类似经历，要如何继续下去。&lt;/p&gt;
&lt;p&gt;吸毒式的玩耍，让我将学习刷题之外的时间全部投入游戏，带着极大的情绪发泄倾向去玩游戏，游戏本身并没有玩出深度，只是无效的简单重复。而且几乎没有社交、没有好奇心、没有与自然的接触、不会做任何家务，完全谈不上有什么“童年回忆”。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;说来好笑，初中时喜欢一个女孩子，但是周末时光，比起和这个女孩子出去玩，我还是选择了在家打游戏……&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我幸运吗？很幸运，靠着这种简单到极点、容错率极低的机制也能考上还不错的大学。至于不幸的那一部分，还是忘却吧。这点痛苦相比于更不幸的那些，又算得了什么呢？至于我丢掉的好奇心、同理心、稳定乐观的心态云云，让我自己去负责吧。&lt;/p&gt;
&lt;p&gt;大学时我的大脑闲置下来，没有在后面催逼的人，看了许多书，好像抓到了一些模糊的脉络——这么下去不行，也许我活着确实有别的意义，虽然还是没有想明白。如今已切断与家父的全部联络通道，至于“家”，也是缺乏好感的地方。但父母确从不亏欠我什么，教育上的手段，也只出于认知上的局限而非主观恶意，经济上赡养父母会是我自愿履行的义务。&lt;/p&gt;
&lt;p&gt;如今放弃保研资格，踏出既定赛道，将会面临什么我一概不知。我只希望可以在 20岁 ~ 30岁的这段时间内，给予自己充分的自由，多尝试、多观察、多成长。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;我的童年，自今日始。&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;闲谈&lt;/h2&gt;
&lt;p&gt;还想聊聊两件事，一件是关于我的生育观。在搭建起这些感性认知之后，我亲身养育孩子的条件更加谨慎了。除非我做到这两件事：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;想明白自己活着是为了什么，自己想要什么。&lt;/li&gt;
&lt;li&gt;能在拥有大量空闲时间的情况下，赚到足够养活家人的金钱。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;若我自己还没长大，我要怎么去养孩子呢。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;还有一件是关于看书时看到他人的评论。教育的话题向来为人关注，其间看到了许多家长质疑自由本身的意义，以“普通人”自比，仍然认为顺从应试教育是孩子唯一的活路，考不上 92 双一流便是踏入鬼门关，活着就是多余。开始觉得可憎，后来觉得可笑可怜，现在则没有感觉。每个人都有资格去讲述自己的认知，谁又能保证自己是对的呢？这种认知并不会跨过屏幕伤害到我。&lt;/p&gt;
&lt;p&gt;想要反驳，那就一有机会就去做一个给予自由、顺应天性的家长吧。给他们看看，这不是天方夜谭。我对自己说。&lt;/p&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>尝试 - wx聊天教练</title><link>https://ww-weeds.xyz/blog/wx%E8%81%8A%E5%A4%A9%E6%95%99%E7%BB%83---%E4%B8%80%E6%AC%A1%E5%A4%B1%E8%B4%A5%E7%9A%84%E5%B0%9D%E8%AF%95</link><guid isPermaLink="true">https://ww-weeds.xyz/blog/wx%E8%81%8A%E5%A4%A9%E6%95%99%E7%BB%83---%E4%B8%80%E6%AC%A1%E5%A4%B1%E8%B4%A5%E7%9A%84%E5%B0%9D%E8%AF%95</guid><description>尽管失败，总之开始了</description><pubDate>Tue, 23 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;你们好呀，现在是 2025 年  9 月 23 日上午十点，我投递了几十家企业，没拿到 offer，但是从今天往后一场面试也没有约到，突然间不知道这段时间要如何度过，所以我决定向你们介绍我做的一个小玩具。&lt;/p&gt;
&lt;p&gt;很抱歉的是，这个玩具做得并不好。&lt;/p&gt;
&lt;p&gt;它大概长这个样子：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://typora-images-wwweeds.oss-cn-hangzhou.aliyuncs.com/image-20250923154432386.png&quot; alt=&quot;image-20250923154432386&quot;&gt;&lt;/p&gt;
&lt;p&gt;右侧是我制作的应用。我也简单地拍了一个小视频：https://www.bilibili.com/video/BV1cwJkzDENe/?spm_id_from=333.1387.upload.video_card.click&amp;#x26;vd_source=3c1b1f30ae8a8b2a440a8a0aff3f3943。&lt;/p&gt;
&lt;p&gt;功能上也非常简单，监听微信聊天记录，然后和 deepseek 对话。这样 deepseek 就可以教你怎么回复。但总的来说——不好用，我也想不到该怎么优化，现在没有人跟我聊天，我找不到试验材料。&lt;/p&gt;
&lt;p&gt;它有个名字叫“没话找话”，英文就是直译，&quot;findWords&quot;。&lt;/p&gt;
&lt;p&gt;这并不是一次自豪的展示，所以我也并没有像正经产品经理一样编一个故事来讲述它的价值。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;只是我想人生总有些事要开个头。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;如果我做出了让我自己自豪的东西，我确实觉得有用的东西，彼时我将会非常认真地和诸位分享。&lt;/p&gt;
&lt;p&gt;谢谢你看到这里。github 地址为：https://github.com/WWWeedss/findWords&lt;/p&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>一种整理收藏夹的思路</title><link>https://ww-weeds.xyz/blog/%E4%B8%80%E7%A7%8D%E6%95%B4%E7%90%86%E6%94%B6%E8%97%8F%E5%A4%B9%E7%9A%84%E6%80%9D%E8%B7%AF</link><guid isPermaLink="true">https://ww-weeds.xyz/blog/%E4%B8%80%E7%A7%8D%E6%95%B4%E7%90%86%E6%94%B6%E8%97%8F%E5%A4%B9%E7%9A%84%E6%80%9D%E8%B7%AF</guid><description>就像串起一串珍珠</description><pubDate>Wed, 20 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;起因&lt;/h2&gt;
&lt;p&gt;在 8.15 最后一天在淘天上班的时候，我看着我 Chrome 浏览器内的&lt;strong&gt;四百多个收藏网址&lt;/strong&gt;陷入了沉思……&lt;/p&gt;
&lt;p&gt;不管是 Edge 还是 Chrome 的收藏夹，都有一个很令我不爽的地方，就是在点开收藏网址的时候，有搜索栏可以搜索，但是在收藏新网址的时候却没有搜索栏选项。我也尝试过 Raindrop.io 这样的收藏夹插件，但是远程网络请求终究不如原生收藏夹侧边栏来的反应快、使用自如。为 Chrome 编写一个收藏夹插件，仅仅为了保留原生体验的同时可以在收藏新网址时使用搜索栏，这一项一直在我的待办列表里。&lt;/p&gt;
&lt;h2&gt;反思&lt;/h2&gt;
&lt;p&gt;我一直以为新加收藏页没有配备搜索功能是 Chrome 和 Edge 开发者的失误，直到我仔细审查我的全量收藏网址……&lt;/p&gt;
&lt;p&gt;网址众多、层层嵌套、相互交叉……&lt;/p&gt;
&lt;p&gt;我有一个习惯，不光是在整理收藏夹时，整理文档、定义项目结构时也会出现，就是习惯于定义大量的嵌套文件夹，&lt;strong&gt;像生物学家给生物分类界门纲目科属种&lt;/strong&gt;一样，总是想要像编写教科书一样给每一种文件一个唯一的 index。可事实上，分类过细是有坏处的。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;为了保持唯一的 Index，假如 A 项目和 B 项目都用到了工具 C，那么关于工具 C 的使用经验就不能和 A、B 的开发记录放在一起，而要单独列出，这导致了同一项目的信息分散在了不同的文件夹内。&lt;/li&gt;
&lt;li&gt;紧跟着的，想要做一件事时，为了搜集全量信息，不得不分别打开非常深的文件夹嵌套层级……这个过程还容易遗忘。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;正是因为我的&lt;strong&gt;分类过细、嵌套过深&lt;/strong&gt;，才导致了每次增加新的收藏网页时，我都需要搜索功能来帮我定位到目标收藏夹。&lt;/p&gt;
&lt;p&gt;这不是一件好事，我得清理清理它了。&lt;/p&gt;
&lt;h2&gt;改变&lt;/h2&gt;
&lt;p&gt;根据对某个答主博客的学习，也在网上搜索资料。我获得了一个新的管理收藏夹的思路。&lt;/p&gt;
&lt;p&gt;为什么我需要收藏夹？两种情况：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;有趣的、发散的内容，收藏下来以后再看。&lt;/li&gt;
&lt;li&gt;要做一件事情，需要各种网页。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;所以收藏夹总体上分为两类：随意采撷（有趣的、非系统性的内容），项目所需信息（完成一个个项目所需要的信息）。&lt;/p&gt;
&lt;p&gt;在随意采撷中，可以再分为书籍、博客、电影、旅行目标地……只分大文件夹，内部不要分类，在想看的时候随机点开，或者搜索。&lt;/p&gt;
&lt;p&gt;在项目所需信息中，按项目划分文件夹，假设我们有 A、B、C 三个前后端开发项目，那么每个项目文件夹内都维护一份前端框架使用经验、后端框架使用经验、开发记录等。&lt;/p&gt;
&lt;p&gt;当然我们也不能完全放弃对于同一工具使用经验的整合，所以额外列一个资源文件夹，只收集最泛用的资源。譬如 UI 素材，包括图片、图标、字体等，只要是做界面，每个项目必定都会用得到。放入资源文件夹的工具非常严格，至少在多于 3 个项目中使用过，才考虑放入其中。&lt;/p&gt;
&lt;p&gt;所以最后，我们就有了&lt;strong&gt;探索、项目、资源&lt;/strong&gt;三个文件夹，也只有这三个文件夹，每一个文件夹内的分类都很清晰。&lt;/p&gt;
&lt;p&gt;吉他琴谱与教学、烹饪基本功与菜谱，这些也都作为单独的项目放入项目文件夹。&lt;/p&gt;
&lt;p&gt;因为对内容纳入资源文件夹的严格限制，不可避免地，我们会在不同的项目文件夹内重复性地整理某些内容……但这不要紧，因为我们的目的已经达成了：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在想做一件事时可以快速定位全量相关信息。&lt;/li&gt;
&lt;li&gt;新增一个收藏页时，迅速定位目标收藏夹。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;“&lt;strong&gt;你将你的知识凝聚成一颗颗珍珠，用线穿过它们，这就已经是结构化了，已经足够你做成一切想做的工作了。至于重组成树状的结构，那是教授们才要考虑干的事情。&lt;/strong&gt;” 我非常喜欢这个比喻。&lt;/p&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>21岁 - 看看昨天我在想什么</title><link>https://ww-weeds.xyz/blog/21%E5%B2%81---%E7%9C%8B%E7%9C%8B%E6%98%A8%E5%A4%A9%E6%88%91%E5%9C%A8%E6%83%B3%E4%BB%80%E4%B9%88</link><guid isPermaLink="true">https://ww-weeds.xyz/blog/21%E5%B2%81---%E7%9C%8B%E7%9C%8B%E6%98%A8%E5%A4%A9%E6%88%91%E5%9C%A8%E6%83%B3%E4%BB%80%E4%B9%88</guid><description>和今年的自己聊一聊</description><pubDate>Sat, 16 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;二十一岁生日博客&lt;/h1&gt;
&lt;h2&gt;今天的坐标&lt;/h2&gt;
&lt;p&gt;今天是 2025 年 8 月 16 日，我的二十一岁生日，淘天转正失败，昨天我刚刚从淘天离职，这段实习的时间人的变化主要在想法和思想，技术之类的硬成长并不多，等我想聊的时候再聊吧。我的师兄和我在同一天跑路了……我实习完团队不仅没加人还少了人，还真是挺戏剧性的。&lt;/p&gt;
&lt;p&gt;昨晚附庸风雅一回，和朋友听了场《爱乐之城》主题的音乐会，眼睛在第一小提琴、低音提琴、中提琴上转个不停，真不知道放哪比较好。最后只记住了大提琴有四根弦，因为看见大提琴手拨弦伴奏的时候每次都是拨四下……还是觉得音乐会后吃的重庆小面比较有记忆，油真大，味真重，除了价格之外一点也不杭州，我挺喜欢这个！&lt;/p&gt;
&lt;p&gt;现在坐下来，看看今年自己写的日记，然后写下今天的生日博客。&lt;/p&gt;
&lt;h2&gt;回想今年&lt;/h2&gt;
&lt;p&gt;日记还真是记了非常多，从 24 年 10 月，到 25 年 8 月为止，有接近十万字。零零碎碎，虽然读来颇觉亲切，但实在太多太散，读得头大。看来这玩意以后也得结构化掉。拣出几条主线，也都有了结果：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;保研/工作&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;收尾本科生涯&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;寻找我要做的事&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;人际关系&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;略去细节，保研与工作的思考从我 2024 年写下的第一篇日记就开始挣扎，最终在前往淘天实习一个月后彻底决定&lt;strong&gt;放弃保研&lt;/strong&gt;；&lt;/p&gt;
&lt;p&gt;25 年 4 月开始，一边上班一边写作业、准备期末，总算无一挂科，学位课成绩尚可，开学说不定能再拿一两千的奖学金。虽然决定不保研后，它对我的作用不再那么显然，但谁知道呢，本科生涯基本算是结束；&lt;/p&gt;
&lt;p&gt;知道不想要什么没有意义，那多半是对现状的不满和环境的抱怨，知道想要什么才算是主动的探寻。丢掉保研的包袱之后细细思考，写代码就是我最开心的事情，有能看得到的产出则更令我欣喜——所以&lt;strong&gt;我决定将参与制作小巧精致、能解决实际问题的软件作为本阶段的人生目标&lt;/strong&gt;。能作为全栈开发参与甚至需求中也起到主导作用是我的愿望，努力去做但不强求；&lt;/p&gt;
&lt;p&gt;人际总算回到了它应有的位置，不再像火焰般炙烤我……&lt;strong&gt;一个人、两个人或者一群人，只是一种选择，任何时候都不该成为一种需要我去极力避免的惩罚&lt;/strong&gt;。&lt;/p&gt;
&lt;h2&gt;至少我做到了一些事…&lt;/h2&gt;
&lt;p&gt;困扰我许久的刷哔站的问题，我通过注销账号 + dns 屏蔽 + 下载纪录片基本彻底解决了，近一个月应该都没有刷过哔哩哔哩了吧？还在吃饭时看完了几部类似《线性代数的本质》这样的片子。因为这些片子没有刻意地留悬念、增趣味，更没有随机推荐出来的视频，所以吃完饭也不留念，直接就做正事了。其他困扰我的诱惑物也做了类似处理，&lt;strong&gt;基本摆脱了虚无 - 做事 - 疲倦 - 娱乐 - 虚无的困境循环&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;对于工作这件事祛魅，不再将诸如价值之类的东西加之其上，我是来赚钱的，还是来获取某个领域的实践经验，或者有别的目标，内心有了定数。面对大厂，既免去类似求学者面对清北的仰望，也丢掉作为无产阶级对资本机器的憎恶……&lt;/p&gt;
&lt;p&gt;定下了阶段性目标，不管这个主线究竟是否能在成就感或薪资上给我带来多少回报，至少好过夜里辗转反侧、面对选择无所适从时的孩子般的无助。&lt;/p&gt;
&lt;h2&gt;未来&lt;/h2&gt;
&lt;p&gt;秋招是又一次大事件。追求有三：增加可能性、靠近目标、赚钱。不可兼得则取其一。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;功能性 SaaS 岗位 &gt; AI/硬件相关 &gt; 薪资 （时薪）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;虽说最后可能并不由得我选择，至少计划要照着列。&lt;/p&gt;
&lt;p&gt;若能持续向目标迈进，自然最好；若因为能力毕竟有限，没法找到心仪岗位，向硬件或者 AI 拓宽一下技术栈或者干脆攒钱三五年后出国读硕或博，都是有意思的选项。&lt;/p&gt;
&lt;p&gt;若去大厂，至少薪资方面可以满足，其对于我慢慢成长的宽容度也更高；若去小厂，则接触 SaaS 落地与客户方面肯定更多。事情总有好坏两面，人生总有可企盼的地方。&lt;/p&gt;
&lt;p&gt;现在的能力几乎只有后端开发，而且还缺乏对于真实生产环境下的问题处理，想达到阶段性目标，前端、设计、需求、市场，还有许多事要做，时不我待。&lt;/p&gt;
&lt;p&gt;对于更遥远的未来，不去想，懒于规划，立一个清晰的目标，把握住几个模糊的原则，尽力不亏欠于人，如此而已。&lt;/p&gt;
&lt;h2&gt;愿望&lt;/h2&gt;
&lt;p&gt;希望我的朋友们、同学们：&lt;/p&gt;
&lt;p&gt;直接工作的，秋招顺利；&lt;/p&gt;
&lt;p&gt;保研考研的，得遇良师；&lt;/p&gt;
&lt;p&gt;已经工作的，财运亨通；&lt;/p&gt;
&lt;p&gt;成家立业的，家庭和乐。&lt;/p&gt;
&lt;p&gt;也期待我自己……能顺着这个月给自己划定的路线走下去，坚持坚持，至少在自己身上看到一些真真正正的成长之后，再谈其他。人生真的很长，尤其对于没准备结婚的人来说，是该耐心一些。&lt;/p&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>把钱管起来</title><link>https://ww-weeds.xyz/blog/%E6%8A%8A%E9%92%B1%E7%AE%A1%E8%B5%B7%E6%9D%A5</link><guid isPermaLink="true">https://ww-weeds.xyz/blog/%E6%8A%8A%E9%92%B1%E7%AE%A1%E8%B5%B7%E6%9D%A5</guid><description>是该为自己的计划付诸行动了</description><pubDate>Wed, 23 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;一份理财计划&lt;/h1&gt;
&lt;h2&gt;为了一些事，我得攒钱&lt;/h2&gt;
&lt;p&gt;之前的资产配置计划总有些地方感觉不是很好执行，我有下面的一些需求：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;区分为现款和存款&lt;/li&gt;
&lt;li&gt;在一般情况下存款只增不减&lt;/li&gt;
&lt;li&gt;设定应急存款&lt;/li&gt;
&lt;li&gt;存款配置偏好中高风险（因为今年的基金涨得真的很好……）&lt;/li&gt;
&lt;li&gt;现款除了日用，还要满足我可能的报课学习、器具购买、社交、旅行支出&lt;/li&gt;
&lt;li&gt;可以按月为周期进行分配存款，即每月不需重新计算，可以只用月薪按比例分配，每半年进行重平衡&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;综合上述需求，今天上班的时候配合 AI 重新制定了一份计划出来。具体计划如下：&lt;/p&gt;
&lt;p&gt;这里面的配比是我自己拍脑袋定的，别问我为啥……&lt;/p&gt;
&lt;h2&gt;资产配置计划&lt;/h2&gt;
&lt;h3&gt;当前资产分配&lt;/h3&gt;
&lt;p&gt;日用：5000 元&lt;/p&gt;
&lt;p&gt;现款：20000 元，用于学习、旅行、社交&lt;/p&gt;
&lt;p&gt;其余均作为存款，在非特殊情况下只增不减。特殊情况包括生病、婚丧嫁娶、出国、买房、买车等。&lt;/p&gt;
&lt;p&gt;应急存款：20%&lt;/p&gt;
&lt;p&gt;债券：20%&lt;/p&gt;
&lt;p&gt;红利低风险证券：10%&lt;/p&gt;
&lt;p&gt;国内宽基（上证、创业、北交所）：15%&lt;/p&gt;
&lt;p&gt;海外科技指数：15%&lt;/p&gt;
&lt;p&gt;黄金：10%&lt;/p&gt;
&lt;p&gt;战术现金：10% ，每个平衡周期内为定额，在每个再平衡中进行值更新。&lt;/p&gt;
&lt;h3&gt;薪资分配&lt;/h3&gt;
&lt;p&gt;发薪或任意大额收入，优先填满日用与现款池，再填满战术现金池，剩下进行拆分。&lt;/p&gt;
&lt;p&gt;现款集中到 xx 卡，日用集中到微信，应急存款放入 xx 卡&lt;/p&gt;
&lt;p&gt;每月工资发放时进行现金池填充以及按下列比例存款：&lt;/p&gt;
&lt;p&gt;首先填充日用、现款、战术现金三个定额池，剩余钱款按比例摊入&lt;/p&gt;
&lt;p&gt;应急存款：22.2%&lt;/p&gt;
&lt;p&gt;债券：22.2%&lt;/p&gt;
&lt;p&gt;红利低风险证券：11.1%&lt;/p&gt;
&lt;p&gt;国内宽基（上证、创业、北交所）：16.7%&lt;/p&gt;
&lt;p&gt;海外科技指数：16.7%&lt;/p&gt;
&lt;p&gt;黄金：11.1%&lt;/p&gt;
&lt;h3&gt;再平衡&lt;/h3&gt;
&lt;p&gt;每半年再平衡一次&lt;/p&gt;
&lt;p&gt;平衡首先更新日用与现金池：&lt;/p&gt;
&lt;p&gt;日用 = 最近平均 6 个月的月支出，不低于 5000，不高于月薪的 50%&lt;/p&gt;
&lt;p&gt;现款 = 日用 * 4&lt;/p&gt;
&lt;p&gt;战术现金 = 存款总额 * 10%&lt;/p&gt;
&lt;p&gt;然后按比例更新存款：&lt;/p&gt;
&lt;p&gt;应急存款：20%&lt;/p&gt;
&lt;p&gt;债券：20%&lt;/p&gt;
&lt;p&gt;红利低风险证券：10%&lt;/p&gt;
&lt;p&gt;国内宽基（上证、创业、北交所）：15%&lt;/p&gt;
&lt;p&gt;海外科技指数：15%&lt;/p&gt;
&lt;p&gt;黄金：10%&lt;/p&gt;
&lt;h3&gt;大额花销补充&lt;/h3&gt;
&lt;p&gt;当想要进行爱好课程报名、长途旅行、贵重摆件购买（注意是奢侈消费，出国留学、车、房购买算入特殊事件，可动用应急存款外的所有钱款）而现金池不够时，且下个月发薪较远，可以：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;根据当前战术资金池反推存款总额，若现有存款高于理论存款总额，针对溢出部分，可以进行下列操作；若现有存款低于理论存款总额，则考虑放弃当前规划&lt;/li&gt;
&lt;li&gt;以盈利 &gt; 亏损，证券 &gt; 红利 &gt; 债券 &gt; 黄金的方式进行售出&lt;/li&gt;
&lt;li&gt;优先售出盈利超过 30% 的产品&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;后续&lt;/h2&gt;
&lt;p&gt;我是用的支付宝进行债券、黄金、指数基金投资，看到有的微信小程序居然可以导入支付宝基金数据，那么我想将再平衡、制定理财计划、调整理财计划这些通通自动化，至少说可以直接计算出各种需要平衡的数字出来。&lt;/p&gt;
&lt;p&gt;我想想，我可以再接入一个 AI + MCP 去拉取基金数据等，制定和修订理财计划……不过这个理财计划不能通用化，那么就要取舍了……是彻底方便我自己的操作，还是把这个往通用 AI 助手的道路上发展……&lt;/p&gt;
&lt;p&gt;我先做一个自己会用的软件吧！程序员必须得做自己会用的软件！&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;教导我的人想要的，我不是很 care，ta 不怎么在意的，我觉得很有趣；爬梯子、攒钱、功成名就、娱乐、结婚、生子，那是些根本没有尽头的事情……人生来就是自由的，我给各位打个样，看看就认真地按自己的想法活，到底至于不至于真的把自己饿死。&lt;/p&gt;
&lt;p&gt;我不能等待命运降临，我要选择自己的人生，就按现在这个想法活，死了拉倒，谁也管不着我！&lt;/p&gt;
&lt;p&gt;相信自己，也相信老天吧。&lt;/p&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>small-spring 学习总结</title><link>https://ww-weeds.xyz/blog/my-small-spring</link><guid isPermaLink="true">https://ww-weeds.xyz/blog/my-small-spring</guid><description>第一次感受到编程的魅力</description><pubDate>Mon, 14 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;爱上编程的第一步&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;如果以后我真的可以全心全意地爱上编程的话，那这个项目就是丘比特的箭了！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;写在开头&lt;/h2&gt;
&lt;p&gt;跟着教程一步一步地把这个简陋的 Spring 框架敲出来了，DI 容器、Bean 生命周期管理、Xml 配置、Aware、Event、AOP、注解与包扫描、多级缓存、类型转换，全都涉猎了一遍。&lt;/p&gt;
&lt;p&gt;这是我的第一个正经学完的编程项目，回想本科期间，可能只有编译原理课上的简单编译器可以与之媲美，但是编译原理课的助教团体太过负责，制作了茫茫多的非公开测试用例，导致项目体感更类似 OJ 而非工程……往事不要再提。&lt;/p&gt;
&lt;p&gt;还记得把多级缓存搞明白的那个晚上，我是 8 点 50 离开公司座位（那是周六，所以没在摸鱼啦，为了周末有饭吃就到公司去了），走到楼下，朗月清风。我骑着共享单车绕着小区转了好多好多圈之后才回家，唱的是伍佰的《亏欠》和《一生最爱的人》，也不知道唱这两首歌的时候心里想的是谁，希望那天早睡的人没有被我吵醒……&lt;/p&gt;
&lt;p&gt;如果你也感兴趣，可以参考我的学习路径总结：&lt;a href=&quot;https://github.com/WWWeedss/my-small-spring&quot;&gt;my-small-spring 项目地址&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;下方的内容则是我自己对 Spring 学习的一个回顾，练一练总结和抓重点脉络的能力。&lt;/p&gt;
&lt;h2&gt;为什么要有 Spring&lt;/h2&gt;
&lt;p&gt;为了能这么写后端：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;@Autowired
UserService userService;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Spring 就是基础设施，除了帮我们管理好实例之间的依赖，还内置了 event、AOP 等等功能。我已经无法想象我无法想象没有 SpringBoot 或类似 DI 容器的后端开发流程，就像我无法想象没有 ChatAI 的工作生活。&lt;/p&gt;
&lt;h2&gt;一起搭一个积木：从使用者的角度看 Spring 功能的逐步丰满&lt;/h2&gt;
&lt;h3&gt;最简单的容器&lt;/h3&gt;
&lt;p&gt;BeanFactory 里存储了一个 HashMap，这就是全部的秘密。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;beanFactory.register(&quot;userService&quot;, new UserService());
UserService userService = beanFactory.get(&quot;userService&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;用反射来替代 new&lt;/h3&gt;
&lt;p&gt;我们增加一个 BeanDefinition 的定义，在 BeanDefinition 内存储 BeanName 和 Class 信息。这就可以用反射来避免用户直接 new 对象了。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;BeanDefinition beanDefinition = new BeanDefinition(UserService.class);
beanFactory.registerBeanDefinition(&quot;userService&quot;, beanDefinition);
UserService userService = beanFactory.getBean(&quot;userService&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;有参构造 Bean 与属性注入&lt;/p&gt;
&lt;p&gt;在 getBean 的时候传入构造参数，使用反射匹配符合参数的构造函数，完成 bean 的有参构造。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;BeanDefinition beanDefinition = new BeanDefinition(UserService.class);
beanFactory.registerBeanDefinition(&quot;userService&quot;, beanDefinition);
// UserService 有一个 name 属性，接受一个 String 参数
UserService userService = beanFactory.getBean(&quot;userService&quot;, &quot;WWWeeds&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;用户不仅可以在 getBean 的时候传参数，还可以在 getBean 之前配置属性，这就用到了属性注入。&lt;/p&gt;
&lt;p&gt;没有什么神秘的，只是 BeanDefinition 中存储了 PropertyValues，每一个 PropertyValue 都有字段名和对应的值，在 createBean 的时候使用反射进行 setField 而已。当然我们也需要一个额外的类型来表示引用，这就是 BeanReference，注入 BeanReference 时要使用 getBean。 这里我们忽略循环依赖和字段类型不匹配的情况。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;beanFactory.registerBeanDefinition(&quot;userDao&quot;, new BeanDefinition(UserDao.class));

PropertyValues propertyValues = new PropertyValues();
propertyValues.addPropertyValue(new PropertyValue(&quot;uId&quot;, &quot;10001&quot;));
propertyValues.addPropertyValue(new PropertyValue(&quot;userDao&quot;, new BeanReference(&quot;userDao&quot;)));

BeanDefinition beanDefinition = new BeanDefinition(UserService.class, propertyValues);
beanFactory.registerBeanDefinition(&quot;userService&quot;, beanDefinition);

// 框架会先 getBean(&quot;userDao&quot;)，然后将取出的 userDao 注入 userService 的字段中；对于 uId 这个字段直接注入就好。
UserService userService = (UserService) beanFactory.getBean(&quot;userService&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;使用 XML 进行配置&lt;/h3&gt;
&lt;p&gt;Xml 就是一个树状元素，把我们在代码里写的东西写到 xml 文件中，仅此而已。为了兼容各种路径（classpath、普通路径、网络 url），Spring 框架使用不同的 Reader 实现了同一个接口方法：输入路径，输出字节流。这是经典的策略模式或者简单工厂的应用场景。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-xml&quot;&gt;&amp;#x3C;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&amp;#x3C;beans&gt;

    &amp;#x3C;bean id=&quot;userDao&quot; class=&quot;bean.UserDao&quot;/&gt;

    &amp;#x3C;bean id=&quot;userService&quot; class=&quot;bean.UserService&quot;&gt;
        &amp;#x3C;property name=&quot;uId&quot; value=&quot;10001&quot;/&gt;
        &amp;#x3C;property name=&quot;userDao&quot; ref=&quot;userDao&quot;/&gt;
    &amp;#x3C;/bean&gt;

&amp;#x3C;/beans&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;就是把我们的代码翻译了一遍，没有任何失真，除了 value 只能是字符串&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;已经有点像魔法了，它自动生成了 UserDefinition，自动注入了 userDao，我们只要拿出来用就可以。当然前提是……xml 文件不是你填的。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;UserService userService = beanFactory.getBean(&quot;userService&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;增加 ApplicationContext 控制 Bean 的生命周期&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;BeanPostprocessor&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;我们希望在创建 Bean 的过程中对 BeanDefinition 或者 Bean 进行一些特殊处理，这就是 PostProcessor。&lt;/p&gt;
&lt;p&gt;实现方式就是新建一个 ApplicationContext 类持有 BeanFactory，在 ApplicationContext 中定义 Bean 的全生命周期。在注册 BeanDefinition 之后执行 BeanFactoryPostProcessor 之类。&lt;/p&gt;
&lt;p&gt;像 BeanFactoryPostProcessor  本身也是 Bean，我们实现之后用 Xml 注册进来，容器就能自动通过类型识别取出调用了。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

        BeanDefinition beanDefinition = beanFactory.getBeanDefinition(&quot;userService&quot;);
        PropertyValues propertyValues = beanDefinition.getPropertyValues();

        propertyValues.addPropertyValue(new PropertyValue(&quot;company&quot;, &quot;改为：字节跳动&quot;));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-xml&quot;&gt;&amp;#x3C;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&amp;#x3C;beans&gt;

    &amp;#x3C;bean id=&quot;userDao&quot; class=&quot;bean.UserDao&quot;/&gt;

    &amp;#x3C;bean id=&quot;userService&quot; class=&quot;bean.UserService1&quot;&gt;
        &amp;#x3C;property name=&quot;uId&quot; value=&quot;10001&quot;/&gt;
        &amp;#x3C;property name=&quot;company&quot; value=&quot;腾讯&quot;/&gt;
        &amp;#x3C;property name=&quot;location&quot; value=&quot;深圳&quot;/&gt;
        &amp;#x3C;property name=&quot;userDao&quot; ref=&quot;userDao&quot;/&gt;
    &amp;#x3C;/bean&gt;

    &amp;#x3C;bean class=&quot;common.MyBeanPostProcessor&quot;/&gt;
    &amp;#x3C;bean class=&quot;common.MyBeanFactoryPostProcessor&quot;/&gt;

&amp;#x3C;/beans&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;// 1.初始化 BeanFactory
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(&quot;classpath:springPostProcessor.xml&quot;);

// 2. 获取Bean对象调用方法
UserService userService = applicationContext.getBean(&quot;userService&quot;, UserService.class);
String result = userService.queryUserInfo();
System.out.println(&quot;测试结果：&quot; + result);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;BeanPostProcessor 的具体执行对用户是无感知的，后面的 Aware、Event、AOP 都会用到它。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;初始化与销毁&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;有两种注册初始化与销毁方法的方式，一种是类似 BeanPostProcessors，透出接口，在特定位点取出实现了接口的 Bean 执行，另一种就是 xml 配置，通过反射取出特定方法，在生命周期的特定位置执行。其中销毁方法是用虚拟机关闭时的钩子触发的。&lt;/p&gt;
&lt;p&gt;initialzingBean.afterProperties() 会先于 init-method 执行，二者均配置时顺序执行。&lt;/p&gt;
&lt;p&gt;disposableBean.destroy() 会先于 destroy.method 执行，二者均配置时只执行 destroy，避免二次销毁。&lt;/p&gt;
&lt;p&gt;xml 配置如下：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;&amp;#x3C;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&amp;#x3C;beans&gt;

    &amp;#x3C;bean id=&quot;userDao&quot; class=&quot;bean.UserDao&quot; init-method=&quot;initDataMethod&quot; destroy-method=&quot;destroyDataMethod&quot;/&gt;

    &amp;#x3C;bean id=&quot;userService&quot; class=&quot;bean.UserService1&quot;&gt;
        &amp;#x3C;property name=&quot;uId&quot; value=&quot;10001&quot;/&gt;
        &amp;#x3C;property name=&quot;company&quot; value=&quot;淘天&quot;/&gt;
        &amp;#x3C;property name=&quot;location&quot; value=&quot;杭州&quot;/&gt;
        &amp;#x3C;property name=&quot;userDao&quot; ref=&quot;userDao&quot;/&gt;
    &amp;#x3C;/bean&gt;

&amp;#x3C;/beans&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;package bean;

import springframework.beans.factory.DisposableBean;
import springframework.beans.factory.InitializingBean;

public class UserService implements InitializingBean, DisposableBean {

    private String uId;
    private String company;
    private String location;
    private UserDao userDao;

    @Override
    public void destroy() throws Exception {
        System.out.println(&quot;执行：UserService.destroy()&quot;);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println(&quot;执行：UserService.afterPropertiesSet()&quot;);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;感知 Aware&lt;/h3&gt;
&lt;p&gt;所谓感知，就是让 Bean 知道创建自己的 BeanName、ClassLoader、BeanFactory、ApplicationContext，来进行一些反向操作。框架的实现非常简单，通过注册一个 BeanPostProcessor，透出一些 Aware 接口，这个 BeanPostProcessor 会对实现了 Aware 接口的 Bean 进行注入（调用 set 方法）。&lt;/p&gt;
&lt;p&gt;其中一个 Aware 接口：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;public interface ApplicationContextAware extends Aware {
    void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;用户可以这么去定义 Bean：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;public class UserService implements BeanNameAware, ApplicationContextAware, BeanFactoryAware {

    private ApplicationContext applicationContext;
    private BeanFactory beanFactory;

    private String uId;
    private String company;
    private String location;
    private UserDao userDao;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    public void setBeanName(String name) {
        System.out.println(&quot;Bean Name is：&quot; + name);
    }

}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Spring Event&lt;/h3&gt;
&lt;p&gt;发送消息是一个经典的解耦需求，在这里我们暂且不考虑消息队列。Spring 框架内部注册一个 ApplicationEventMulticaster Bean，从 ApplicationContext 向外暴露一个 PublishEvent 方法。&lt;/p&gt;
&lt;p&gt;当用户使用 ApplicationContext.publishEvent() 时，ApplicationEventMulticaster 就会通知所有订阅该事件的 Listener。&lt;/p&gt;
&lt;p&gt;Event 和自定义 Listener 由用户实现接口，通过泛型指定订阅的消息类型，框架会抛出几个特定事件，比如容器刷新完成和关闭。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;public class CustomEvent extends ApplicationContextEvent {

    private Long id;
    private String message;

    public CustomEvent(Object source, Long id, String message) {
        super(source);
        this.id = id;
        this.message = message;
    }

    public Long getId() {
        return id;
    }

    public String getMessage() {
        return message;
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;public class CustomEventListener implements ApplicationListener&amp;#x3C;CustomEvent&gt; {
    @Override
    public void onApplicationEvent(CustomEvent event) {
        System.out.println(&quot;CustomEventListener received event: &quot; + event.getMessage() + &quot; with ID: &quot; + event.getId());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-xml&quot;&gt;&amp;#x3C;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
    &amp;#x3C;beans&gt;

        &amp;#x3C;bean class=&quot;event.ContextRefreshedEventListener&quot;/&gt;

        &amp;#x3C;bean class=&quot;event.CustomEventListener&quot;/&gt;

        &amp;#x3C;bean class=&quot;event.ContextClosedEventListener&quot;/&gt;

    &amp;#x3C;/beans&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;public class ApiTest {
    @Test
    public void test_event(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext((&quot;classpath:spring.xml&quot;));
        applicationContext.publishEvent(new CustomEvent(applicationContext, 1001L, &quot;Hello, this is a custom event!&quot;));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;AOP&lt;/h3&gt;
&lt;p&gt;首先你需要了解动态代理：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://typora-images-wwweeds.oss-cn-hangzhou.aliyuncs.com/image-20250703073925782.png&quot; alt=&quot;image-20250703073925782&quot;&gt;&lt;/p&gt;
&lt;p&gt;动态代理持有着 targetObject 的引用，通过反射的方式调用其中的方法，并在调用前后增加额外操作。那么如何对用户屏蔽代理的存在呢？JDK 的动态代理是让代理和 targetObject 实现同一个接口，用户只能调用接口中的方法，Cglib 的动态代理是让代理类去继承 targetObject，形成增强子类。&lt;/p&gt;
&lt;p&gt;AOP 也很好理解，在 Bean 初始化完成之后，通过 AspectJ 切点表达式（切点表达式标注了）判断这个 Bean 是否需要代理，如果需要就增强一下。后续 getBean 出来都是这个代理类，用户的调用都会被代理转发，代理的 preprocessor 和 postprocessor 都暴露出来可以给用户自定义，去打日志之类的。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;&amp;#x3C;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&amp;#x3C;beans&gt;

    &amp;#x3C;bean id=&quot;userService&quot; class=&quot;bean.UserService1&quot;/&gt;

    &amp;#x3C;bean class=&quot;springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator&quot;/&gt;

    &amp;#x3C;bean id=&quot;beforeAdvice&quot; class=&quot;bean.UserServiceBeforeAdvice&quot;/&gt;

    &amp;#x3C;bean id=&quot;methodInterceptor&quot; class=&quot;springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor&quot;&gt;
        &amp;#x3C;property name=&quot;advice&quot; ref=&quot;beforeAdvice&quot;/&gt;
    &amp;#x3C;/bean&gt;

    &amp;#x3C;bean id=&quot;pointcutAdvisor&quot; class=&quot;springframework.aop.aspectj.AspectJExpressionPointcutAdvisor&quot;&gt;
        &amp;#x3C;property name=&quot;expression&quot; value=&quot;execution(* bean.IUserService.*(..))&quot;/&gt;
        &amp;#x3C;property name=&quot;advice&quot; ref=&quot;methodInterceptor&quot;/&gt;
    &amp;#x3C;/bean&gt;

&amp;#x3C;/beans&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;beforeAdvice 定义了方法的前置操作，在 methodInterceptor 和原方法执行一起被封装到 Invoke 中。pointcutAdvisor 定义了切点表达式，告知了 proxy 要匹配哪些方法。&lt;/p&gt;
&lt;p&gt;Proxy 接到调用之后，就检查切点表达式是否能匹配到，能就调用 methodInterceptor 的 invoke，否则直接执行。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;public class UserServiceBeforeAdvice implements MethodBeforeAdvice {
    @Override
    // 在目标方法之前执行
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println(&quot;拦截方法：&quot; + method.getName());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;public class ApiTest {
    @Test
    public void test_aop() throws NoSuchMethodException {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(&quot;classpath:spring.xml&quot;);

        IUserService userService = applicationContext.getBean(&quot;userService&quot;, IUserService.class);
        System.out.println(userService.queryUserInfo());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;注解与包扫描&lt;/h3&gt;
&lt;p&gt;这是一个非常经典的用户体验优化。经过这一步，我们就能写出这样的类了：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;@Component(&quot;userService&quot;)
public class UserService {
    @Autowired
    UserDao userDao;
    
    @Value(&quot;helloWorld&quot;);
    String token;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;保留到运行时的注解会和修饰类绑定，我们可以通过反射拿到指定包内被修饰的类，这就可以对 @Component 修饰的类进行 Bean 注册，再拿到被注解修饰的字段，进行属性注入即可。&lt;/p&gt;
&lt;h2&gt;Bean 的生命周期&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://typora-images-wwweeds.oss-cn-hangzhou.aliyuncs.com/image-20250714190004691.png&quot; alt=&quot;image-20250714190004691&quot;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;对于 Prototype 类型的 Bean 来说，它根本不进入缓存，创建完直接返回，不归 Spring 框架管，没有什么讨论的价值。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;每两个步骤之间，都可以添加 PostProcessors 去修改 BeanDefinition 或者 Bean，Spring 框架提供了切口给我们，我们只需要继承某一个特定类或者实现某一个特定接口就可以了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://typora-images-wwweeds.oss-cn-hangzhou.aliyuncs.com/image-20250714230832198.png&quot; alt=&quot;image-20250714230832198&quot;&gt;&lt;/p&gt;
&lt;h2&gt;其他细节&lt;/h2&gt;
&lt;h3&gt;关于 FactoryBean&lt;/h3&gt;
&lt;p&gt;FactoryBean 是 Bean 的一种。它存储在 Spring 框架内，但是无法被 getBean 获取实例，getBean 会调用 FactoryBean.getObject() 方法，这个方法的返回值才是 getBean 的结果。&lt;/p&gt;
&lt;p&gt;FactoryBean 实际是把 Bean 的实例化抛回给用户，如果你的对象需要复杂的配置，无法用 get、set、依赖注入解决，或者说每次 getBean 都需要根据 xx 因素改变一下，或者 FactoryBean 本身有一些额外作用，那就用 FactoryBean 吧。&lt;/p&gt;
&lt;h3&gt;循环依赖的解决&lt;/h3&gt;
&lt;p&gt;基本方案是缓存。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;A a = new A();
B b = new B();
a.setB(b);
b.setA(a);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Spring 就是把上述代码中的 a 刚 new 出来就放入了缓存以供 b 引用，通过维持引用一致，在 a 初始化之后，b 持有的 a 也初始化完成。&lt;/p&gt;
&lt;p&gt;至于为什么要有三级缓存，缺乏了 ApplicationContext 以及 Spring AOP 如何实现的前置知识，是无法理解的。可以顺着项目走，走到那里就懂了。&lt;/p&gt;
&lt;h3&gt;类型转换的解决&lt;/h3&gt;
&lt;p&gt;@Value 只能写字符串值，那么 Spring 如何将字符串值转换为其他类型并注入字段呢。这就用到了 Convertor。你可以简单地理解为 Spring 的容器中存储了一组 Convertors，注入字段时 Spring 会尝试去匹配，如果有类型符合的 Convertor 就使用。&lt;/p&gt;
&lt;p&gt;Spring 内置了字符串到数字值的转换器，用户也可以自己实现并注册成为 Bean。&lt;/p&gt;
&lt;p&gt;下方的配置文件中就使用了 FactoryBean，当我们 getBean(conversionService) 时，它就会返回 converters，而 getBean(converters)，返回的就是我们定义的各种转换器了。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-xml&quot;&gt;&amp;#x3C;beans&gt;
    &amp;#x3C;bean id=&quot;conversionService&quot; class=&quot;springframework.context.support.ConversionServiceFactoryBean&quot;&gt;
        &amp;#x3C;property name=&quot;converters&quot; ref=&quot;converters&quot;/&gt;
    &amp;#x3C;/bean&gt;

    &amp;#x3C;bean id=&quot;converters&quot; class=&quot;converter.ConvertersFactoryBean&quot;/&gt;
    
    &amp;#x3C;component-scan base-package=&quot;bean&quot;/&gt;
&amp;#x3C;/beans&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;写在最后&lt;/h2&gt;
&lt;p&gt;将日常使用的东西逐渐解构，这种对世界理解加深的感觉真是太棒了；不考虑面试、不考虑就业、不考虑任何东西，只凭借单纯的好奇与 Spring 代码本身的优雅结构（也许只是比我写的代码优雅？），就可以收获很多很多乐趣。在以后的日子里，我想要更多地学习日常接触的东西的原理，并且开发我自己日常可以使用的软件。什么都离不开生活，软件也是。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;用软件来改善生活，是二十一世纪魔法师的最终使命。&lt;/strong&gt;&lt;/p&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>跨域的解决 - 在博客里面添加一个评论系统</title><link>https://ww-weeds.xyz/blog/%E8%B7%A8%E5%9F%9F%E7%9A%84%E8%A7%A3%E5%86%B3---%E7%94%B1%E5%B8%83%E7%BD%AE-comment-%E5%BC%95%E5%8F%91</link><guid isPermaLink="true">https://ww-weeds.xyz/blog/%E8%B7%A8%E5%9F%9F%E7%9A%84%E8%A7%A3%E5%86%B3---%E7%94%B1%E5%B8%83%E7%BD%AE-comment-%E5%BC%95%E5%8F%91</guid><description>花了点时间配了下 waline 评论系统，作为第一篇技术博客啦</description><pubDate>Sat, 28 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;这是一个一级标题&lt;/h1&gt;
&lt;h2&gt;这是一个二级标题&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;因为这个主题没有支持跨级标题，因为标题是树状结构的，只能有一个根，而且孩子的 depth 只能比 parent 深一层。个人的写作习惯又是从三级标题开始（这个习惯是有缘由的，挖个坑以后说）。所以可能后面我的每篇博客都会有这俩玩意。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;没能免俗&lt;/h3&gt;
&lt;p&gt;看过不少同行的博客，发现好多博客的第一篇技术博客都是“用 xx 分钟搭一个属于你的个人博客”。哈，果然我也没能“免俗”（其实一点也不俗好嘛，都不写我怎么学）。&lt;/p&gt;
&lt;p&gt;但是现在这个 astro + vercel + react 的工具链确实非常好用，找到个这个挺好看的 theme 之后基本是 fork 下来随便弄弄就搞定了，没费啥脑子（作者真棒！）。如果你也想用这个主题，可以直接到页面最下方找到 Astro &amp;#x26; Pure theme 的链接。&lt;/p&gt;
&lt;p&gt;过程中唯一比较费事的就是配置 waline 评论系统，遇到了经典的&lt;strong&gt;跨域问题&lt;/strong&gt;，在此记录一番。&lt;/p&gt;
&lt;h3&gt;问题回顾&lt;/h3&gt;
&lt;p&gt;博客是静态的东西，所有的 markdown 文档都存储在代码仓库里，在新的 git push 之前是不会有任何内容变化的。而正常的前后端系统是有 db 的，每次操作都对 db 发送了写请求，所以才能做交互。&lt;/p&gt;
&lt;p&gt;评论系统就是一个需要 db 的玩意，那我们懒得为了评论再去写一个后端，这时候就可以把人家写好的评论服务器（包括 db 操作和后端 api）部署下来用。本主题使用的评论系统是 &lt;a href=&quot;https://waline.js.org/&quot;&gt;Waline&lt;/a&gt;。主题作者将评论相关调用的 baseUrl 封装到了配置内，方便使用主题的用户部署好自己的 waline 后端后替换 url，太贴心了~&lt;/p&gt;
&lt;p&gt;交互的路径大概是这样的：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://typora-images-wwweeds.oss-cn-hangzhou.aliyuncs.com/image-20250629071209909.png&quot; alt=&quot;image-20250629071209909&quot;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;所以为啥不把 api 放到云上，直接做成通过 apikey 可得而是要让用户自己部署呢？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;好，现在我已经在 vercel 上部署了 waline 后端系统，假设生成的默认域名是 &lt;strong&gt;example.com&lt;/strong&gt;。那么此时我把该域名替换到 baseUrl 内，此时是无法正常显示数据的，因为出现了&lt;strong&gt;跨域问题&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://typora-images-wwweeds.oss-cn-hangzhou.aliyuncs.com/image-20250629072801797.png&quot; alt=&quot;image-20250629072801797&quot;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;看到这经典的 CORS 报错，有没有感到很亲切~&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;关于跨域&lt;/h3&gt;
&lt;p&gt;这是浏览器的锅，一个 url 里面包括协议、域名、端口号，这三者全部一致才算同源。对于非同源的请求，就会被浏览器拦截。那么这个拦截对于简单请求与复杂请求其实要进一步区分。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;复杂请求的条件包括使用 PUT、DELETE、PATCH 方法、自定义头、application/json Type 等等，比较杂。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;对于简单请求：浏览器拿到了 server 的响应后将数据屏蔽。这种情况下，server 已经执行了请求。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://typora-images-wwweeds.oss-cn-hangzhou.aliyuncs.com/image-20250629085133741.png&quot; alt=&quot;image-20250629085133741&quot;&gt;&lt;/p&gt;
&lt;p&gt;对于复杂请求：浏览器会先发送一个预检请求，如果发现不行了就不发正式请求了。这种情况下，server 没有执行请求。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://typora-images-wwweeds.oss-cn-hangzhou.aliyuncs.com/image-20250629085518572.png&quot; alt=&quot;image-20250629085518572&quot;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;至于为什么会有跨域的屏蔽，这是出于安全性方面的考虑……但实际我们也看到，简单请求也可能更改服务端数据，而返回的响应只是被屏蔽了，服务端实际执行了请求。所以服务端数据安全还得在业务代码里自己保障。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;问题解决&lt;/h3&gt;
&lt;p&gt;我在以前的大学课程项目中经常遇到这个问题，那时候前后端都是自己写的，那么在服务器的请求响应中增加 Access-Control-Allow-Origin 响应头即可。但是现在 waline 后端是写好的，我不想改，怎么办？&lt;/p&gt;
&lt;h4&gt;子域名与同站&lt;/h4&gt;
&lt;p&gt;我先试了一个错误的方法：我的博客有一个域名 blog.com，我把 waline 后端增加了一个域名 waline.blog.com，这是 blog.com 的子域名。其实这显而易见的无法解决跨域问题，因为域名仍然不一样，blog.com 与 waline.blog.com 是非同源的。&lt;/p&gt;
&lt;p&gt;可是 waline.blog.com 与 blog.com 总有些关系吧，那么这个关系的称呼叫作什么？&lt;/p&gt;
&lt;p&gt;叫作同站。TLD（Top Level Domain，顶级域名）以及 TLD + 1 域名一致，就是同站 url。譬如 waline.blog.com 中，com 是 TLD，blog 是 TLD + 1，waline.blog.com 与 blog.com 就是同站请求。&lt;/p&gt;
&lt;p&gt;同站请求虽然仍然会产生跨域拦截（因为不同源），但是与不同站的请求有一个区别，就是会自动携带 cookie。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;cookie 是什么玩意呢，其实就是一些 K-V，里面存储了一些登录状态与用户数据。假如你已经登录了 github.com，那么访问子域名 a.github.com，就会自动携带 cookie，从而直接进入登录状态。更详细的，请参考 &lt;a href=&quot;https://www.ruanyifeng.com/blog/2019/09/cookie-samesite.html&quot;&gt;Cookie 的 SameSite 属性 - 阮一峰&lt;/a&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;子路径解决跨域&lt;/h4&gt;
&lt;p&gt;看来我们必须保证 waline 的服务通过 https://blog.com/xxx 来访问了，这就是我们需要把 waline 服务映射到 blog.com 的子路径上。怎么做呢？我们必须有一个第三方为我们转发请求。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://typora-images-wwweeds.oss-cn-hangzhou.aliyuncs.com/image-20250629091622657.png&quot; alt=&quot;image-20250629091622657&quot;&gt;&lt;/p&gt;
&lt;p&gt;如上图，浏览器并不知道发往 blog.com/waline 的请求被谁接手了，它只知道对方发回了想要的 response，同样的，waline 也不知道是谁发来的请求。第三方对于浏览器和 waline 都是透明的。&lt;/p&gt;
&lt;p&gt;vercel 正好可以充当这个第三方，这种转发请求从而达到更改请求 url 的方法，被称为 rewrite。&lt;/p&gt;
&lt;p&gt;将博客项目部署到 vercel 之后，我们只需要在博客项目内增加 vercel.json，如下：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &quot;rewrites&quot;: [
    {
      &quot;source&quot;: &quot;/waline/:path*&quot;,
      &quot;destination&quot;: &quot;https://waline.blog.com/:path*&quot;
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;vercel 会自动解析，push 后重新部署即可。浏览器发出的请求被 vercel 转发，交给 waline 再传回，我们此刻就成功解决了跨域问题。&lt;/p&gt;
&lt;h4&gt;其他&lt;/h4&gt;
&lt;p&gt;看到 rewrite，你可能会想到 redirect，这两个东西有什么区别呢？&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://typora-images-wwweeds.oss-cn-hangzhou.aliyuncs.com/image-20250629092347462.png&quot; alt=&quot;image-20250629092347462&quot;&gt;&lt;/p&gt;
&lt;p&gt;如上图，浏览器在 redirect 的情况下清楚地知道 server B 的存在，所以在跨域情景下，redirect 无法解决问题，只能是浏览器向 blog.com/waline 请求之后，再次向 waline.blog.com 请求，仍然会被无情拦截。&lt;/p&gt;
&lt;h3&gt;参考文章&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://segmentfault.com/a/1190000022506474&quot;&gt;3 种CORS 错误的方式与 Access - Control - Allow - Origin 的作用原理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://juejin.cn/post/7233698667848777787&quot;&gt;同源与同站&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ruanyifeng.com/blog/2019/09/cookie-samesite.html&quot;&gt;Cookie 的 SameSite 属性 - 阮一峰&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item></channel></rss>