<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
  <title>Ed&apos;s page</title>
  <link>https://jxncted.github.io</link>
  <description>Ed Zou&apos;s personal page</description>
  <language>en</language>
  <lastBuildDate>Tue, 19 May 2026 00:00:00 GMT</lastBuildDate>
  <atom:link xmlns:atom="http://www.w3.org/2005/Atom" href="https://jxncted.github.io/rss.xml" rel="self" type="application/rss+xml" />
<item>
  <title>机器人比赛</title>
  <link>https://jxncted.github.io/blog/2026/reflecting-on-robomaster/</link>
  <guid isPermaLink="true">https://jxncted.github.io/blog/2026/reflecting-on-robomaster/</guid>
  <pubDate>Tue, 19 May 2026 00:00:00 GMT</pubDate>
  <description>记录一下不太成功的机器人比赛参赛经历和反思</description>
  <content:encoded><![CDATA[<h1>机器人比赛</h1>
<h2>第一部分：香港科技大学ENTERPRIZE战队</h2>
<p>我认为大学机器人社团很难形成统一的文化和价值观，因为人员流动的，基本上技术骨干和管理骨干会因为毕业/个人学业分配不断流动，导致社团很难形成统一的价值和体系。在这中间只有口口相传的技术信仰和故事会暂时分别维持一些技术和文化传承。总的来说，ENTERPRIZE（在我加入时）自然形成了如下几个特点：</p>
<h3>1. 现代的技术路线（软件方面）。</h3>
<p>得益于有几个有软件工程和计算机语言基础的前辈，ENTERPRIZE很早的就采取了“现代化”的软件工程结构。比如使用Git/GitHub进行开发管理，使用静态工具（clang-tidy，clang-format）规范化开发，选择性的使用“现代”C++特性（使用OOP，template，generic，不使用动态内存分配，RTTI，exception，不实用标准库）。回过头来看这些选择非常理智正确，一方面用语言的expressiveness简化了开发难度，另一方面也规避了C++中很多不确定的部分。我也是在读到比如<a href="https://arobenko.github.io/bare_metal_cpp/">Bare Metal C++</a>和NASA的<a href="https://www.grc.nasa.gov/www/winddocs/guidelines/pgmstds.pdf">Programming Guidelines</a>之后，结合实践中的经验和部分承担了管理队伍代码管理的职责后，才慢慢理解其中很多看似简朴的道理，即我们不断在高效，简洁，可扩展性上取舍，动态的在拓展代码库功能的同时，努力维护代码规范和设计模式抑制熵增。</p>
<p>另一个方面，ENTERPRIZE经历的多轮技术经验流失（RM队伍中称之为断代），即因为队伍核心成员流失加上长时间不参加补赛，参赛成员需要重新发现/踩坑。一体两面的结果是目前为止，ENTERPRIZE软件方面也没有积累所谓的“技术债”，新的模式积极拥抱，老的屎山积极推翻。</p>
<h3>2. 技术第一</h3>
<p>ENTERPRIZE的团队组成大多数（&gt;90%）来自于理工科院系，最多的应该是计算机工程，综合系统设计，以及机械工程。这样的理工科聚集团队很容易形成一个典型的文化：所有人的兴趣点在于钻研最高水平的技术，容易忽视不太sexy的事情，比如组织人员管理和宣传。从参加比赛性价比来说，RoboMaster比赛对于在香港的同学不算高。主要好处在于：</p>
<ol>
<li>学校比较支持，对于参加机器人相关科研/project可以提供很好的实际上手全栈经验。</li>
<li>队伍“传承”还行，学长学姐有不少在香港学界大组或香港业界大厂。</li>
<li>如果在珠三角创业或者参加创业公司属于技术栈契合，同时学校也有鼓励创业的相关机会。</li>
</ol>
<p>主要坏处在于：</p>
<ol>
<li>时间成本很高，基本上会消耗课业外（或课业中）所有时间。</li>
<li>如果想出国留学或者想回内地找工作，属于不太有帮助的经历（在2026年具身热潮这中稍微好一点点）。</li>
</ol>
<p>回顾来看，ENTERPRIZE 这种&quot;技术第一、其他靠边&quot;的文化是一把双刃剑。一方面，它让队员能够在几乎没有官僚摩擦的环境中快速迭代、深入技术细节，这种氛围对刚入门嵌入式或机器人系统的学生来说极其珍贵——你可以在一个真实的大赛场景里，从零搭建一套完整的机器人软硬件系统，踩遍所有该踩的坑。另一方面，这种文化的代价也很明显：队伍的战斗力高度依赖个别核心成员的个人能力和投入，一旦这些人毕业或精力转移，积累的经验很难沉淀为可复用的方法论。技术可以推翻重来，但组织能力和参赛经验的&quot;断代&quot;却是一次次重复上演。</p>
<p>某种意义上，ENTERPRIZE 给我的最大收获反而不是具体的技术技能，而是对&quot;什么样的团队能持续做出好东西&quot;这个问题有了切身体感——这个问题我在之后的经历中一直在反复验证和修正。</p>
<h3>3. 有文化，无制度</h3>
<p>ENTERPRIZE 几乎没有成文的研发流程。代码怎么写、分支怎么管、需求怎么定、测试怎么做，全靠口口相传和个人自觉。这种状态在一个十来人的小团队里勉强能跑——大家低头不见抬头见，出了问题直接吼一嗓子就解决了。但它的隐性成本很高：新人上手完全依赖学长学姐的面授，一旦中间断了一届，下一届就得从零摸索；同一个坑可能在不同赛季被不同的人反复踩，因为没有人把经验固化成流程。同时一个组织结构也很难scaleup，基本上一个组长管理7-8人小团队，大组长管理4-5个小组长，也就是说一个队伍从管理工具上基本被限制在50有效人员以内。</p>
<p>更深层的问题在于，这种&quot;没有流程&quot;的状态被潜移默化地合理化了——在&quot;技术第一&quot;的文化里，写文档、定规范、画流程图、报账这些事天然被视为不够酷、不够硬核的&quot;杂活&quot;。技术能力强的队员不屑做，想做的人又未必有足够的语境和权威去推动。</p>
<h2>第二部分：重生之</h2>
<p>反过来思考，如果想要在港科组建一个比赛结果为导向的战队，what could have done differently？</p>
<h3>有哪些相关方？</h3>
<p>要想理清究竟该怎么做，第一个方面是要搞清楚有哪些利益相关方。</p>
<ul>
<li>比赛组织者DJI</li>
</ul>
<p>DJI出钱举办比赛，我观察到具体有下面两个利益考量：</p>
<ol>
<li>创始人 Frank Wang 自己本身是 RoboCon 出身，也许有一些从比赛到实业的情怀。</li>
<li>RM 能固定产出“高性价比”的工程人才，同时通过比赛宣传公司价值观，引导相关技术路线。</li>
</ol>
<p>但是同时，比赛组织者和参赛队伍的目标并不完全一致。对 DJI 来说，赛事需要足够好看、足够有传播性、足够能筛选人才；对学校战队来说，真正的问题是如何在有限预算、有限场地、有限学生时间里，把一个高度复杂的工程项目稳定地跑完。这两者有交集，但不是同一个问题。</p>
<ul>
<li>学校和学院</li>
</ul>
<p>学校的诉求相对更分散。一方面，机器人比赛是很好的本科生实践平台，也很适合用来对外展示“学生动手能力强”“学校支持创新创业”之类的形象。另一方面，学校并不会天然理解一支 RM 队伍为什么需要长期场地、采购流程、报账支持、危险品管理、宣传资源和稳定的技术传承。对于学校行政系统来说，比赛往往只是很多学生项目中的一个；对于队伍来说，它却几乎是一个小型工程公司。</p>
<p>所以如果要重来，战队不能只把学校当作“要钱的对象”，而应该把学校当作一个需要持续沟通的合作方。什么东西能换来学校支持？可展示的成果、清晰的安全边界、稳定的预算规划、对本科教学或招生宣传有帮助的产出。这些听起来很功利，但如果不把这些讲清楚，队伍就会长期停留在“几个学生凭热情硬撑”的状态。</p>
<ul>
<li>队员</li>
</ul>
<p>队员的诉求也不是单一的。有人想学技术，有人想打比赛，有人想做简历，有人只是喜欢机械和电控，有人可能只是被朋友拉进来。一个比赛结果导向的战队不能假设所有人都有同样的目标，也不能只靠“热爱”维持投入。热爱很重要，但热爱不是管理制度。</p>
<p>更现实的做法应该是把队员分层：核心研发、稳定执行、短期参与、宣传行政，各自有不同的任务、权限和预期回报。核心研发需要足够高的技术自由度，也要承担文档、评审和带人的责任；稳定执行成员需要明确任务边界和可完成的工作包；短期参与者则应该被安排在低耦合、可快速反馈的任务里。这样听起来不浪漫，但比把所有人都丢进同一个大群里，然后期待大家自然成长要靠谱很多。</p>
<h3>如果目标是赢，应该先承认什么？</h3>
<p>第一件事是承认 RoboMaster 不是一个纯技术比赛。它是技术、组织、资源、时间管理、供应链、学校支持、赛规理解和临场执行的混合体。单点技术强当然有用，但不足以稳定转化成比赛成绩。</p>
<p>第二件事是承认学生队伍天然不稳定。毕业、实习、交换、期末、情绪波动都会打断节奏，所以制度不是为了限制人，而是为了在这些不可避免的波动里保住最低战斗力。一个好的制度应该让新人能接住前人的工作，让普通成员也能稳定贡献，让核心成员离开时队伍不至于直接失忆。</p>
<p>第三件事是承认“赢比赛”和“做有意思的技术”有时候是冲突的。比赛需要的是在规则、时间和资源约束下做最可靠的选择，而不是每个模块都追求最漂亮的方案。</p>
<h3>最小可行的制度</h3>
<p>如果重新设计队伍，我觉得不需要一开始就搞很复杂的流程。学生社团不是公司，流程太重会把热情磨掉，但至少需要几条最小制度。</p>
<h4>1. 招新</h4>
<p>招新不应该只是“找更多人”。很多队伍招新时默认人越多越好，但机器人比赛里，人多不一定等于产出多。没有任务拆分、培训路径和负责人，招来的人越多，沟通成本越高，核心成员反而越累。</p>
<p>我觉得招新应该分成几层。第一层是兴趣筛选，让大家知道 RM 到底是不是自己想象中的“机器人比赛”：它有很酷的部分，也有大量调车、焊线、画板、拧螺丝、报账、等快递和熬夜排查问题。第二层是基础训练，不应该一上来就丢进大项目，而是用几个小任务建立共同语言，比如 CAN 通信、PID、简单机构装配、Git workflow、基本电路调试。第三层才是进入真实模块，让新人在一个有限范围内承担责任。</p>
<p>这里最重要的是反馈周期。新人如果连续一个月不知道自己做的东西有没有意义，很快就会流失。反过来，一个很小但可运行的任务，比如让一个电机按指定速度稳定转起来，或者让一块板子正确读取传感器数据，反而能让人快速建立参与感。队伍真正需要的不是一开始就能独当一面的天才，而是能被系统性培养、逐步接住复杂任务的人。</p>
<h4>2. SOP，文档，和流程</h4>
<p>SOP 听起来很行政，但对于学生战队来说，它本质上是降低记忆负担。很多事情不应该每年都重新发明，比如新电脑怎么配环境，电池怎么管理，赛前检查清单有哪些，采购要提前多久走流程，代码合并前要跑什么检查，真车测试前谁有权把车架起来。这些东西如果只存在于某几个人脑子里，队伍就会被这些人的时间表绑架。</p>
<p>文档也不需要写得像公司内部规范。一个能活下来的文档系统应该足够轻：能说明背景、当前做法、常见坑、负责人和最后更新时间就够了。重要的是文档要和实际工作绑定，而不是赛季结束之后为了总结而补写。比如每次做完一次重要测试，就顺手记录测试条件、现象、结论和下一步；每次做出一个关键技术决策，就记录为什么选这个方案，为什么没有选另一个方案。</p>
<p>流程的目标也不是制造审批，而是明确责任边界。什么时候可以直接改？什么时候必须 review？什么时候必须通知机械、电控、视觉其他组？什么时候需要停止测试？如果这些边界不清楚，队伍就会在两种状态之间来回摆动：平时过度自由，出事后过度紧张。好的流程应该让大多数常规事情自动运行，让真正危险或高成本的事情被提前拦住。</p>
<h4>3. 迭代</h4>
<p>RoboMaster 的系统复杂度很容易诱导一种错觉：只要把所有模块都做到足够好，最后自然会变成一台强车。但真实情况通常相反，很多问题只有整车联调时才暴露，而整车联调又总是最稀缺的资源。所以迭代不能等到所有东西都“差不多做好了”才开始，应该从赛季早期就建立可运行的最小系统。</p>
<p>一个结果导向的迭代节奏，应该尽早得到一台能动、能通信、能安全停下来的车。它一开始可以很丑，功能可以很少，但必须能被反复测试。之后每次增加功能，都应该尽量保持主链路可用。比如先保证底盘和遥控稳定，再接入云台；先保证发射机构机械可靠，再追求射频和弹道一致性；先保证视觉模块能输出可解释的数据，再讨论策略层怎么优化。</p>
<p>迭代还需要明确的止损点。学生项目很容易因为一个技术方案已经投入太多时间而继续硬撑，但比赛不会因为你努力过就降低难度。一个方案如果连续几轮都无法稳定复现，就应该降级、替换，或者先做保守版本。保守版本不是失败，它是给队伍留下继续调试和参赛的余地。</p>
<h3>可能的队伍结构</h3>
<p>如果按结果导向来设计，队伍结构也许不应该完全按传统机械、电控、软件、视觉来切。专业分组当然必要，但比赛产出是以机器人为单位交付的，所以还需要横向的项目负责人。每台车至少应该有一个 owner，负责追踪它的整体状态：机械完成度、电控风险、软件接口、测试记录、备件情况和赛前 checklist。</p>
<p>这样做的好处是问题不会永远停留在“这是哪个组的问题”。真实系统里很多问题都跨组：电机发热可能是机械阻力、控制参数、驱动设置或操作习惯；通信异常可能是线束、协议、任务调度或电源噪声。如果没有整车 owner，这类问题很容易在组和组之间来回踢。owner 不一定要亲自解决所有问题，但要负责把问题推进到有结论。</p>
<p>同时，队伍还需要把“研发”和“比赛执行”分开看。研发关注长期能力，比赛执行关注当下可靠性。临近比赛时，应该有人有权说：这个功能暂时不上，这个模块只保留保守模式，这个问题赛后再重构。否则队伍很容易在赛前最后一周继续做大改，最后每个模块看起来都更先进，但整车更不稳定。</p>
<h2>小结</h2>
<p>写到这里，其实我并不是想说 ENTERPRIZE 做得不好。恰恰相反，我能很明显地感觉到队伍正在越来越好。新同学的水平很高，学习速度也很快，很多人在刚加入不久之后就能做出相当完整的东西。和我刚进队时相比，现在大家能接触到的工具、资料、工程习惯和外部环境都好了很多，队伍也在慢慢形成更成熟的技术审美。</p>
<p>但矛盾也在这里：队伍确实在进步，却也仍然在重复踩一些老坑。很多问题不是因为这一届不够努力，也不是因为某个同学能力不够，而是学生战队天然容易失忆。人员流动太快，经验沉淀太慢，很多过去已经付过代价的事情，如果没有被写下来、制度化、变成新人可以继承的东西，就会在几年后换一种形式重新出现。看到新同学一边变强、一边重新撞上相似的问题，其实是一种很复杂的感受：既欣慰，也有点可惜。</p>
<p>对我个人来说，参加 RoboMaster 带来的影响很难只用“学到了技术”概括。它当然让我接触了嵌入式、控制、机械、电控、视觉、项目管理这些具体东西，也让我第一次比较完整地经历了一个复杂工程系统从想法到实物、从能跑到能比赛的过程。但更重要的是，它让我更早地理解了工程和组织之间的关系：一个系统能不能跑起来，不只取决于某段代码、某块板子、某个算法，也取决于一群人能不能沟通、交接、复盘、承担责任。</p>
<p>这段经历里也有很多不成功的部分。有些比赛没有打好，有些方案最后没有用上，有些问题反复出现，有些时间现在回头看也许可以用得更聪明。但正因为它不是一段被包装得很漂亮的经历，反而更真实地塑造了我对工程的理解。它让我知道什么叫临场压力，什么叫系统复杂度，什么叫“差一点就能跑”和“真的能稳定跑”之间的距离。</p>
<p>所以最后还是感谢这段经历。感谢 ENTERPRIZE，感谢一起熬夜调车、写代码、修线、搬东西、吵架又继续干活的人，也感谢那些失败的测试和不太体面的比赛结果。它们没有给我一个完美的故事，但给了我很多之后仍然会反复用到的判断标准。也希望之后的 ENTERPRIZE 能继续变好，不只是做出更强的机器人，也能把每一届人踩过的坑、建立过的经验、形成过的判断，真正留给下一届。</p>
<p>赛场上的比赛会结束，但现实世界里更复杂、更实际的问题还会一直存在。面对这些问题，单纯的热情和聪明都不够，最终仍然需要有人用科学的态度、工程的方法，以及创业实干家的行动力，把问题拆开、验证、推进、落地。这大概也是机器人比赛留给我最重要的价值：它让我相信，真正值得做的事情，不止发生在赛场上，也发生在赛场之外更漫长、更具体的现实里（这几句是ChatGPT写的，感觉总结的很好😂）。</p>
]]></content:encoded>
</item>
<item>
  <title>Raii</title>
  <link>https://jxncted.github.io/blog/2024/raii/</link>
  <guid isPermaLink="true">https://jxncted.github.io/blog/2024/raii/</guid>
  <pubDate>Mon, 01 Jan 2024 00:00:00 GMT</pubDate>
  <description>Notes on safer resource management in C++.</description>
  <content:encoded><![CDATA[<blockquote>
<p>这是一系列关于C++的学习笔记。</p>
</blockquote>
<h2>著名的C++内存安全</h2>
<p>2019年，微软发布了一篇著名的文章，<a href="https://msrc.microsoft.com/blog/2019/07/a-proactive-approach-to-more-secure-code/"><em>A proactive approach to more secure code</em></a>，主要结论是有大概70%的安全漏洞来自于不安全的内存。那么作为“现代”的程序员，怎样可以不容易Shoot yourself in the foot呢？同时，因为exception的设计，程序运行的path有的时候不可预测，有的时候很难管理。如果再throw exception的时候，资源没有被释放，那么就会造成资源泄漏。</p>
<h2>RAII</h2>
<p>两个个人理解的重点：</p>
<ol>
<li>应该基于内存管理更少的自由。</li>
<li>应该基于资源的所属权做出明确的划分。</li>
</ol>
<p>由此引出了对于有 <em>明确生命周期</em>（invariant）的资源的管理方式：RAII，即Resource Acquisition Is Initialization。</p>
<h2>一个简单的例子</h2>
<p>RAII适合管理有明确获取（acquire）和释放（release）的资源，比如文件句柄、内存、锁等。下面是一个简单的例子：</p>
<h3>手动管理文件</h3>
<pre><code class="hljs language-cpp"><span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&lt;fstream&gt;</span></span>

<span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
    FILE* file = <span class="hljs-built_in">fopen</span>(<span class="hljs-string">&quot;example.txt&quot;</span>, <span class="hljs-string">&quot;w&quot;</span>);
    <span class="hljs-built_in">some_complex_function_that_may_throw_exception</span>();
    file &lt;&lt; <span class="hljs-string">&quot;Hello, RAII!&quot;</span>;
    file.<span class="hljs-built_in">close</span>(); <span class="hljs-comment">// release</span>
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}</code></pre><p>可以看到，如果在<code>some_complex_function_that_may_throw_exception</code>中抛出了异常，那么<code>file.close()</code>就不会被调用，造成资源泄漏。</p>
<h3>使用RAII管理文件</h3>
<pre><code class="hljs language-cpp">
<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&lt;fstream&gt;</span></span>

<span class="hljs-keyword">class</span> <span class="hljs-title class_">File</span> {
<span class="hljs-keyword">public</span>:
    <span class="hljs-built_in">File</span>(<span class="hljs-type">const</span> std::string&amp; filename) : <span class="hljs-built_in">file</span>(filename) {}
    ~<span class="hljs-built_in">File</span>() { file.<span class="hljs-built_in">close</span>(); }
    <span class="hljs-function">std::ofstream&amp; <span class="hljs-title">get</span><span class="hljs-params">()</span> </span>{ <span class="hljs-keyword">return</span> file; }
<span class="hljs-keyword">private</span>:
    std::ofstream file;
};

<span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
    <span class="hljs-function">File <span class="hljs-title">file</span><span class="hljs-params">(<span class="hljs-string">&quot;example.txt&quot;</span>)</span></span>;
    <span class="hljs-built_in">some_complex_function_that_may_throw_exception</span>();
    file.<span class="hljs-built_in">get</span>() &lt;&lt; <span class="hljs-string">&quot;Hello, RAII!&quot;</span>;
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>; <span class="hljs-comment">// 资源会在File析构的时候被释放</span>
}</code></pre><h3>另一个lock_guard的例子</h3>
<p>RAII与其说是一种模式，不如说是一种思想。STL中已经存在了很多RAII的实现，比如<code>std::lock_guard</code>，它的构造函数会lock一个mutex，析构函数会unlock这个mutex。这样就可以保证在任何情况下，mutex都会被正确释放。</p>
<pre><code class="hljs language-cpp"><span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&lt;mutex&gt;</span></span>

