@@ -30,8 +30,9 @@ export default function FirstReviewChallengePage() {
3030 < a className = "active" href = "#review" >
3131 第一题
3232 </ a >
33+ < a href = "#review-flow" > 审核流程</ a >
3334 < a href = "#diff" > AI 补丁</ a >
34- < a href = "#submit" > 提交审核 </ a >
35+ < a href = "#submit" > 提交 Review </ a >
3536 < a href = "#rubric" > 评分</ a >
3637 </ nav >
3738 < div className = "actions" >
@@ -84,7 +85,7 @@ export default function FirstReviewChallengePage() {
8485 SymPy 项目,只需要围绕本页给出的行为规则和 diff 做判断。
8586 </ p >
8687 < div className = "review-template" >
87- < pre > { `是否可以合并:可以 / 不可以
88+ < pre > { `是否可以合并:可以 / 不可以 / 需要更多信息
8889
8990问题 1:
9091- 严重程度:
@@ -112,46 +113,114 @@ export default function FirstReviewChallengePage() {
112113 从而抛出 `Imaginary coordinates are not permitted`。
113114 </ p >
114115 < p >
115- 所以这道题的关键不是“只要不报错就行”,而是判断 AI 补丁有没有同时保住两个行为:普通坐标不要误杀,明确的虚数坐标仍然要拒绝 。
116+ 这道题要练的是 code review 判断力:一个补丁修好 happy path 之后,是否仍然保留了原有输入约束和边界语义 。
116117 </ p >
117118 </ div >
118119 </ section >
119120
120121 < section className = "challenge-section card" >
121122 < div className = "card-head" >
122- < h2 > 预期行为表</ h2 >
123- < span className = "mono" > review hints</ span >
123+ < h2 > 术语速查</ h2 >
124+ < span className = "mono" > 不用先学完整 SymPy</ span >
125+ </ div >
126+ < div className = "term-grid" >
127+ < div className = "term-item" >
128+ < strong > PR / diff</ strong >
129+ < p > PR 是一次代码变更提议,diff 展示这次变更具体改了哪些行。</ p >
130+ </ div >
131+ < div className = "term-item" >
132+ < strong > merge / request changes</ strong >
133+ < p > merge 表示接受变更;request changes 表示发现必须修复的问题,暂时不能进主分支。</ p >
134+ </ div >
135+ < div className = "term-item" >
136+ < strong > 回归</ strong >
137+ < p > 修一个问题时,把原本正确的行为弄坏。Review Mode 很多题都在考这个。</ p >
138+ </ div >
139+ < div className = "term-item" >
140+ < strong > 边界条件 / 负例测试</ strong >
141+ < p > 边界条件是容易暴露错误的输入;负例测试用来确认非法输入仍然会被拒绝。</ p >
142+ </ div >
143+ < div className = "term-item" >
144+ < strong > Point / Point2D</ strong >
145+ < p > SymPy 里的几何点对象。这里你只需要知道:点坐标有一组原有合法性约束。</ p >
146+ </ div >
147+ < div className = "term-item" >
148+ < strong > evaluate(False)</ strong >
149+ < p > 临时关闭部分自动化简。它可能让表达式保持未化简状态,所以要留意分支判断是否被影响。</ p >
150+ </ div >
151+ < div className = "term-item" >
152+ < strong > im(a)</ strong >
153+ < p > 读取表达式 a 的虚部。你不需要掌握 SymPy 内部,只要知道它参与坐标合法性判断。</ p >
154+ </ div >
155+ < div className = "term-item" >
156+ < strong > a.is_number</ strong >
157+ < p > 判断 a 是否是具体数值。审核时要看它被放进条件判断后,是否改变了输入分类。</ p >
158+ </ div >
159+ </ div >
160+ </ section >
161+
162+ < section className = "challenge-section card" id = "review-flow" >
163+ < div className = "card-head" >
164+ < h2 > 推荐审核流程</ h2 >
165+ < span className = "mono" > review path</ span >
166+ </ div >
167+ < ol className = "review-flow" >
168+ < li >
169+ < strong > 先看改动点</ strong >
170+ < span > 先确认 PR 声称修复什么用户问题,再看 diff 改了哪条校验逻辑。</ span >
171+ </ li >
172+ < li >
173+ < strong > 再看新增测试</ strong >
174+ < span > 新增测试通常能证明一个正向场景,也要检查是否覆盖了反向场景和边界输入。</ span >
175+ </ li >
176+ < li >
177+ < strong > 对照原有约束</ strong >
178+ < span > 判断补丁是精确修复,还是只让某个 case 通过并顺手放宽了旧规则。</ span >
179+ </ li >
180+ < li >
181+ < strong > 主动找反例</ strong >
182+ < span > 想一类补丁作者没有写进测试、但原有约束必须继续成立的输入。</ span >
183+ </ li >
184+ < li >
185+ < strong > 给出 merge 结论</ strong >
186+ < span > 如果有回归风险,就写出 blocking finding、影响和可执行修复方向。</ span >
187+ </ li >
188+ </ ol >
189+ </ section >
190+
191+ < section className = "challenge-section card" >
192+ < div className = "card-head" >
193+ < h2 > 审查清单</ h2 >
194+ < span className = "mono" > 不要只看 happy path</ span >
124195 </ div >
125196 < div className = "behavior-table-wrap" >
126197 < table className = "behavior-table" >
127198 < thead >
128199 < tr >
129- < th > 输入场景 </ th >
130- < th > 期望行为 </ th >
131- < th > 审核时要看什么 </ th >
200+ < th > 输入类型 </ th >
201+ < th > 原有约束 </ th >
202+ < th > 你要验证的问题 </ th >
132203 </ tr >
133204 </ thead >
134205 < tbody >
135206 < tr >
136207 < td >
137- < code > with evaluate(False): Point(1, 2) </ code >
208+ 普通数值坐标
138209 </ td >
139- < td > 应该允许创建点 </ td >
140- < td > 不能再误报 imaginary coordinates </ td >
210+ < td > 不应因为关闭自动化简被误拒 </ td >
211+ < td > 新增测试是否只证明了这个正向场景 </ td >
141212 </ tr >
142213 < tr >
143- < td >
144- < code > with evaluate(False): Point(I, 2)</ code >
145- </ td >
146- < td > 应该继续抛出错误</ td >
147- < td > 检查这个约束在补丁后是否仍成立</ td >
214+ < td > 明显非法的坐标</ td >
215+ < td > 原有非法输入校验仍应清楚可解释</ td >
216+ < td > PR 是否改变了合法 / 非法输入的分类边界</ td >
148217 </ tr >
149218 < tr >
150219 < td >
151- < code > Point(x, y) </ code >
220+ 无法静态确定的符号坐标
152221 </ td >
153- < td > 符号输入不应被粗暴拒绝 </ td >
154- < td > 不确定是否为虚数时,不能当成明确非法 </ td >
222+ < td > 不应被粗暴当成非法输入 </ td >
223+ < td > 条件判断是否把 unknown 和 invalid 混成一种 </ td >
155224 </ tr >
156225 </ tbody >
157226 </ table >
@@ -189,12 +258,13 @@ export default function FirstReviewChallengePage() {
189258
190259 < section className = "card" >
191260 < div className = "card-head" >
192- < h2 > 看 Diff 顺序 </ h2 >
261+ < h2 > 审核顺序 </ h2 >
193262 </ div >
194263 < div className = "section-body compact" >
195- < p > 1. 先看 AI 改了哪一行判断条件。</ p >
196- < p > 2. 再看新增测试只覆盖了什么场景。</ p >
197- < p > 3. 最后用行为表检查是否有回归。</ p >
264+ < p > 1. 看 AI 改了哪一行条件。</ p >
265+ < p > 2. 检查新增测试是否覆盖正例和反例。</ p >
266+ < p > 3. 对照原有约束找回归风险。</ p >
267+ < p > 4. 写出能阻止 merge 的 finding。</ p >
198268 </ div >
199269 </ section >
200270
0 commit comments