A place to cache linked articles (think custom and personal wayback machine)
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

index.html 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <!doctype html><!-- This is a valid HTML5 document. -->
  2. <!-- Screen readers, SEO, extensions and so on. -->
  3. <html lang="fr">
  4. <!-- Has to be within the first 1024 bytes, hence before the `title` element
  5. See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
  6. <meta charset="utf-8">
  7. <!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
  8. <!-- The viewport meta is quite crowded and we are responsible for that.
  9. See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
  10. <meta name="viewport" content="width=device-width,initial-scale=1">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>Wrap Up and Q&amp;A - Jacob Kaplan-Moss (archive) — David Larlet</title>
  13. <meta name="description" content="Publication mise en cache pour en conserver une trace.">
  14. <!-- That good ol' feed, subscribe :). -->
  15. <link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/">
  16. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  17. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png">
  18. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png">
  19. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png">
  20. <link rel="manifest" href="/static/david/icons2/site.webmanifest">
  21. <link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c">
  22. <link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
  23. <meta name="msapplication-TileColor" content="#f7f7f7">
  24. <meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml">
  25. <meta name="theme-color" content="#f7f7f7" media="(prefers-color-scheme: light)">
  26. <meta name="theme-color" content="#272727" media="(prefers-color-scheme: dark)">
  27. <!-- Documented, feel free to shoot an email. -->
  28. <link rel="stylesheet" href="/static/david/css/style_2021-01-20.css">
  29. <!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
  30. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  31. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  32. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  33. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  34. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  35. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  36. <script>
  37. function toggleTheme(themeName) {
  38. document.documentElement.classList.toggle(
  39. 'forced-dark',
  40. themeName === 'dark'
  41. )
  42. document.documentElement.classList.toggle(
  43. 'forced-light',
  44. themeName === 'light'
  45. )
  46. }
  47. const selectedTheme = localStorage.getItem('theme')
  48. if (selectedTheme !== 'undefined') {
  49. toggleTheme(selectedTheme)
  50. }
  51. </script>
  52. <meta name="robots" content="noindex, nofollow">
  53. <meta content="origin-when-cross-origin" name="referrer">
  54. <!-- Canonical URL for SEO purposes -->
  55. <link rel="canonical" href="https://jacobian.org/2022/jan/6/wst-wrap-up/">
  56. <body class="remarkdown h1-underline h2-underline h3-underline em-underscore hr-center ul-star pre-tick" data-instant-intensity="viewport-all">
  57. <article>
  58. <header>
  59. <h1>Wrap Up and Q&amp;A - Jacob Kaplan-Moss</h1>
  60. </header>
  61. <nav>
  62. <p class="center">
  63. <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
  64. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
  65. </svg> Accueil</a> •
  66. <a href="https://jacobian.org/2022/jan/6/wst-wrap-up/" title="Lien vers le contenu original">Source originale</a>
  67. </p>
  68. </nav>
  69. <hr>
  70. <p>This is the final post in <a href="https://jacobian.org/series/work-sample-tests/">my series on work sample tests</a>. It’s a wrap-up post: I’ll address a few random points I couldn’t quite fit in elsewhere, and answer some questions from readers. I don’t think this’ll make much sense without having read the rest of the series, so you should probably do that before finishing this post.</p>
  71. <h2 id="how-do-work-sample-tests-fit-into-on-site-interviews">How do work sample tests fit into on-site interviews?</h2>
  72. <p>Throughout the series, I’ve mostly assumed that these tests are taking place in the context of a distributed/remote interview<sup id="fnref:1"></sup>. How would they fit into a traditional, on-site interview?</p>
  73. <p>I maintain that <strong>the candidate time investment limit needs to stay the same</strong>. A day of onsite interviews (which, remember, might include up to a day of travel on both ends) is about the upper limit of time investment I think is fair to ask of a candidate. This means that asking a candidate do some coding at home <em>and then</em> come spend a full day on-site is unfair. Either have the coding homework time replace some of the on-site interview time, or use a work sample test that’s more suited to a synchronous experience. <a href="https://jacobian.org/2021/nov/30/wst-pair-programming/">Pair programming</a> and<a href="https://jacobian.org/2021/dec/15/wst-reverse-review/"> “reverse” code review</a> seem like they’d work very well as part of an onsite loop.</p>
  74. <p>Other than that, I don’t see other big differences between on-site and distributed interviews with regard to work sample tests.</p>
  75. <h2 id="can-work-sample-tests-work-for-non-engineering-roles">Can work sample tests work for non-engineering roles?</h2>
  76. <p>I assume so. I’ve heard various anecdotes from folks using work sample tests for other kinds of roles: an editor told me about giving candidates unedited material to edit and comment upon; I’ve talked to support reps who role-play conversations with customers as part of an interview; I’ve talked to designers who give design challenges. I even ran across <a href="https://www.opm.gov/policy-data-oversight/assessment-and-selection/other-assessment-methods/work-samples-and-simulations/">official guidance on work sample tests from The US Office of Personnel Management (OPM)</a>, the agency responsible for US Federal employment regulation and policy.</p>
  77. <p>So I would tend to assume that the same principles apply to any kind of role. However, I’ve almost exclusively hired for engineering roles, and only really studied hiring practices in that context, so it’s hard for me to speak authoritatively.</p>
  78. <p>If you’ve used work sample tests in non-engineering contexts, and want to write about it – let me know! I’d love to co-author a post with you, or link out to your blog, etc.</p>
  79. <h2 id="what-about-people-youve-worked-with-before-should-you-let-them-skip-the-work-sample-test">What about people you’ve worked with before? Should you let them skip the work sample test?</h2>
  80. <p>The point of a work sample test is to verify that someone can deliver on the core job requirements - write code, find security vulnerabilities, etc. If you, or someone on your team, has already worked with a candidate, and seen them do those things in other contexts, do you still need to give them a work sample test? Or is that a waste of their time?</p>
  81. <p>I don’t have a hard and fast answer. My answer depends; sometimes I think it’s better to make everyone do the same test, even if it’s redundant for some candidates; sometimes I think it’s better to be flexible and allow prior colleagues to skip that step. I ask myself a few questions when I’m trying to decide:</p>
  82. <ul><li><strong>Is the previous work relevant and recent?</strong> If I’m hiring a Python programmer, and a candidate is someone I wrote Python with just six months ago, it seems silly to verify that they can write Python. But if the candidate is someone I worked with five years ago on a Java project, I should probably give them the test. Generally, if it’s been longer than two years, or the technologies are radically different, I’ll give them the test.</li><li><strong>Would letting this person skip the work sample test mean missing out on other candidates?</strong> Often, the former colleague in this situation is one of the first candidates. They know you, saw the job post, and applied immediately. If you let them skip the test, you can be ready to make an offer in like a week or so! This is awesome for filling a role quickly, but often means you’ll miss out on candidates you don’t know. Are you comfortable making a very quick decision here even if it means missing out on some hypothetical great candidate you <em>don’t</em> already know? Generally, I’d like to have at least 3-5 candidates, including the one I know, before I’m comfortable making an offer. But if the person I know is just an amazing match, I might not follow this rule.</li><li><strong>Is the rest of my team comfortable trusting my experience with this person over seeing their work first-hand?</strong> If anyone’s even a bit uncomfortable, better to ask the candidate to take the test.</li></ul>
  83. <p>Depending on the answers to those questions, I might let someone whose work I was familiar with skip a work sample test. I’d still want to have them go through a round of interviews, and there’s a lot to say about how to <em>interview</em> people you’ve worked with before. But this is a series about work sample tests, so that’ll have to wait for some other time.</p>
  84. <h2 id="how-secret-do-work-sample-tests-need-to-be">How secret do work sample tests need to be?</h2>
  85. <p>The word “test” usually implies secrecy; something the test-taker shouldn’t know about ahead of time. Should work sample tests be kept secret? Do we need to take steps to ensure that candidates don’t know the details of the test before applying? Do we need to ask them not to post their solution code on Github?</p>
  86. <p>Generally, no. <strong>Most work sample tests don’t need to be secret.</strong> My favorite single test, <a href="https://homework.adhoc.team/slcsp/">Ad Hoc’s SLCSP exercise</a>, has solutions on Github if you look for them. But vanishingly few candidates cheat, and the ones that do are easily caught in the post-exercise interview (<a href="https://jacobian.org/2021/nov/17/wst-framework/#no-pass-fail">rule #5</a>): they can’t explain the code or answer questions about how they wrote it (because they didn’t). Further, if someone did find existing code that solved the problem, read through to understand it carefully, and then told me in an interview, “yeah, I found this on Github, and it solved the problem” – well, that’s pretty close to how any number of real-world problems get solved, right? I wouldn’t consider that cheating. Cheating, in the context of most work sample tests, is dishonesty, not reuse.</p>
  87. <p>There are a few tests that require some degree of secrecy, though. <a href="https://jacobian.org/2021/dec/24/wst-labs/">Lab environments</a> sometimes do: exercises where candidates look for bugs or vulnerabilities can be “spoiled” easily if the candidate knows where to look. So that test, and ones like it, benefit from being kept secret. Still, I’d argue this makes them worse simulations: in the real world, we have the entire sum of human knowledge at our fingertips; we want to hire people who know how to effectively use the Internet to help them solve problems.</p>
  88. <p>If your test requires secrecy to be effective, that’s a sign it could be better. It might be acceptable given other tradeoffs, but it’s something to be wary of.</p>
  89. <h2 id="should-we-pay-candidates-for-their-time-on-work-sample-tests">Should we pay candidates for their time on work sample tests?</h2>
  90. <p>I established a rule of no more than three hours for a work sample test, out of a maximum of 8 hours for the entire interview loop (<a href="https://jacobian.org/2021/nov/17/wst-framework/#three-hours">rule #2</a>). And I wrote a few times that if companies want to exceed that mark, they should compensate candidates for their time.</p>
  91. <p>Why stop there? Should we compensate <em>all</em> candidates for their time?</p>
  92. <p><a href="https://changeset.nyc/">Sumana</a> pointed me towards Software Freedom Conservancy, who did exactly that; <a href="https://sfconservancy.org/blog/2021/oct/15/equitable-hiring/">every candidate who made it through the initial screens was paid for their time</a>:</p>
  93. <blockquote><p>Because we are a small organization, adding another employee is a big deal. We knew that to do this job right we were going to need to take some time talking to them to figure out if they were the right fit for the role. We also know that not everybody does their best when put on the spot in an interview, and wanted to make sure that we allowed people the chance to know what we’d be asking and to prepare if they wanted to. We didn’t want to take our applicants' time for granted, even though we are a small publicly supported organization.</p><p>Because of this, we decided to pay each [of] our five finalists $500 to proceed with the rest of the interview. While $500 is not a huge amount, we thought it was a nice amount for a charitable organization to give to an applicant who would dedicate some time and thought to our hiring process, which would cover strategic thinking about our organization’s mission and operations in our communications and other related areas.</p></blockquote>
  94. <p>I love this and am going to try for something similar in the future. I think it might be a hard sell to some organizations because it’s outside of the norm. But paying candidates for their time as a mark of respect is excellent.</p>
  95. <h2 id="how-do-you-measure-the-effectiveness-of-a-work-sample-test">How do you measure the effectiveness of a work sample test?</h2>
  96. <p>Throughout the post I’ve mentioned “effective” and “successful” work sample tests (and also occasional “ineffective” and “unsuccessful” ones). How do I know? What am I measuring to know if a test is working?</p>
  97. <p>Measuring the effectiveness of hiring techniques – interviews, screens, tests – is a much larger topic and one I hope to write about in more detail in the future. For now, here’s a quick sketch:</p>
  98. <ol><li>For a given role, establish <em>competencies</em> – the core behaviors that define success in the job. For example, for a penetration testing role, “finds vulnerabilities” might be a competency; “written communication” (i.e. vulnerability write-ups) might be another.</li><li>Use those competencies as part of your performance review process; record everyone’s scores.</li><li>Design an interview question or work sample test that measures that competency. Test it out internally to verify that performance on the question correlates with your staff member’s recent performance reviews.</li><li>Hire some people using the question/test.</li><li>Monitor their performance over time. If the question is effective, their performance on the question will correlate with their performance reviews for that competency.</li></ol>
  99. <p>Once again, this is a very quick sketch; I’ve left out a ton of nuance and detail. If you’d like to see me write about this in detail sooner rather than later, drop me a line.</p>
  100. <h2 id="how-do-you-grade-work-sample-tests">How do you grade work sample tests?</h2>
  101. <p>In this series, and my <a href="https://jacobian.org/series/unpacking-interview-questions/">previous series on interview questions</a>, I glossed over how exactly I recommend measuring candidates' responses. Should you have grading rubrics, and score candidates' responses to each question? What about overall: should candidates get a numeric score for the interview?</p>
  102. <p>This is another topic I hope to write about in detail at some point, but for now, another quick sketch:</p>
  103. <p>It’s not critical: fundamentally, hiring is a binary decision; you either make someone an offer or you don’t. So if the only “score” you record out of an interview is a “hire”/“no-hire” recommendation, that’s sufficient.</p>
  104. <p>But if you can establish grading rubrics, I think it’s a good practice. Certainly, it gives you a way to measure effectiveness, see above. I use a grading rubric based on the <a href="https://www.apache.org/foundation/voting.html#expressing-votes-1-0-1-and-fractions">Apache Voting System</a> +1/0/-1 scores, so something like this:</p>
  105. <ul><li><strong>+1</strong>: the candidate’s response to this question was <em>incredible</em> and makes a strong case to hire them</li><li><strong>+0</strong>: a typical good answer, roughly what we were expecting</li><li><strong>-0</strong>: not a strong answer, but not terrible enough to be a red flag</li><li><strong>-1</strong>: red flag: a bad enough answer that I might not want to hire them based on this question alone</li></ul>
  106. <p>I like this system because it’s not linear: +0/-0 capture answers that are strong or weak but in a typical way, while +1/-1 capture exceptionally good or bad responses. I also like that it’s fairly easy to teach and understand. A more typical 1-5 scale often causes a fair bit of confusion over the difference between a “3” and a “4” or whatever. But I don’t think the specifics matter very much: as long as you’re consistent, any rubric will be useful.</p>
  107. <h2 id="could-a-short-work-sample-test-replace-a-traditional-resume-screen">Could a short work sample test replace a traditional resume screen?</h2>
  108. <p>This question was asked by Alex Yang, founder of <a href="https://www.mightyacorn.io/">Mighty Acorn</a> - a startup that runs work sample tests. They’re thinking about work sample tests in a way that matches much of what I’ve written here, so he reached out and we spoke about work sample tests for a while.</p>
  109. <p>Resume screens are ridiculous. We look at this piece of paper and try to make a snap judgment about whether we should invest some time in an interview, or reject them out of hand. We’re not measuring someone’s suitability for the role; we’re measuring how well they write resumes. If we don’t take steps to anonymize the resume, we can easily end up <a href="https://hbswk.hbs.edu/item/minorities-who-whiten-job-resumes-get-more-interviews">making decisions shaped by unconscious bias</a>.</p>
  110. <p>Unfortunately, most job listings get a lot of completely irrelevant applicants. It seems like some candidates believe the best approach is to blast their resume at every job opening, regardless of any potential fit. I’ve seen applications for quite senior engineering roles where the resume doesn’t show a single month of software development experience anywhere. Interviewing obviously unqualified applicants is a waste of everyone’s time, hence the resume screen.</p>
  111. <p>So maybe we could solve two problems at once, and give a work sample test <em>instead</em> of a resume screen?</p>
  112. <p>Perhaps, but I’m unconvinced. Work sample tests are usually time-consuming, and I don’t like the idea of asking applicants to spend that time until we’re both at least a little bit sure there’s a match (see <a href="https://jacobian.org/2021/nov/17/wst-framework/#offer-exercises-late">rule #8</a>). Possibly if the work sample was truly very short, like well under an hour.</p>
  113. <p>One alternative that come up in talking with Alex and his team was offering a work sample test as an alternative, should someone not pass the resume screen. Instead of rejecting them outright, give them a chance to get into the running by completing a short test. This would help reveal candidates who <em>do</em> have some of the skills you’re looking for, but have done a poor job showing it on the resume. This is a very interesting idea, and one I’m hoping to try out sometime soon.</p>
  114. <h2 id="fin">Fin</h2>
  115. <p>That’s all folks. Thanks for reading. I hope you found it useful. If this series helped you improve your work sample tests, I’d like to hear about it. Get in touch!</p>
  116. </article>
  117. <hr>
  118. <footer>
  119. <p>
  120. <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
  121. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
  122. </svg> Accueil</a> •
  123. <a href="/david/log/" title="Accès au flux RSS"><svg class="icon icon-rss2">
  124. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-rss2"></use>
  125. </svg> Suivre</a> •
  126. <a href="http://larlet.com" title="Go to my English profile" data-instant><svg class="icon icon-user-tie">
  127. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-user-tie"></use>
  128. </svg> Pro</a> •
  129. <a href="mailto:david%40larlet.fr" title="Envoyer un courriel"><svg class="icon icon-mail">
  130. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-mail"></use>
  131. </svg> Email</a> •
  132. <abbr class="nowrap" title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340"><svg class="icon icon-hammer2">
  133. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-hammer2"></use>
  134. </svg> Légal</abbr>
  135. </p>
  136. <template id="theme-selector">
  137. <form>
  138. <fieldset>
  139. <legend><svg class="icon icon-brightness-contrast">
  140. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-brightness-contrast"></use>
  141. </svg> Thème</legend>
  142. <label>
  143. <input type="radio" value="auto" name="chosen-color-scheme" checked> Auto
  144. </label>
  145. <label>
  146. <input type="radio" value="dark" name="chosen-color-scheme"> Foncé
  147. </label>
  148. <label>
  149. <input type="radio" value="light" name="chosen-color-scheme"> Clair
  150. </label>
  151. </fieldset>
  152. </form>
  153. </template>
  154. </footer>
  155. <script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script>
  156. <script>
  157. function loadThemeForm(templateName) {
  158. const themeSelectorTemplate = document.querySelector(templateName)
  159. const form = themeSelectorTemplate.content.firstElementChild
  160. themeSelectorTemplate.replaceWith(form)
  161. form.addEventListener('change', (e) => {
  162. const chosenColorScheme = e.target.value
  163. localStorage.setItem('theme', chosenColorScheme)
  164. toggleTheme(chosenColorScheme)
  165. })
  166. const selectedTheme = localStorage.getItem('theme')
  167. if (selectedTheme && selectedTheme !== 'undefined') {
  168. form.querySelector(`[value="${selectedTheme}"]`).checked = true
  169. }
  170. }
  171. const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
  172. window.addEventListener('load', () => {
  173. let hasDarkRules = false
  174. for (const styleSheet of Array.from(document.styleSheets)) {
  175. let mediaRules = []
  176. for (const cssRule of styleSheet.cssRules) {
  177. if (cssRule.type !== CSSRule.MEDIA_RULE) {
  178. continue
  179. }
  180. // WARNING: Safari does not have/supports `conditionText`.
  181. if (cssRule.conditionText) {
  182. if (cssRule.conditionText !== prefersColorSchemeDark) {
  183. continue
  184. }
  185. } else {
  186. if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
  187. continue
  188. }
  189. }
  190. mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
  191. }
  192. // WARNING: do not try to insert a Rule to a styleSheet you are
  193. // currently iterating on, otherwise the browser will be stuck
  194. // in a infinite loop…
  195. for (const mediaRule of mediaRules) {
  196. styleSheet.insertRule(mediaRule.cssText)
  197. hasDarkRules = true
  198. }
  199. }
  200. if (hasDarkRules) {
  201. loadThemeForm('#theme-selector')
  202. }
  203. })
  204. </script>
  205. </body>
  206. </html>