std::mutex mtx;

<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">print_block</span><span class="hljs-params">(<span class="hljs-type">int</span> n, <span class="hljs-type">char</span> c)</span> </span>{
    <span class="hljs-function">std::lock_guard&lt;std::mutex&gt; <span class="hljs-title">lck</span><span class="hljs-params">(mtx)</span></span>; <span class="hljs-comment">// acquire lock</span>
    <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i=<span class="hljs-number">0</span>; i&lt;n; ++i) { std::cout &lt;&lt; c; }
    std::cout &lt;&lt; <span class="hljs-string">&#x27;\n&#x27;</span>;
    <span class="hljs-comment">// automatically release lock</span>
}

<span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
    <span class="hljs-function">std::thread <span class="hljs-title">th1</span><span class="hljs-params">(print_block,<span class="hljs-number">50</span>,<span class="hljs-string">&#x27;*&#x27;</span>)</span></span>;
    <span class="hljs-function">std::thread <span class="hljs-title">th2</span><span class="hljs-params">(print_block,<span class="hljs-number">50</span>,<span class="hljs-string">&#x27;$&#x27;</span>)</span></span>;

    th<span class="hljs-number">1.</span><span class="hljs-built_in">join</span>();
    th<span class="hljs-number">2.</span><span class="hljs-built_in">join</span>();

    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}</code></pre><h2>Smart Pointers</h2>
<p>另一个C++允许你做的蠢事是使用<code>new</code>和<code>delete</code>来手动管理堆上的内存。</p>
<p><a href="http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#r11-avoid-calling-new-and-delete-explicitly">别这么做</a>。</p>
<p>C++11引入了<code>std::unique_ptr</code>和<code>std::shared_ptr</code>，它们是RAII的实现，可以帮助你管理堆上的内存。</p>
<pre><code class="hljs language-cpp"><span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&lt;memory&gt;</span></span>

<span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
    <span class="hljs-function">std::unique_ptr&lt;<span class="hljs-type">int</span>&gt; <span class="hljs-title">p1</span><span class="hljs-params">(<span class="hljs-keyword">new</span> <span class="hljs-type">int</span>(<span class="hljs-number">5</span>))</span></span>;
    std::cout &lt;&lt; *p1 &lt;&lt; std::endl;
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>; <span class="hljs-comment">// p1会在main函数结束的时候被释放</span>
}</code></pre><section class="footnotes" aria-label="References">
<h2>References</h2>
<ol>
<li id="fn-1">
<p><a href="http://web.stanford.edu/class/cs106l/">Stanford CS106L</a></p>


