做资料合集这件事,最容易翻车的地方从来不是“找不到东西”,而是“找到太多”。我从第一期整理到现在的第二十四期,中间删掉过的条目比留下的还多,原因很朴素:一份自动驾驶合集如果只是把论文、开源仓库、教程链接堆在一起,那它的生命周期基本就是收藏夹吃灰。真正有用的合集,得能回答三个问题——这个条目解决的是整条链路里哪一段的问题、它的输入输出契约是什么、把它拿过来我需要付出多少适配成本。这篇就把这套整理思路摊开讲,顺带把感知、预测、规划、数据闭环、工程落地这几段里我认为最值得反复回看的技术点拆细,适合刚进这个方向想搭知识框架的人,也适合已经做过一两个模块、想把碎片经验串成体系的人。文中涉及的参数和量级,多数是行业里比较常见的工程取值,我用来说明取舍逻辑,不是硬标准,落到具体项目上还得按自己的传感器配置和算力重新标定。
1. 合集的归档口径决定了它三年后还能不能用
我最早两期是按年份和热点归档的,结果很快就发现一个问题:同一个话题会在不同年份以不同深度反复出现,2019年讲的是传统滤波跟踪,2022年讲的是基于查询的跟踪,如果按时间排,读者要跨十几个条目才能拼出一条完整的技术演进线。更麻烦的是热点驱动归档会天然放大短期流行度,某一年某类特征表达方式集中爆发,合集里一半条目都指向同一个方向,反而把更基础的标定、同步、评测这些“不出彩但决定成败”的部分挤没了。所以从第六期开始我改成了按技术栈分层,每层有明确的输入输出边界,条目按“它在这层里补了哪块砖”来定位。
1.1 六层分层法:让每个条目都能被定位
我把整条链路切成六层,切法不追求学术严谨,追求的是“一个条目扔进来我能立刻知道它属于哪层、跟谁对接”。
| 层级 | 核心问题 | 输入 | 输出 |
|---|---|---|---|
| L0 数据与标定 | 我怎么知道传感器看到的东西在同一个时空里 | 原始点云、图像、组合导航 | 统一坐标系下的对齐数据 |
| L1 感知 | 周围有什么、在哪、往哪动 | 对齐后的多模态数据 | 目标框/语义/占用栅格/跟踪轨迹 |
| L2 预测 | 它们接下来几秒会怎么动 | 历史轨迹、地图、交互对象 | 多模态未来轨迹及概率 |
| L3 规划决策 | 我该做什么动作、走哪条线 | 预测结果、地图、自车状态 | 行为决策 + 可行轨迹 |
| L4 控制执行 | 怎么把轨迹变成方向盘和踏板指令 | 参考轨迹、车辆状态 | 横纵向控制量 |
| L5 工具链与闭环 | 我怎么证明它比上一版好 | 日志、场景库、评测脚本 | 指标、回归报告、问题清单 |
这么切的好处很直接:每个条目进来先问一句“它的输出喂给谁”,答不上来的基本就是综述性质或者纯理论推导,我会单独放到“背景阅读”里,不占正式条目名额。另一个隐性收益是,按层归档之后很容易看出哪一层条目严重偏多、哪一层几乎是空的。我自己的合集里L1占了将近四成,L5只有一成出头,这个比例其实很不健康——实际项目里后期卡住进度的往往就是L5。
1.2 收录判据:六条硬门槛筛掉八成噪音
我给每个候选条目设了六条判据,满足四条以上才进正式列表,这个门槛筛掉的量比想象中大。
- 输入输出写清楚了:方法部分能明确说出“吃什么、吐什么”,尺寸、频率、坐标系至少交代两样。
- 实验设置有可复现性:用了什么数据规模、什么硬件、训练多久,哪怕只给量级也行。
- 有失败案例分析:只报成功指标的条目我基本不信任,愿意写清楚“什么情况下会崩”的才有参考价值。
- 有时延或算力的实测数字:自动驾驶是个强实时系统,一个精度很高但推理要两百毫秒的方案,在车上等于不可用。
- 有边界条件说明:雨天、夜间、逆光、隧道出入口这些场景有没有覆盖,没覆盖至少要说一句。
- 有可复用组件:哪怕只是一个数据预处理脚本或者一个评价函数,也比纯文字描述强。
反过来,有几类条目我后来一律不收:只给最终指标不给中间过程的、指标高得离谱但没说明数据划分的、把公开数据集刷到接近饱和却完全不提泛化性的。这些内容读起来爽,落到自己项目上一行代码都用不上。
1.3 每个条目强制填六个字段
光有分层和判据还不够,条目本身的信息结构得统一,否则半年后自己都看不懂当初为什么收它。我要求每条至少写清六件事:来源与时间、问题定义(一句话说清它想解决什么)、方法要点(不超过五行,逼自己提炼)、实验条件(数据规模/硬件/耗时)、已知局限、可复用组件(代码、配置、评价脚本)。这六个字段里,我认为最有价值的是“已知局限”和“可复用组件”,前者帮你避免重复踩坑,后者帮你省下重复造轮子的时间。实际操作中我发现,写“已知局限”最费劲,因为很多条目自己也未必写得清楚,这时候我会补一句“待验证”,而不是硬编一个局限出来——合集里最怕的就是自己给自己制造二手错误。
2. 感知这一段:八成疑难问题出在时空对齐
感知层的条目最多,也最容易让人产生“方法学不完”的焦虑。但我复盘过自己排查过的那些问题,真正卡住进度的很少是网络结构选得不对,绝大多数都能追到时空对齐上。举个很具体的例子:两个传感器的时间戳差10毫秒,在静止或者低速场景下几乎看不出来,但车速到20米每秒时,这10毫秒就是0.2米的位移;如果目标本身也在动,相对位移还会叠加。这个量级已经超过了紧凑型目标检测的定位精度要求,你会看到融合结果里目标框“发飘”,然后花两周时间去调网络,最后发现是时间戳的问题。
2.1 外参、时间戳与坐标系的误差传导计算
外参误差的传导更隐蔽。假设俯仰角外参有0.1度的偏差,在50米处产生的横向误差大约是50×tan(0.1°)≈0.087米,看起来不大;但如果这个偏差是滚转角引起的,远处地面的投影会发生整体倾斜,导致地面点被误判为障碍物,或者障碍物被压进地面。我做合集时特意收了几篇讲误差传导推导的条目,就是因为这类内容能让你在动手调参之前先算出“这个偏差值不值得修”。
坐标系这块我踩过的坑是混用。车体系、世界系、各传感器系、图像系,四个坐标系之间的转换在代码里往往是散落在各处的几个矩阵乘法,一旦有人改了其中一个的定义(比如车体系原点从后轴中心挪到质心),整个链路的结果都会漂,而且不会报错。后来我的做法是强制所有跨模块的数据都带一个坐标系标签,转换函数只接受带标签的数据,标签不匹配直接抛异常。这个习惯看起来笨,但它把一类极难排查的静默错误变成了启动就能发现的显式错误。
2.2 前融合、特征级融合、后融合的取舍逻辑
融合路线这块,合集里三种都有,我给它们的定位是这样的:
| 路线 | 做法 | 优势 | 代价 | 适用场景 |
|---|---|---|---|---|
| 前融合 | 原始数据层对齐后统一编码 | 信息损失最小,弱目标保留好 | 对时间同步和外参精度极敏感,标定成本高 | 传感器刚性安装、标定稳定的平台 |
| 特征级融合 | 各模态提特征后在统一空间交互 | 兼顾精度与鲁棒性,工程上最常选 | 需要设计特征对齐方式,调参空间大 | 主流量产方案 |
| 后融合 | 各模态独立出结果再关联 | 模块解耦,单传感器失效可降级 | 关联环节容易出错,信息利用不充分 | 传感器异构、算力受限 |
我个人的倾向是:不要一上来就冲前融合。前融合的收益建立在标定质量足够好的前提上,如果你的外参是靠手工量的、没有在线标定能力,前融合带来的对齐误差可能比它省下的信息损失还大。反过来,如果平台传感器是刚性安装、出厂做过精密标定,前融合在远距离弱目标上的优势确实明显。这个判断在合集里我用“标定条件”作为一个检索维度,方便按自己的实际情况筛。
2.3 一次小目标漏检的完整排查链路
去年整理某一期时,我自己顺手复现了一个检测方案,在公开数据上指标正常,但换到自己录的一段城市场景里,50米开外的锥桶和行人漏检明显。我把排查过程完整记进了合集,因为这类链路比结论更有价值。
第一步先确认真值本身有没有问题。我把漏检帧的点云单独拉出来看,发现有些目标在标注里确实被漏了——标注规范里对“被遮挡超过一定比例”的目标是允许不标的。这一下就排除掉了一部分“假漏检”。
第二步看点云密度随距离的衰减。机械式激光雷达的线束是发散的,50米处的相邻线束间距可能是近处的十几倍,远处一个锥桶可能只落到一两根线上。这种情况下网络再强也没用,信息本身就不够。我统计了漏检目标在点云里的实际点数分布,发现大部分漏检目标的点数低于一个很低的阈值,说明问题出在输入侧而不是网络侧。
第三步查体素化和下采样。原方案为了控制显存,把体素尺寸设得比较大,远处小目标在体素化之后直接消失了。把体素尺寸调小、同时对远处区域做非均匀划分之后,漏检率降了一大截,代价是推理时间涨了约三成。
第四步才轮到网络和阈值。检查了正负样本分配策略,发现小目标因为落在少数几个网格里,正样本数量严重不足;又检查了非极大值抑制的阈值,阈值偏高时相邻的密集目标会被误抑制。这两处调完,指标才回到可用区间。
这条链路的顺序很关键:先查真值,再查输入,然后查预处理,最后才动模型。我见过太多人直接从第四步开始,改了一堆超参,指标上下浮动,但根本没解决根因。
3. 预测与规划:把“会开”拆成能被验证的子问题
预测和规划这两层在合集里最容易被写得玄乎,因为“像人一样开车”这种表述没法验证。我的处理办法是强制拆成可验证的子问题:预测层只回答“其他交通参与者未来几秒的位置分布”,规划层只回答“在这条分布下我走哪条轨迹能同时满足安全和通行效率”。一旦这么拆,很多模糊的讨论就落地了。
3.1 预测模块真正难的是不确定性怎么表达
预测的头号误区是只输出一条最可能的轨迹。这在简单跟车场景下看着没问题,一旦遇到路口、并线、非机动车横穿这类多意图场景,单条轨迹必然在多个可能之间取平均,而平均出来的轨迹往往一条都不成立——既不像左转也不像直行,规划层拿到这种输入会做出莫名其妙的选择。
合集里我收的预测类条目,大部分都在处理多模态输出和概率校准。常见做法是预设一组轨迹锚点,网络对每个锚点输出偏移量和概率,最后保留概率最高的若干条。这里有两个容易忽略的点:一是概率之和要归一,但很多实现直接对分数做归一化,导致概率不可比;二是概率的校准,也就是“我说80%概率的轨迹,实际应该落在80%的置信区间里”,这个指标很少有人报,但规划层如果按概率做风险决策,校准不好会直接导致决策偏保守或偏激进。
损失函数的选择也有讲究。纯回归损失会让模型倾向于输出均值,正好踩中上面说的“平均轨迹不成立”;换成对多条候选做分类加回归,能缓解这个问题,但会引入模式坍缩——模型可能只输出某一类轨迹,其他候选的概率被压到很低。我在合集里专门标了几篇讨论这个权衡的条目,因为这是实际训练中最常遇到的。
3.2 行为决策和轨迹优化的职责边界
规划层我习惯分两级:行为决策负责离散选择(保持车道、变道、跟车、让行、通过路口),轨迹优化负责在选定行为下生成连续、平滑、可执行的轨迹。这两级的运行频率不一样,行为决策一般几赫兹到十赫兹就够,轨迹优化通常要十几到二十赫兹,因为下层控制需要足够新的参考。
把两级分开的核心原因是为了可解释性和可调试性。当车辆做出一个不合理的动作时,你可以先问“是行为选错了还是轨迹生成错了”,这两个问题的排查路径完全不同。如果做成一个大一统的优化问题,出了问题只能看到一个结果,中间过程全是黑盒。
轨迹优化里的常见约束包括:曲率约束(对应车辆最小转弯半径)、加速度和加加速度约束(对应舒适性)、横向偏移约束(对应车道边界和障碍物安全距离)、动力学可行性约束。这里有一个实操经验:加加速度约束不要设得太紧。理论上限制得越死越舒适,但实际会让优化问题在很多场景下无解,尤其是需要紧急避让的时候。我一般会给一个正常工况的紧约束和一个紧急工况的松约束,按场景切换。
3.3 规则与学习混合是现阶段的工程共识
合集中关于“端到端”的条目我一律归到背景阅读,不是不看好,而是现阶段真正能上车的方案基本都是混合架构:用学习方法处理感知和预测这些高维、难写规则的部分,用规则或优化方法保证规划控制的确定性和可验证性。这么做不是因为保守,而是因为安全兜底必须是确定性的——你没法给一个神经网络写单元测试,但你可以给“前车距离小于阈值时必须减速”写一条断言。
混合架构的接口设计是关键。我的经验是让规则层掌握最终否决权,学习层输出建议。比如规划层给出了一条轨迹,规则层做一次快速校验:是否越过车道边界、是否与预测轨迹的最小距离低于安全阈值、曲率是否超出车辆能力。任何一项不通过就触发降级策略(减速、跟车、靠边)。这个校验必须足够轻量,控制在几毫秒内,否则它会成为整个链路的新瓶颈。
4. 数据闭环与仿真:被低估却决定上限的一段
前二十期我的合集里这一段几乎空白,直到有几个朋友反馈“复现了方法但效果差很远”,我才意识到问题不在方法本身,而在数据。公开数据集给你的是一个已经清洗好、分布均衡的样本集合,而真实车上采回来的数据是长尾极度不均衡的:百分之九十的时间在直道上匀速,剩下百分之十里有一半是重复场景。不做闭环,模型的提升很快会撞墙。
4.1 数据挖掘的触发条件怎么设计
我现在用的触发规则大概是这几类:人工接管事件(尤其是急刹和猛打方向)、规划模块求解失败或触发降级、感知置信度低于阈值且持续若干帧、自车与前车的时间间隔低于某个安全值、以及固定里程的均匀采样作为对照组。前四类是“有问题”的样本,最后一类是“看起来没问题”的样本,两类都要,因为只看问题样本会让训练集分布严重偏移。
这里有个反直觉的经验:接管事件不等于模型错了。很多接管是因为驾驶员不耐烦、或者对系统能力边界不了解而提前介入。我早期把全部接管都当作负样本,结果训练出来的模型异常保守,路口不敢走。后来加了一步人工复核,把接管分成“系统确实处理不了”和“驾驶员主观介入”,只把前者作为高价值样本,效果才正常。
数据闭环还有一个容易被忽略的环节是标注一致性。同一批数据如果分给不同标注员,边界框的松紧习惯可能差出十几个像素,训练时这些差异会变成噪声。我的做法是每个批次抽样做交叉复核,算标注员之间的一致性,低于阈值就重新培训。这件事很枯燥,但它对最终指标的影响比换个网络结构大得多。
4.2 回放仿真和闭环仿真的分工
仿真这块,我把它分成两类用途完全不同的工具。回放仿真(把真实日志灌进系统,跑一遍完整的感知预测规划链路,但不让仿真结果反过来影响输入)主要用来做回归测试,它的价值在于确定性——同一段日志跑一百遍结果应该完全一样,任何不一致都说明代码里有随机性或者并发问题。闭环仿真(仿真结果会影响下一帧的输入)用来测交互场景,比如加塞、路口博弈,这类场景在真实数据里很难采到足够样本。
回放仿真的搭建成本比想象中低,但有几个坑。一是时间戳的推进方式,如果直接按日志里的时间戳走,遇到丢帧或者乱序就会出问题,需要做一次重采样和时间轴重建。二是模块间的数据拷贝,一条链路跑下来可能拷贝几十次点云,内存带宽会先于算力成为瓶颈。三是随机种子,任何用到随机数的地方都要固定,包括点云下采样、数据增强、某些优化器的初始化。
闭环仿真的难点在传感器仿真的保真度。激光雷达的仿真相对成熟,射线投射加噪声模型能凑合;相机的仿真就麻烦得多,光照、反射、雨雾、运动模糊,任何一项不真实都会让感知模型的表现偏离实际。我的态度是:闭环仿真用来验证逻辑正确性和极端场景下的兜底行为,不用来预测真实世界的绝对指标。凡是拿闭环仿真跑出来的数字直接对外宣称性能的,我都会在合集里标一个“需实测验证”。
4.3 评测指标怎么定才不骗自己
单一指标是最容易骗自己的东西。感知只看平均精度,会忽略长尾;规划只看接管里程,会因为场景分布不同而完全不可比;端到端只看总里程无接管,样本量小的时候置信区间大得没有意义。
我在合集里推荐的是一套分层指标加场景切片。分层指标指每层有自己的核心指标(感知看不同距离段和不同尺寸目标的召回、预测看轨迹误差和概率校准、规划看安全性、舒适性、通行效率三类),场景切片指把所有指标按场景类型拆开看(白天/夜间、直道/路口、畅通/拥堵)。这样做的工作量会翻几倍,但只有拆开看,你才知道这一版到底是在哪类场景上进步了、哪类场景上退步了。我遇到过整体指标涨了两个点、但夜间场景掉了五个点的情况,如果不拆开看,这个退化会被掩盖,上线之后就是事故隐患。
5. 上车之前:时延、标定漂移与降级策略
实验室里跑通和车上能用之间隔着一段很现实的鸿沟,这一段在我的合集里单独归到L5。这一层的内容读起来最不“高级”,但它是决定项目能不能交付的地方。
5.1 端到端时延预算怎么切
先算一笔账:车速100公里每小时约等于27.8米每秒,如果整条链路端到端时延是200毫秒,那么从传感器采集到执行器动作,车辆已经往前走了约5.6米。这个数字直接决定了你的安全距离设计和最高可用车速。
| 环节 | 常见量级 | 说明 |
|---|---|---|
| 传感器采集与传输 | 20-40ms | 曝光、读出、传输、驱动层 |
| 时间同步与预处理 | 10-20ms | 去畸变、坐标变换、点云组织 |
| 感知推理 | 50-100ms | 与模型规模强相关,需实测 |
| 预测 | 10-30ms | 通常与感知并行或紧随其后 |
| 规划 | 20-40ms | 含优化求解,注意最坏情况 |
| 控制 | 5-10ms | 周期通常比规划快一个数量级 |
| 调度与通信 | 10-20ms | 跨进程、跨核通信,容易被忽略 |
切预算的时候有两个原则。第一,按最坏情况算,不按平均值算——优化求解的耗时分布是长尾的,平均值30毫秒可能意味着百分位99是120毫秒。第二,留出余量,总预算不要贴着理论上限设计,我一般留20%到30%给突发情况和后续功能迭代。
还有一个常被忽略的点是流水线设计。如果所有模块严格串行,端到端时延就是各模块之和;如果做成流水线,感知在處理第N帧时规划还在处理第N-1帧,时延会降低但引入了“用旧信息做决策”的问题。这个权衡没有标准答案,取决于你的场景对时延的敏感程度。
5.2 标定漂移:一个必须按里程管理的消耗品
外参不是一次标完就一劳永逸的。温度变化会让支架产生微小形变,路面颠簸和长期振动会让紧固件松动,胎压不一致会改变车体姿态。我见过跑了几个月之后俯仰角偏了零点几度的情况,表现为远处地面点被误检成障碍物,然后系统在空旷路段莫名其妙地急刹。
应对办法分两层。一层是被动监测:用地面拟合、车道线消失点、或者固定标定物的观测值,持续估计外参的变化量,超过阈值就报警。另一层是主动重标定:在特定场景下(比如长直道、清晰的平行车道线)在线更新外参的小幅偏移。要注意在线标定只能修正小偏差,偏差大了必须回场地重新标,否则容易收敛到错误解。
我的合集里给标定这块设了一个简单的管理规则:每行驶一定里程做一次外参一致性检查,每次拆装传感器后必须重标,每次更换轮胎或做四轮定位后检查俯仰和横滚。这些规则写下来很土,但它能避免大量莫名其妙的问题。
5.3 降级策略:系统必须知道自己什么时候不行
降级策略的设计前提是失效可检测。传感器被遮挡、镜头脏污、通信超时、某个模块超时未返回、输出值超出物理合理范围,这些都要有明确的检测逻辑和对应的处理动作。常见的分级是:轻微异常时降低置信度并提示驾驶员;中度异常时限制功能(比如禁用变道、降低最高车速);严重异常时请求接管;接管无响应时执行最小风险策略(减速靠边停车)。
这里最容易犯的错是把降级逻辑写得过于复杂,最后没人能说清系统在当前状态下到底允许做什么。我的建议是用一个显式的状态机,状态数量控制在个位数,每个状态明确定义允许的功能集合和退出条件,并且这个状态机要能被完整地测试覆盖。任何“隐式的降级”都是隐患,因为它在测试里看不见。
6. 把合集用起来:从“读过”到“跑通”的最短路径
合集整理得再好,不跑一遍都是别人的知识。这一节讲讲我自己的使用方式,也是我给这套合集设计的“消费路径”。
6.1 先搭一个最小可运行闭环,再往里填模块
我的建议是先不碰感知。用一段录好的数据或者一个简单的仿真环境,把规划加控制这条闭环跑起来:给定一条参考线和几个静态障碍物,让车能沿着线走、遇到障碍能停。这条闭环大概几百行代码就能跑通,但它会逼你把坐标系、时间步长、控制周期、轨迹表示这些基础问题想清楚。
闭环跑通之后再往里填。填感知的时候用假数据替代,比如直接喂真值框,验证接口对不对;填预测的时候先用匀速模型,验证数据结构对不对。这样每次只引入一个新变量,出问题容易定位。反过来,一上来就把感知预测规划控制全接上,一旦结果不对,你根本不知道该查哪。
我在合集里给每个层级都标了“最小实现”条目,就是那种用最简单的办法把接口跑通、精度很差但结构完整的实现。这类条目在筛选时最容易被忽略,因为指标不好看,但它们对入门的价值远高于那些刷榜的方案。
6.2 复现时的对齐清单
复现失败是常态,我统计过自己复现的成功率大概在六成左右,剩下的四成里绝大多数不是方法本身有问题,而是某个细节没对上。这份清单是我每次复现前都会过一遍的:
| 检查项 | 常见偏差 | 影响 |
|---|---|---|
| 框架与依赖版本 | 算子实现差异、默认参数变化 | 结果小幅漂移,偶尔大幅偏离 |
| 数据预处理 | 归一化方式、裁剪范围、坐标系定义 | 影响最大,常导致完全跑不出结果 |
| 随机种子 | 数据打乱顺序、初始化、增强 | 指标波动,掩盖真实差异 |
| 评价脚本 | 匹配阈值、忽略区域、类别映射 | 指标不可比,是最隐蔽的坑 |
| 硬件与精度 | 混合精度、不同显卡的算子精度 | 小幅漂移,极端情况数值不稳定 |
| 训练轮数与学习率调度 | warmup 步数、衰减策略 | 收敛程度不同,指标差几个点 |
这份清单里我最想强调的是评价脚本。很多人复现时直接用自己的评价代码去算别人模型的输出,然后发现指标对不上就怀疑方法有问题,实际上两边对“什么算匹配”的定义可能完全不同——交并比阈值差0.05、是否忽略小目标、多类别怎么平均,任何一项不同都能造成几个点的差距。我的做法是先用原作者的权重跑一遍,确认能复现出接近的指标,再开始改自己的东西。这一步花不了多少时间,但能省掉后面大量的自我怀疑。
6.3 给合集留一个“失效记录”
最后说一个我认为最有用但很少有人做的习惯:每个条目用了一段时间之后,回头补一条“失效记录”——它在什么情况下不好用、我当时是怎么绕过去的、后来有没有更好的替代方案。这套记录现在已经成了合集里我自己翻阅频率最高的部分,因为方法会过时,但“什么条件下会失效”这种经验保质期长得多。
举个具体的例子。我早期很推崇某类基于采样的轨迹生成方法,觉得它天然处理非凸约束、实现也简单。后来在一个窄路会车的场景里反复出问题,采样点不够密的时候可行解被漏掉,采样点加密之后计算量又顶不住。这条失效记录让我后来对这类方法的适用边界有了清晰认识:它适合约束相对宽松、需要处理多模态的场景,不适合狭窄空间里的高精度通行。这种认识不是读论文能读出来的,只能靠自己撞上去再记下来。
这套合集整理到第二十四期,我最大的感受是:自动驾驶这个方向的资料从来不缺,缺的是把资料变成自己判断力的那一步。分层是为了知道每块砖该放哪,判据是为了挡住噪音,失效记录是为了让踩过的坑只踩一次。真正能让你跑得比别人快的,往往不是多读了几篇新方法,而是少在已经有人踩过的地方再摔一遍。