各种指导技巧
指导学员时,最有帮助的做法之一就是准备一个文件,用来记录你指导的每道练习的笔记。你可能会发现,很多解答都能受益于同样的建议;把笔记留下来,你就不必每次都凭记忆重新写一遍同样的建议。而且,把建议集中放在一处,你还能不断打磨,让它们越来越清楚。
如果不知道笔记该从何写起,可以在 exercism/website-copy/tracks 下找你所在学习轨道中那道练习的 mentoring.md 文件。如果它存在,里面可能有合理解答的示例,以及常见建议和可以用来引出进一步讨论的话题。如果不存在,等你为那道练习整理出自己的笔记后,也许可以回头补一个。
另外,即使你现在只指导一门语言,将来也可能指导更多。按学习轨道和练习名来组织指导笔记会很有帮助,因为不同的学习轨道对同一道练习往往需要不同的建议。
无论你指导某道练习的频率是高是低,指导笔记都很好用。如果指导得频繁,你可以直接从笔记里复制粘贴,省下大量从头打字的时间。如果指导得不频繁,它也能提醒你那些建议,毕竟距离上次指导已经过去几周甚至几个月,你可能已经忘了。
不同导师的指导笔记有差异是正常的。下面是一种组织方式,但它不是_唯一_的方式。
祝贺学员通过了测试(如果他们通过了的话)。
如果那道练习已经在队列里放了好几天,也许可以这样提一句:
抱歉让你等了一段时间才有人回复。 目前在
Resistor Color Duo上活跃的 JavaScript 导师人手不足。
逐条列出你喜欢学员解答的地方。例如:
我喜欢这个解答简洁易读。
我喜欢这里用了indexOf。
我喜欢这里采用(first * 10) + second的写法,避免了在数字和字符串之间来回转换。
我喜欢这里没有用循环/迭代。
我喜欢这里的解构参数。
接下来可以写你常用的建议。
如果你为每个新引入的语言特性都附上链接,对学员会非常有帮助。例如:
这道练习不要求这样做,不过也许可以考虑把函数改写成箭头函数。
虽然我们不想直接把答案给出来,但有时候学员通过例子学得最快。把一小段代码放进可折叠的 details 区域,就能提供这样的例子,学员可以自己决定要不要展开。例如:
<details><summary>剧透示例</summary>
<pre>
export const decodedValue = ([firstColor, secondColor]) => COLORS.indexOf(firstColor) * 10 + COLORS.indexOf(secondColor)
</pre>
</details>
在笔记接近结尾的地方,可以放一个已发布解答的链接,那个解答完整体现了这些建议。
在笔记最底部,可以放一些学员有时会要求的长篇解释。这些解释并不常出现,但第一次用到时把它们记下来仍然很有好处,这样下一次(也许是几周或几个月之后)就不用从头再想一遍了。例如,有时学员会问,对于 Resistor Color Duo,如果第一位色环是黑色、表示前导零,那么乘法那种写法会怎样:
把黑色作为第一位色环,这是个值得考虑的点,那我们就来考虑一下。 电阻的颜色是用来表示这只电阻有多少欧姆的,而多色环电阻不会使用前导零。 所以黑色不会出现在第一位。 再说,
parseInt或Number也会去掉前导零。
指导笔记里还可以选择记录一类数据:各种解答或做法的基准测试结果。
学员常关心的一个问题是,自己的解答性能如何。对于 C、C++、Go、Rust 这类“底层”语言尤其如此。除了代码写得是否地道,其他语言的学员也常常关心代码的效率。
导师并不_必须_做基准测试。不过,把自己的解答的基准测试结果和其他做法做对比,往往特别能让学员印象深刻。
Go 的学习轨道对基准测试特别友好,因为测试文件里往往就带了基准测试。其他语言可能需要先研究一下,才能确定哪种方法最适合你。比如,如果你只用在线编辑器,那就要找一个能在网上跑基准测试的地方。例如,JSBench.me 就是一个面向 JavaScript 的在线基准测试工具。
如果你在本地运行代码,就可以下载基准测试软件,在自己的机器上跑。例如,Rust 可以用 Criterion,或者用 cargo bench 配合基准测试。
跟踪基准测试结果至少有几种方式。一种是把所有做过基准测试的解答都记成一份不断增长的清单,但清单一长就会变得难以打理。另一种是为不同的做法各保留一份有代表性的基准测试结果。学员往往想看更快做法的代码,所以如果某种更快的做法已经发布,把它的链接给他们会大受欢迎。
如果你要给出某个做过基准测试的解答的链接,一定要链接到已发布的解答,而不是指导会话。并不是所有被指导过的解答都会发布。
有些语言特性,你可能会发现自己在不止一道练习里都会讲到。当你准备把一条建议从一个文件复制到另一个文件时,也许可以考虑把它单独放进一个文件。同样,把建议放在一处的好处是以后更容易打磨。用它来指导一道以前没用过这条建议的练习时,也更容易找到。你不必费力回想自己上次是在哪道练习里讲过这条建议,直接打开这条建议自己的文件就行。
我们鼓励学员说明自己期望从这次指导会话中得到什么。他们常常会以问题的形式来表达。如果这个问题你不知道答案,也不感兴趣,那把这个指导请求留给其他导师就好。
如果你不知道答案但想弄清楚,那最好先别接这个指导请求,等你找到答案再说。如果那时请求已经被别人接走了,至少你学到了东西,也没让学员干等。
有一个例外:如果这个指导请求已经在队列里待了好几天甚至更久。这种情况下,你可以先接下请求,给出你能给的反馈,并告诉学员你会就他们的问题再回复。当然,之后一定要跟进,要么把答案告诉学员,要么告诉他们你没找到。如果没找到答案,把你尝试过哪些找答案的办法描述给学员可能会有帮助。学员也许会回复其他可以尝试的途径。你们两人一起,也许就能找到答案。
如果你已经用尽了所有你知道的找答案办法,可以建议学员结束讨论并重新提交请求,说不定别的导师能给出答案。如果学员愿意,可以在已结束的讨论里发帖,等他们知道答案后分享给你。同样,如果你后来知道了答案,也可以回到那个已结束的讨论告诉学员。
如果你知道答案,也愿意回答,那么合适的时机是在告诉学员你喜欢他们解答的哪些地方之后、提出其他做法的建议之前。
代码出错,要么是因为没能通过全部测试,要么是因为无法编译或不满足解释器的要求。
不同的导师对处理出错的代码有不同的倾向和/或耐心,这在一定程度上可能取决于代码是怎么呈现的,因为出错的代码并不总是以同样的方式呈现。
有时学员会说他们试了另一种做法,但没成功,然后问为什么不行。代码可能根本没提供,或者被贴在一段几乎读不了的评论里,而不是放在一次迭代中。
在网页编辑器里测试过的解答,只有通过全部测试后才能提交指导请求。原因之一是,这样导师就能专注于针对现有可用代码提出改进或其他做法的建议。_调试_代码不一定是导师想做或被要求做的事。不过,通过 CLI 提交的未通过测试的解答也可以提交指导请求,学员可以请人帮忙把它解决掉。
如果没有提供出错的代码,而所描述的失败做法听起来也不好,那么也许只要建议他们:与其用那个失败的做法,不如试试既不是失败做法、也不是他们已通过的做法的另一种做法。或者,也许只要解释一下他们用的做法为什么比失败的做法更好就够了,不必深入讨论失败的做法里到底有什么 bug。
例如,常见的情况是学员在 Robot Name 这道练习上遇到困难。要么测试超时,要么生成的名称不够多,他们想知道怎么修。如果你有意愿也有耐心,当然可以分析他们的代码并建议如何解决问题。或者你可以解释:随机生成的名称越多,检查时发生冲突的可能就越大,并建议另一种做法是先按顺序生成名称,然后再打乱。
如果出错的代码被贴在一段几乎读不了的评论里,你可以就通过的解答给出你能给的反馈,并建议他们把评论里的代码作为另一次迭代提交。你也可以建议学员去查看那次失败迭代的错误信息,以此作为问题所在的线索。
如果代码就在一次失败的迭代里,那么引导学员查看测试运行的错误信息会很有帮助。有些语言在如何读错误信息或测试结果方面,需要比别的语言更多的引导。引用错误信息中的一处或多处,并向学员解释它的含义,可能会有帮助。
归根结底,修好学员出错的代码并不是导师的责任,但如果导师愿意,可以向学员建议他们自己修复的办法。
你可能加入某个学习轨道做导师,却从没在它的队列里看到任何可以指导的练习。你可能会觉得哪里出了问题,但至少有两种原因。一是眼下可能没人在这个学习轨道上请求指导,有时一个学习轨道会有一段时间没什么动静。二是其他导师可能在你看到之前就把请求接走了。在活跃导师很多的热门学习轨道上,这很常见。
如果队列里有很多请求,有几种处理方式。你可以从最旧的做到最新的,这样等得最久的人先被照顾到。或者,你也可以选择从最新的做到最旧的,尤其是在最旧的那些已经等了很久的情况下。这样,最近活跃的人就不必等积压的请求处理完。
如果同一道练习有多个请求,你可以按同一道练习分批处理,以保持专注,而不是从练习 A 跳到练习 B 又跳回练习 A。
也许有一道你不太感兴趣的练习,它的请求已经放在那里好几天甚至好几周了。你可以选择不去管它,希望别的导师接手;也可以把它当作动力,自己试一试这道练习。有帮助的一点是看看提交的解答。它可能用了你没想到的做法,而那个做法也许会让你更愿意做这道练习。但如果你看了代码之后仍然不想做这道练习,也没什么损失。看过一个指导请求,并不意味着你必须点“开始指导”按钮。