</li>
<li id="fn-2">
<p><a href="http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines">ISO C++ Core Guidelines</a></p>


</li>
<li id="fn-3">
<p><a href="https://en.cppreference.com/w/cpp/memory">Smart Pointers</a></p>


</li>
</ol>
</section>]]></content:encoded>
</item>
<item>
  <title>超越性， 说点怪话</title>
  <link>https://jxncted.github.io/blog/2023/transcendent/</link>
  <guid isPermaLink="true">https://jxncted.github.io/blog/2023/transcendent/</guid>
  <pubDate>Fri, 08 Sep 2023 00:00:00 GMT</pubDate>
  <description>关于逻辑、计算和日常生活的一些想法。</description>
  <content:encoded><![CDATA[<p>要么是人的注意力作怪，要么是相似的事情就是会集中发生，总之最近总有一些事触发对超越性这件事的思考。</p>
<ol>
<li>家里小孩新养了一只小鸟，会和镜子里的自己打架。</li>
<li>电影《奥本海默》上映。</li>
<li>新学期上了一门关于computation theory的课。</li>
</ol>
<p>总之总之，从理发师悖论说起，</p>
<blockquote>
<p>城里有一个理发师，他给且只给不自己刮胡子的人刮胡子。那么问题是他是否会给自己刮胡子呢？</p>
</blockquote>
<p>如果随便表达以下的话，</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.25em" columnalign="center" columnspacing="0em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mi>R</mi><mo>=</mo><mo stretchy="false">{</mo><mo stretchy="false">(</mo><mi>a</mi><mo separator="true">,</mo><mi>b</mi><mo stretchy="false">)</mo><mo>:</mo><mi>a</mi><mtext>给</mtext><mi>b</mi><mtext>刮胡子</mtext><mo stretchy="false">}</mo></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><msub><mi>R</mi><mi>a</mi></msub><mo>=</mo><mo stretchy="false">{</mo><mi>b</mi><mo>:</mo><mo stretchy="false">(</mo><mi>a</mi><mo separator="true">,</mo><mi>b</mi><mo stretchy="false">)</mo><mo>∈</mo><mi>R</mi><mo stretchy="false">}</mo><mtext>，这个集合表示所有被</mtext><mi>a</mi><mtext>刮胡子的人</mtext></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mi>D</mi><mo>=</mo><mo stretchy="false">{</mo><mi>a</mi><mo>:</mo><mo stretchy="false">(</mo><mi>a</mi><mo separator="true">,</mo><mi>a</mi><mo stretchy="false">)</mo><mo mathvariant="normal">∉</mo><mi>R</mi><mo stretchy="false">}</mo><mo separator="true">,</mo><mtext>表示了所有不给自己刮胡子的人</mtext></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{gathered}
R = \{(a, b): a给b刮胡子\} \\
R_a = \{b: (a, b) \in R \}， 这个集合表示所有被a刮胡子的人  \\
D = \{a: (a, a) \notin R\}, 表示了所有不给自己刮胡子的人
\end{gathered}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:4.5em;vertical-align:-2em;"></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.5em;"><span style="top:-4.66em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mopen">{(</span><span class="mord mathnormal">a</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">b</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">:</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mord mathnormal">a</span><span class="mord cjk_fallback">给</span><span class="mord mathnormal">b</span><span class="mord cjk_fallback">刮胡子</span><span class="mclose">}</span></span></span><span style="top:-3.16em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1514em;"><span style="top:-2.55em;margin-left:-0.0077em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">a</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mopen">{</span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">:</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mopen">(</span><span class="mord mathnormal">a</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">b</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="mclose">}</span><span class="mord cjk_fallback">，这个集合表示所有被</span><span class="mord mathnormal">a</span><span class="mord cjk_fallback">刮胡子的人</span></span></span><span style="top:-1.66em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mopen">{</span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">:</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mopen">(</span><span class="mord mathnormal">a</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">a</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel"><span class="mord"><span class="mrel">∈</span></span><span class="mord vbox"><span class="thinbox"><span class="llap"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="inner"><span class="mord"><span class="mord">/</span><span class="mspace" style="margin-right:0.0556em;"></span></span></span><span class="fix"></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="mclose">}</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord cjk_fallback">表示了所有不给自己刮胡子的人</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2em;"><span></span></span></span></span></span></span></span></span></span></span></span>
<p>理发师悖论的重点在于<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>R</mi><mi>a</mi></msub><mo mathvariant="normal">≠</mo><mi>D</mi></mrow><annotation encoding="application/x-tex">R_a \neq D</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1514em;"><span style="top:-2.55em;margin-left:-0.0077em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">a</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel"><span class="mrel"><span class="mord vbox"><span class="thinbox"><span class="rlap"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="inner"><span class="mord"><span class="mrel"></span></span></span><span class="fix"></span></span></span></span></span><span class="mspace nobreak"></span><span class="mrel">=</span></span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span></span>。让我惊讶的事情是，理发师悖论，某种本质上和以下说法（？）有像是同源的解释，但是对我来说直观上很难建立联系。它们之间各有在我看来截然不同的逻辑和理解</p>
<ul>
<li>抽屉原理</li>
<li>实数是不可数集</li>
<li>Diagonalization principle</li>
<li>不是所有问题都有解</li>
</ul>
<h2>我</h2>
<p>《奥本海默》电影中，奥本海默请教爱因斯坦关于原子弹点燃大气层时，身边短暂的出现了一位疯癫的人，他就是哥德尔。自治，也就是我是构建这些东西的来源（或者一种来源）。因为自指，我们用diagonalization构建和抽屉原理，说明了不是所有问题都有解决方法（大概是这个流程吧）。同样的自指，哥德尔证明证明了包含皮亚诺算数系统的公理体系是不完备的，是不一致的。那么有人用相似的逻辑得出结论说人工智能永远无法在限定的规则中发展出真正的智能。</p>
<p>来点递归话</p>
<ul>
<li>我是这个句子的主语。</li>
<li>人类从历史中得到的唯一教训就是人类无法得到任何教训。</li>
<li>GNU&#39;s Not Unix</li>
</ul>
<p>又从智力上来说，认识到自己的存在是高等智慧的表现。海豚可以认出镜子中的自己，而家里养的小鸟认为镜子中的自己不是自己，和自己打架。小孩在经典数数问题“现在屋里有几个人”中，可以通过会不会数自己来初步判断其智力水平。</p>
<p>又又从哲学一点角度来说，人类的感性思维是可以理解这种不自洽的，无法被证明的系统的。我们仿佛天生的就理解矛盾这个“我”这个核心又复杂的符号，心思细腻的人在审美的时候可以区分“以我观物”和“以物观物“，认识到“我”作为意识的主题可以是抽象的精神符号，又可以是具象改变物质实体的推动力。</p>
<blockquote>
<p>有我之境，以我观物，故物我皆著我之色彩。无我之境，以物观物，故不知何者为我，何者为物。</p>
</blockquote>
<p>又要借助那个著名的比喻，酒神和日神。象征理性的太阳神阿波罗，引导了对称，逻辑，和节制。但总会有象征这诗歌和醉酒的酒神狄奥尼索斯的一面，那个本能的，在价值观，理性，和道德约束下的另一个面。而也许和数学一样，对于“我”这个概念的认识是实现超越自身这个系统的钥匙。</p>
<p>[2023-9-8]</p>
]]></content:encoded>
</item>
<item>
  <title>2022年末</title>
  <link>https://jxncted.github.io/blog/2022/year-of-2022/</link>
  <guid isPermaLink="true">https://jxncted.github.io/blog/2022/year-of-2022/</guid>
  <pubDate>Sat, 31 Dec 2022 00:00:00 GMT</pubDate>
  <description>年终回顾和个人随笔。</description>
  <content:encoded><![CDATA[<p>又到了总结一年和制定不会完成的新年计划的时候了。</p>
<h2>2022</h2>
<h3>主线：大学生活和GPA</h3>
<p>课程上，大学要求在非常有限的时间内熟悉且使用要几门课程的内容。这就有以下几个问题</p>
<ul>
<li>靠课程内容很难“学会”一门课程。大多数学习时间集中在期中和期末考试前，且考试内容往往是课程内容的一个子集。这很无聊（当然也因为我很菜）。<br>大多数课程的内容的优点大概是“这大概有一天会有用吧”，同时缺点就是以上陈述的补集。我始终认为，优质的内容是有趣的，学习它们应该是劳累<br>但是充实的。我在大学的第一年仅仅只有很少的课程是满足这个标准的。引用一下《费曼物理讲义》中的一段话：</li>
</ul>
<blockquote>
<p>The special problem we tried to get at with these lectures was to maintain the interest of the very enthusiastic and rather smart students<br>coming out of the high schools and into Caltech. They have heard a lot about how interesting and exciting physics is—the theory of relativity,<br>quantum mechanics, and other modern ideas. By the end of two years of our previous course, many would be very discouraged because there were<br>really very few grand, new, modern ideas presented to them. They were made to study inclined planes, electrostatics, and so forth, and after<br>two years it was quite stultifying.<br>--<cite>Richard Feynman, The Feynman Lectures on Physics</cite></p>
</blockquote>
<ul>
<li>当然同时，正是如此，想要至少得到“还说的过去给”的成绩是更简单的。我一直在有意识的尝试如何用比较少的时间“应付”课程，再把剩下的时间“正确”地浪费掉。<br>方法论依旧处于实验阶段，现阶段的总结是<ol>
<li>找一个会的人教，效率会很高。当然这个人大概率不是教授，大多教授拥有完全的理论知识，却总是忘记了自己不懂的时候的感觉。这个人首选是取得好成绩的学长、<br>  努力学习同时不忘大庇天下的同学、亦或者是拥有激情的TA。当然，这个人也可能是你自己。</li>
<li>past paper是起点。寻找同一个教授的past paper可以很容易掌握一门课的主线。</li>
<li>同2，掌握主线。一门课程大多有它最最重要的一条逻辑，几个概念，几个必须要熟练的操作/公式。掌握这些，就能在考试中获得高于平均水平的成绩（是的，<br>  这就是当代大学生的平均水平）。</li>
<li>利用office hour。这个是最近才开始尝试的，但是却是非常有效的。</li>
<li>最终最终，好好选课，别被课程名字和描述给骗了。</li>
</ol>
</li>
<li>当然以上只是不得已。同时要提醒提醒自己，别忘了什么是重要的，上课的时候不妨俯瞰一下，别让垃圾课程把热情和时间吃掉了。</li>
</ul>
<h3>支线1：RoboMaster</h3>
<p>接下来就是支线任务。首当其冲（没错，首当其冲），就是RoboMaster机器人竞赛。</p>
<ul>
<li>这是学习知识和应用的机会。它很好的回答了课程的问题，即“这东西你别管你懂不懂，用了就管用”，属于是另一个极端吧。当然，只要但凡有一点点对于知识的好奇，就<br>可以很轻松学到非常多，非常广的东西。</li>
<li>这是一个学习合作的机会。虽然很强的人可以几乎单打独斗实现大部分的目标，但是这个比赛的复杂程度和时间的限制，使得任何人都需要学着和一起完成任务。<br>在这个过程中会发现，最直接的方法往往是自己快速学一下，干一下，事情就完成了。这个过程会强迫自己学很多东西，但同时也某种程度上限制了取得更好成绩的上限。怎样<br>管理自己，怎样管理别人，怎样把目标各有不同的一群人合作起来，也许也需要研究。</li>
</ul>
<h3>支线2：心理和生理健康</h3>
<p>最新的认识是</p>
<ol>
<li>生理健康是心理健康的基础。因此只要正常进食，正常睡眠，人类自我调节的能力大多数时候就可以保持良好的状态。</li>
<li>所谓“人生是人生就是在痛苦和无聊二者之间像钟摆一样摆来摆去”， 这个摆锤是倒立的，静不稳定的。重点是保证闭环动态调整的能力。</li>
<li>和人交流是重要的。但是人是只在意自己的动物。因此需要自己保持稳定。</li>
<li>需要音乐。</li>
<li>有氧运动也很重要，需要加多一些。</li>
</ol>
<h3>支线3：寻找方向</h3>
<p>没有进展。</p>
<h3>2022？</h3>
<p>那么有点像鸡汤的2022大概就是这样。那么又到了一句话总结时间：</p>
<blockquote>
<p>悠然心会，妙处难与君说。</p>
</blockquote>
<p>所以总结了啥，我也不知道。</p>
<h2>2023？</h2>
<p>那么2023会有什么不一样呢？大概不会有什么不一样吧。也别想着有太多计划/目标，绝对不是因为我懒。那同样用一句不知所云的话来描述一下：</p>
<blockquote>
<p>金风玉露一相逢，便胜却，人间无数。</p>
</blockquote>
<p>追求更高的境界，看高一点的风景。</p>
<p>[2022-12-31]</p>
]]></content:encoded>
</item>
<item>
  <title>Why Blogging Over Social Media</title>
  <link>https://jxncted.github.io/blog/2022/why-blogging-over-social-media/</link>
  <guid isPermaLink="true">https://jxncted.github.io/blog/2022/why-blogging-over-social-media/</guid>
  <pubDate>Mon, 26 Dec 2022 00:00:00 GMT</pubDate>
  <description>Why long-form blogging can be more personal and durable.</description>
  <content:encoded><![CDATA[<p>The answer is I don&#39;t know. I&#39;m just going to try it out and see how it goes.<br>Compare to social media, blogging is</p>
<ul>
<li>more personal and less public</li>
<li>more permanent and less ephemeral</li>
<li>more focused and less scattered</li>
<li>more thoughtful and less reactive</li>
</ul>
<p>More importantly, forcing myself to formalizae longer pieces of text has the<br>benefit to help me think more clearly and more deeply.</p>
<p>The blog posts will share no common theme. They may be about my personal<br>experiences, my thoughts, my study notes, or anything else that I find<br>interesting enough to be put down into words. I will try to keep them short<br>and concise, but I will not limit myself to a certain word count.</p>
<p>I will try to keep updating and I guess we will see how it goes.</p>
<p>[2022-12-26]</p>
]]></content:encoded>
</item>
</channel>
</rss>
