diff options
Diffstat (limited to 'src/content/blog/2020/10')
-rw-r--r-- | src/content/blog/2020/10/19/feature-flags.adoc | 315 | ||||
-rw-r--r-- | src/content/blog/2020/10/20/wrong-interviewing.adoc | 302 |
2 files changed, 312 insertions, 305 deletions
diff --git a/src/content/blog/2020/10/19/feature-flags.adoc b/src/content/blog/2020/10/19/feature-flags.adoc index c62c2d1..c9adc8a 100644 --- a/src/content/blog/2020/10/19/feature-flags.adoc +++ b/src/content/blog/2020/10/19/feature-flags.adoc @@ -1,305 +1,304 @@ ---- -title: "Feature flags: differences between backend, frontend and mobile" -date: 2020-10-19 -updated_at: 2020-11-03 -layout: post -lang: en -ref: feature-flags-differences-between-backend-frontend-and-mobile -eu_categories: presentation ---- - -*This article is derived from a [presentation][presentation] on the same -subject.* - -When discussing about feature flags, I find that their -costs and benefits are often well exposed and addressed. Online articles like -"[Feature Toggle (aka Feature Flags)][feature-flags-article]" do a great job of += Feature flags: differences between backend, frontend and mobile + +:empty: +:slides: link:../../../../slides/2020/10/19/feature-flags.html +:fowler-article: https://martinfowler.com/articles/feature-toggles.html + +_This article is derived from a {slides}[presentation] on the same subject._ + +When discussing about feature flags, I find that their costs and benefits are +often well exposed and addressed. Online articles like +"{fowler-article}[Feature Toggle (aka Feature Flags)]" do a great job of explaining them in detail, giving great general guidance of how to apply techniques to adopt it. However the weight of those costs and benefits apply differently on backend, -frontend or mobile, and those differences aren't covered. In fact, many of them +frontend or mobile, and those differences aren't covered. In fact, many of them stop making sense, or the decision of adopting a feature flag or not may change depending on the environment. In this article I try to make the distinction between environments and how - feature flags apply to them, with some final best practices I've acquired when - using them in production. +feature flags apply to them, with some final best practices I've acquired when +using them in production. -[presentation]: {% link _slides/2020-10-19-rollout-feature-flag-experiment-operational-toggle.slides %} -[feature-flags-article]: https://martinfowler.com/articles/feature-toggles.html +== Why feature flags -## Why feature flags +:atlassian-cicd: https://www.atlassian.com/continuous-delivery/principles/continuous-integration-vs-delivery-vs-deployment Feature flags in general tend to be cited on the context of -[continuous deployment][cd]: +{atlassian-cicd}[continuous deployment]: -> A: With continuous deployment, you deploy to production automatically +____ +A: With continuous deployment, you deploy to production automatically -> B: But how do I handle deployment failures, partial features, *etc.*? +B: But how do I handle deployment failures, partial features, _etc._? -> A: With techniques like canary, monitoring and alarms, feature flags, *etc.* +A: With techniques like canary, monitoring and alarms, feature flags, _etc._ +____ -Though adopting continuous deployment doesn't force you to use feature -flags, it creates a demand for it. The inverse is also true: using feature flags -on the code points you more obviously to continuous deployment. Take the -following code sample for example, that we will reference later on the article: +Though adopting continuous deployment doesn't force you to use feature flags, it +creates a demand for it. The inverse is also true: using feature flags on the +code points you more obviously to continuous deployment. Take the following +code sample for example, that we will reference later on the article: -```javascript +[source,javascript] +---- function processTransaction() { - validate(); - persist(); - // TODO: add call to notifyListeners() + validate(); + persist(); + // TODO: add call to notifyListeners() } -``` +---- While being developed, being tested for suitability or something similar, -`notifyListeners()` may not be included in the code at once. So instead of +`notifyListeners()` may not be included in the code at once. So instead of keeping it on a separate, long-lived branch, a feature flag can decide when the new, partially implemented function will be called: -```javascript +[source,javascript] +---- function processTransaction() { - validate(); - persist(); - if (featureIsEnabled("activate-notify-listeners")) { - notifyListeners(); - } + validate(); + persist(); + if (featureIsEnabled("activate-notify-listeners")) { + notifyListeners(); + } } -``` +---- This allows your code to include `notifyListeners()`, and decide when to call it -at runtime. For the price of extra things around the code, you get more +at runtime. For the price of extra things around the code, you get more dynamicity. So the fundamental question to ask yourself when considering adding a feature flag should be: -> Am I willing to pay with code complexity to get dynamicity? +____ +Am I willing to pay with code complexity to get dynamicity? +____ -It is true that you can make the management of feature flags as -straightforward as possible, but having no feature flags is simpler than having -any. What you get in return is the ability to parameterize the behaviour of the -application at runtime, without doing any code changes. +It is true that you can make the management of feature flags as straightforward +as possible, but having no feature flags is simpler than having any. What you +get in return is the ability to parameterize the behaviour of the application at +runtime, without doing any code changes. Sometimes this added complexity may tilt the balance towards not using a feature flag, and sometimes the flexibility of changing behaviour at runtime is -absolutely worth the added complexity. This can vary a lot by code base, feature, but -fundamentally by environment: its much cheaper to deploy a new version of a -service than to release a new version of an app. +absolutely worth the added complexity. This can vary a lot by code base, +feature, but fundamentally by environment: its much cheaper to deploy a new +version of a service than to release a new version of an app. So the question of which environment is being targeted is key when reasoning about costs and benefits of feature flags. -[cd]: https://www.atlassian.com/continuous-delivery/principles/continuous-integration-vs-delivery-vs-deployment +== Control over the environment -## Control over the environment +:fdroid: https://f-droid.org/ +:bad-apple: https://www.paulgraham.com/apple.html The key differentiator that makes the trade-offs apply differently is how much control you have over the environment. -When running a **backend** service, you usually are paying for the servers -themselves, and can tweak them as you wish. This means you have full control do -to code changes as you wish. Not only that, you decide when to do it, and for +When running a *backend* service, you usually are paying for the servers +themselves, and can tweak them as you wish. This means you have full control do +to code changes as you wish. Not only that, you decide when to do it, and for how long the transition will last. -On the **frontend** you have less control: even though you can choose to make a -new version available any time you wish, you can't force[^force] clients to -immediately switch to the new version. That means that a) clients could skip -upgrades at any time and b) you always have to keep backward and forward -compatibility in mind. +On the *frontend* you have less control: even though you can choose to make a +new version available any time you wish, you can't +force{empy}footnote:force[ + Technically you could force a reload with JavaScript using + `window.location.reload()`, but that not only is invasive and impolite, but + also gives you the illusion that you have control over the client when you + actually don't: clients with disabled JavaScript would be immune to such + tactics. +] clients to immediately switch to the new version. That means that a) clients +could skip upgrades at any time and b) you always have to keep backward and +forward compatibility in mind. Even though I'm mentioning frontend directly, it applies to other environment with similar characteristics: desktop applications, command-line programs, -*etc*. +_etc_. -On **mobile** you have even less control: app stores need to allow your app to -be updated, which could bite you when least desired. Theoretically you could -make you APK available on third party stores like [F-Droid][f-droid], or even -make the APK itself available for direct download, which would give you the same +On *mobile* you have even less control: app stores need to allow your app to be +updated, which could bite you when least desired. Theoretically you could make +you APK available on third party stores like {fdroid}[F-Droid], or even make the +APK itself available for direct download, which would give you the same characteristics of a frontend application, but that happens less often. -On iOS you can't even do that. You have to get Apple's blessing on every single -update. Even though we already know that is a [bad idea][apple] for over a -decade now, there isn't a way around it. This is where you have the least +On iOS you can't even do that. You have to get Apple's blessing on every single +update. Even though we already know that is a {bad-apple}[bad idea] for over a +decade now, there isn't a way around it. This is where you have the least control. In practice, the amount of control you have will change how much you value -dynamicity: the less control you have, the more valuable it is. In other words, +dynamicity: the less control you have, the more valuable it is. In other words, having a dynamic flag on the backend may or may not be worth it since you could always update the code immediately after, but on iOS it is basically always worth it. -[f-droid]: https://f-droid.org/ -[^force]: Technically you could force a reload with JavaScript using - `window.location.reload()`, but that not only is invasive and impolite, but - also gives you the illusion that you have control over the client when you - actually don't: clients with disabled JavaScript would be immune to such - tactics. +== Rollout -[apple]: http://www.paulgraham.com/apple.html +:kubernetes-deployment: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#creating-a-deployment +:play-store-rollout: https://support.google.com/googleplay/android-developer/answer/6346149?hl=en +:app-store-rolllout: https://help.apple.com/app-store-connect/#/dev3d65fcee1 -## Rollout - -A rollout is used to *roll out* a new version of software. +A rollout is used to _roll out_ a new version of software. They are usually short-lived, being relevant as long as the new code is being -deployed. The most common rule is percentages. +deployed. The most common rule is percentages. -On the **backend**, it is common to find it on the deployment infrastructure -itself, like canary servers, blue/green deployments, -[a kubernetes deployment rollout][k8s], *etc*. You could do those manually, by -having a dynamic control on the code itself, but rollbacks are cheap enough that -people usually do a normal deployment and just give some extra attention to the -metrics dashboard. +On the *backend*, it is common to find it on the deployment infrastructure +itself, like canary servers, blue/green deployments, {kubernetes-deployment}[a +kubernetes deployment rollout], _etc_. You could do those manually, by having a +dynamic control on the code itself, but rollbacks are cheap enough that people +usually do a normal deployment and just give some extra attention to the metrics +dashboard. Any time you see a blue/green deployment, there is a rollout happening: most likely a load balancer is starting to direct traffic to the new server, until -reaching 100% of the traffic. Effectively, that is a rollout. +reaching 100% of the traffic. Effectively, that is a rollout. -On the **frontend**, you can selectively pick which user's will be able to -download the new version of a page. You could use geographical region, IP, +On the *frontend*, you can selectively pick which user's will be able to +download the new version of a page. You could use geographical region, IP, cookie or something similar to make this decision. -CDN propagation delays and people not refreshing their web -pages are also rollouts by themselves, since old and new versions of the -software will coexist. +CDN propagation delays and people not refreshing their web pages are also +rollouts by themselves, since old and new versions of the software will coexist. -On **mobile**, the Play Store allows you to perform -fine-grained [staged rollouts][staged-rollouts], and the App Store allows you to -perform limited [phased releases][phased-releases]. +On *mobile*, the Play Store allows you to perform fine-grained +{play-store-rollout}[staged rollouts], and the App Store allows you to perform +limited {app-store-rollout}[phased releases]. Both for Android and iOS, the user plays the role of making the download. In summary: since you control the servers on the backend, you can do rollouts at -will, and those are often found automated away in base infrastructure. On the +will, and those are often found automated away in base infrastructure. On the frontend and on mobile, there are ways to make new versions available, but users may not download them immediately, and many different versions of the software end up coexisting. -[k8s]: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#creating-a-deployment -[staged-rollouts]: https://support.google.com/googleplay/android-developer/answer/6346149?hl=en -[phased-releases]: https://help.apple.com/app-store-connect/#/dev3d65fcee1 - -## Feature flag +== Feature flag -A feature flag is a *flag* that tells the application on runtime to turn on or -off a given *feature*. That means that the actual production code will have more -than one possible code paths to go through, and that a new version of a feature -coexists with the old version. The feature flag tells which part of the code to -go through. +A feature flag is a _flag_ that tells the application on runtime to turn on or +off a given _feature_. That means that the actual production code will have +more than one possible code paths to go through, and that a new version of a +feature coexists with the old version. The feature flag tells which part of the +code to go through. They are usually medium-lived, being relevant as long as the new code is being -developed. The most common rules are percentages, allow/deny lists, A/B groups +developed. The most common rules are percentages, allow/deny lists, A/B groups and client version. -On the **backend**, those are useful for things that have a long development -cycle, or that needs to done by steps. Consider loading the feature flag rules -in memory when the application starts, so that you avoid querying a database -or an external service for applying a feature flag rule and avoid flakiness on -the result due to intermittent network failures. +On the *backend*, those are useful for things that have a long development +cycle, or that needs to done by steps. Consider loading the feature flag rules +in memory when the application starts, so that you avoid querying a database or +an external service for applying a feature flag rule and avoid flakiness on the +result due to intermittent network failures. -Since on the **frontend** you don't control when to update the client software, +Since on the *frontend* you don't control when to update the client software, you're left with applying the feature flag rule on the server, and exposing the -value through an API for maximum dynamicity. This could be in the frontend code +value through an API for maximum dynamicity. This could be in the frontend code itself, and fallback to a "just refresh the page"/"just update to the latest version" strategy for less dynamic scenarios. -On **mobile** you can't even rely on a "just update to the latest version" +On *mobile* you can't even rely on a "just update to the latest version" strategy, since the code for the app could be updated to a new feature and be -blocked on the store. Those cases aren't recurrent, but you should always assume -the store will deny updates on critical moments so you don't find yourself with -no cards to play. That means the only control you actually have is via -the backend, by parameterizing the runtime of the application using the API. In -practice, you should always have a feature flag to control any relevant piece of -code. There is no such thing as "too small code change for a feature flag". What -you should ask yourself is: - -> If the code I'm writing breaks and stays broken for around a month, do I care? +blocked on the store. Those cases aren't recurrent, but you should always +assume the store will deny updates on critical moments so you don't find +yourself with no cards to play. That means the only control you actually have +is via the backend, by parameterizing the runtime of the application using the +API. In practice, you should always have a feature flag to control any relevant +piece of code. There is no such thing as "too small code change for a feature +flag". What you should ask yourself is: + +____ +If the code I'm writing breaks and stays broken for around a month, do I care? +____ If you're doing an experimental screen, or something that will have a very small -impact you might answer "no" to the above question. For everything else, the +impact you might answer "no" to the above question. For everything else, the answer will be "yes": bug fixes, layout changes, refactoring, new screen, -filesystem/database changes, *etc*. +filesystem/database changes, _etc_. -## Experiment +== Experiment An experiment is a feature flag where you care about analytical value of the -flag, and how it might impact user's behaviour. A feature flag with analytics. +flag, and how it might impact user's behaviour. A feature flag with analytics. They are also usually medium-lived, being relevant as long as the new code is -being developed. The most common rule is A/B test. +being developed. The most common rule is A/B test. -On the **backend**, an experiment rely on an analytical environment that will -pick the A/B test groups and distributions, which means those can't be held in -memory easily. That also means that you'll need a fallback value in case -fetching the group for a given customer fails. +On the *backend*, an experiment rely on an analytical environment that will pick +the A/B test groups and distributions, which means those can't be held in memory +easily. That also means that you'll need a fallback value in case fetching the +group for a given customer fails. -On the **frontend** and on **mobile** they are no different from feature flags. +On the *frontend* and on *mobile* they are no different from feature flags. -## Operational toggle +== Operational toggle An operational toggle is like a system-level manual circuit breaker, where you -turn on/off a feature, fail over the load to a different server, *etc*. They are -useful switches to have during an incident. +turn on/off a feature, fail over the load to a different server, _etc_. They +are useful switches to have during an incident. They are usually long-lived, being relevant as long as the code is in -production. The most common rule is percentages. +production. The most common rule is percentages. They can be feature flags that are promoted to operational toggles on the -**backend**, or may be purposefully put in place preventively or after a +*backend*, or may be purposefully put in place preventively or after a postmortem analysis. -On the **frontend** and on **mobile** they are similar to feature flags, where -the "feature" is being turned on and off, and the client interprets this value -to show if the "feature" is available or unavailable. +On the *frontend* and on *mobile* they are similar to feature flags, where the +"feature" is being turned on and off, and the client interprets this value to +show if the "feature" is available or unavailable. -## Best practices +== Best practices -### Prefer dynamic content +=== Prefer dynamic content Even though feature flags give you more dynamicity, they're still somewhat manual: you have to create one for a specific feature and change it by hand. If you find yourself manually updating a feature flags every other day, or -tweaking the percentages frequently, consider making it fully dynamic. Try +tweaking the percentages frequently, consider making it fully dynamic. Try using a dataset that is generated automatically, or computing the content on the fly. Say you have a configuration screen with a list of options and sub-options, and -you're trying to find how to better structure this list. Instead of using a -feature flag for switching between 3 and 5 options, make it fully dynamic. This +you're trying to find how to better structure this list. Instead of using a +feature flag for switching between 3 and 5 options, make it fully dynamic. This way you'll be able to perform other tests that you didn't plan, and get more flexibility out of it. -### Use the client version to negotiate feature flags +=== Use the client version to negotiate feature flags After effectively finishing a feature, the old code that coexisted with the new one will be deleted, and all traces of the transition will vanish from the code -base. However if you just remove the feature flags from the API, all of the old +base. However if you just remove the feature flags from the API, all of the old versions of clients that relied on that value to show the new feature will go downgrade to the old feature. This means that you should avoid deleting client-facing feature flags, and retire them instead: use the client version to decide when the feature is stable, and return `true` for every client with a version greater or equal to -that. This way you can stop thinking about the feature flag, and you don't break -or downgrade clients that didn't upgrade past the transition. +that. This way you can stop thinking about the feature flag, and you don't +break or downgrade clients that didn't upgrade past the transition. -### Beware of many nested feature flags +=== Beware of many nested feature flags Nested flags combine exponentially. Pick strategic entry points or transitions eligible for feature flags, and beware of their nesting. -### Include feature flags in the development workflow +=== Include feature flags in the development workflow Add feature flags to the list of things to think about during whiteboarding, and deleting/retiring a feature flags at the end of the development. -### Always rely on a feature flag on the app +=== Always rely on a feature flag on the app -Again, there is no such thing "too small for a feature flag". Too many feature -flags is a good problem to have, not the opposite. Automate the process of +Again, there is no such thing "too small for a feature flag". Too many feature +flags is a good problem to have, not the opposite. Automate the process of creating a feature flag to lower its cost. diff --git a/src/content/blog/2020/10/20/wrong-interviewing.adoc b/src/content/blog/2020/10/20/wrong-interviewing.adoc index 9cdfefb..89f93b8 100644 --- a/src/content/blog/2020/10/20/wrong-interviewing.adoc +++ b/src/content/blog/2020/10/20/wrong-interviewing.adoc @@ -1,51 +1,49 @@ ---- -title: How not to interview engineers -date: 2020-10-20 -updated_at: 2020-10-24 -layout: post -lang: en -ref: how-not-to-interview-engineers ---- -This is a response to Slava's -"[How to interview engineers][how-to-interview-engineers]" article. I initially -thought it was a satire, [as have others][poes-law-comment], but he has -[doubled down on it][slava-on-satire]: - -> (...) Some parts are slightly exaggerated for sure, but the essay isn't meant -> as a joke. += How not to interview engineers + +:bad-article: https://defmacro.substack.com/p/how-to-interview-engineers +:satire-comment: https://defmacro.substack.com/p/how-to-interview-engineers/comments#comment-599996 +:double-down: https://twitter.com/spakhm/status/1315754730740617216 +:poes-law: https://en.wikipedia.org/wiki/Poe%27s_law +:hn-comment-1: https://news.ycombinator.com/item?id=24757511 + +This is a response to Slava's "{bad-article}[How to interview engineers]" +article. I initially thought it was a satire, {satire-comment}[as have others], +but he has [doubled down on it]: + +____ +(...) Some parts are slightly exaggerated for sure, but the essay isn't meant as +a joke. +____ That being true, he completely misses the point on how to improve hiring, and -proposes a worse alternative on many aspects. It doesn't qualify as provocative, -it is just wrong. +proposes a worse alternative on many aspects. It doesn't qualify as +provocative, it is just wrong. I was comfortable taking it as a satire, and I would just ignore the whole thing if it wasn't (except for the technical memo part), but friends of mine -considered it to be somewhat reasonable. This is a adapted version of parts of -the discussions we had, risking becoming a gigantic showcase of -[Poe's law][poes-law-wiki]. +considered it to be somewhat reasonable. This is a adapted version of parts of +the discussions we had, risking becoming a gigantic showcase of {poes-law}[Poe's +law]. In this piece, I will argument against his view, and propose an alternative approach to improve hiring. It is common to find people saying how broken technical hiring is, as well put -in words by a phrase on [this comment][hn-satire]: +in words by a phrase on {hn-comment-1}[this comment]: -> Everyone loves to read and write about how developer interviewing is flawed, -> but no one wants to go out on a limb and make suggestions about how to improve -> it. +____ +Everyone loves to read and write about how developer interviewing is flawed, but +no one wants to go out on a limb and make suggestions about how to improve it. +____ I guess Slava was trying to not fall on this trap, and make a suggestion on how to improve instead, which all went terribly wrong. -[how-to-interview-engineers]: https://defmacro.substack.com/p/how-to-interview-engineers -[poes-law-comment]: https://defmacro.substack.com/p/how-to-interview-engineers/comments#comment-599996 -[slava-on-satire]: https://twitter.com/spakhm/status/1315754730740617216 -[poes-law-wiki]: https://en.wikipedia.org/wiki/Poe%27s_law -[hn-satire]: https://news.ycombinator.com/item?id=24757511 +== What not to do -## What not to do +=== Time candidates -### Time candidates +:hammock-driven-talk: https://www.youtube.com/watch?v=f84n5oFoZBc Timing the candidate shows up on the "talent" and "judgment" sections, and they are both bad ideas for the same reason: programming is not a performance. @@ -55,270 +53,280 @@ psychologists. For a pianist, their state of mind during concerts is crucial: they not only must be able to deal with stage anxiety, but to become really successful they -will have to learn how to exploit it. The time window of the concert is what +will have to learn how to exploit it. The time window of the concert is what people practice thousands of hours for, and it is what defines one's career, since how well all the practice went is irrelevant to the nature of the -profession. Being able to leverage stage anxiety is an actual goal of them. +profession. Being able to leverage stage anxiety is an actual goal of them. That is also applicable to athletes, where the execution during a competition makes them sink or swim, regardless of how all the training was. -The same cannot be said about composers, though. They are more like book +The same cannot be said about composers, though. They are more like book writers, where the value is not on very few moments with high adrenaline, but on -the aggregate over hours, days, weeks, months and years. A composer may have a +the aggregate over hours, days, weeks, months and years. A composer may have a deadline to finish a song in five weeks, but it doesn't really matter if it is done on a single night, every morning between 6 and 9, at the very last week, or -any other way. No rigid time structure applies, only whatever fits best to the +any other way. No rigid time structure applies, only whatever fits best to the composer. Programming is more like composing than doing a concert, which is another way of -saying that programming is not a performance. People don't practice algorithms +saying that programming is not a performance. People don't practice algorithms for months to keep them at their fingertips, so that finally in a single afternoon they can sit down and write everything at once in a rigid 4 hours window, and launch it immediately after. Instead software is built iteratively, by making small additions, than -refactoring the implementation, fixing bugs, writing a lot at once, *etc*. -all while they get a firmer grasp of the problem, stop to think about it, come -up with new ideas, *etc*. +refactoring the implementation, fixing bugs, writing a lot at once, _etc_. all +while they get a firmer grasp of the problem, stop to think about it, come up +with new ideas, _etc_. Some specifically plan for including spaced pauses, and call it -"[Hammock Driven Development][hammock-driven-development]", which is just -artist's "creative idleness" for hackers. +"{hammock-driven-talk}[Hammock Driven Development]", which is just artist's +"creative idleness" for hackers. Unless you're hiring for a live coding group, a competitive programming team, or a professional live demoer, timing the candidate that way is more harmful than -useful. This type of timing doesn't find good programmers, it finds performant +useful. This type of timing doesn't find good programmers, it finds performant programmers, which isn't the same thing, and you'll end up with people who can do great work on small problems but who might be unable to deal with big -problems, and loose those who can very well handle huge problems, slowly. If you -are lucky you'll get performant people who can also handle big problems on the -long term, but maybe not. +problems, and loose those who can very well handle huge problems, slowly. If +you are lucky you'll get performant people who can also handle big problems on +the long term, but maybe not. An incident is the closest to a "performance" that it gets, and yet it is still -dramatically different. Surely it is a high stress scenario, but while people +dramatically different. Surely it is a high stress scenario, but while people are trying to find a root cause and solve the problem, only the downtime itself -is visible to the exterior. It is like being part of the support staff backstage -during a play: even though execution matters, you're still not on the spot. -During an incident you're doing debugging in anger rather than live coding. +is visible to the exterior. It is like being part of the support staff +backstage during a play: even though execution matters, you're still not on the +spot. During an incident you're doing debugging in anger rather than live +coding. -Although giving a candidate the task to write a "technical memo" has -potential to get a measure of the written communication skills of someone, doing -so in a hard time window also misses the point for the same reasons. +Although giving a candidate the task to write a "technical memo" has potential +to get a measure of the written communication skills of someone, doing so in a +hard time window also misses the point for the same reasons. -[hammock-driven-development]: https://www.youtube.com/watch?v=f84n5oFoZBc +=== Pay attention to typing speed -### Pay attention to typing speed +:dijkstra-typing: https://www.cs.utexas.edu/users/EWD/transcriptions/EWD05xx/EWD512.html +:speech-to-text: https://www.youtube.com/watch?v=Mz3JeYfBTcY +:j-lang: https://www.jsoftware.com/#/ Typing is speed in never the bottleneck of a programmer, no matter how great they are. -As [Dijkstra said][dijkstra-typing]: +As {dijkstra-typing}[Dijkstra said]: -> But programming, when stripped of all its circumstantial irrelevancies, boils -> down to no more and no less than very effective thinking so as to avoid -> unmastered complexity, to very vigorous separation of your many different -> concerns. +____ +But programming, when stripped of all its circumstantial irrelevancies, boils +down to no more and no less than very effective thinking so as to avoid +unmastered complexity, to very vigorous separation of your many different +concerns. +____ In other words, programming is not about typing, it is about thinking. Otherwise, the way to get those star programmers that can't type fast enough a -huge productivity boost is to give them a touch typing course. If they are so +huge productivity boost is to give them a touch typing course. If they are so productive with typing speed being a limitation, imagine what they could accomplish if they had razor sharp touch typing skills? Also, why stop there? A good touch typist can do 90 WPM (words per minute), and a great one can do 120 WPM, but with a stenography keyboard they get to 200 -WPM+. That is double the productivity! Why not try -[speech-to-text][perl-out-loud]? Make them all use [J][j-lang] so they all need -to type less! How come nobody thought of that? +WPM+. That is double the productivity! Why not try +{speech-to-text}[speech-to-text]? Make them all use {j-lang}[J] so they all need +to type less! How come nobody thought of that? And if someone couldn't solve the programming puzzle in the given time window, but could come back in the following day with an implementation that is not only faster, but uses less memory, was simpler to understand and easier to read than anybody else? You'd be losing that person too. -[dijkstra-typing]: https://www.cs.utexas.edu/users/EWD/transcriptions/EWD05xx/EWD512.html -[j-lang]: https://www.jsoftware.com/#/ -[perl-out-loud]: https://www.youtube.com/watch?v=Mz3JeYfBTcY +=== IQ -### IQ +:determination-article: https://www.paulgraham.com/determination.html +:scihub-article: https://sci-hub.do/https://psycnet.apa.org/doiLanding?doi=10.1037%2F1076-8971.6.1.33 -For "building an extraordinary team at a hard technology startup", intelligence -is not the most important, [determination is][pg-determination]. +For "building an extraordinary team at a hard technology startup", +intelligence is not the most important, +{determination-article}[determination is]. -And talent isn't "IQ specialized for engineers". IQ itself isn't a measure of how -intelligent someone is. Ever since Alfred Binet with Théodore Simon started to -formalize what would become IQ tests years later, they already acknowledged +And talent isn't "IQ specialized for engineers". IQ itself isn't a measure of +how intelligent someone is. Ever since Alfred Binet with Théodore Simon started +to formalize what would become IQ tests years later, they already acknowledged limitations of the technique for measuring intelligence, which is -[still true today][scihub-paper]. +{scihub-article}[still true today]. So having a high IQ tells only how smart people are for a particular aspect of -intelligence, which is not representative of programming. There are numerous +intelligence, which is not representative of programming. There are numerous aspects of programming that are covered by IQ measurement: how to name variables and functions, how to create models which are compatible with schema evolution, how to make the system dynamic for runtime parameterization without making it fragile, how to measure and observe performance and availability, how to pick -between acquiring and paying technical debt, *etc*. +between acquiring and paying technical debt, _etc_. Not to say about everything else that a programmer does that is not purely -programming. Saying high IQ correlates with great programming is a stretch, at +programming. Saying high IQ correlates with great programming is a stretch, at best. -[pg-determination]: http://www.paulgraham.com/determination.html -[scihub-paper]: https://sci-hub.do/https://psycnet.apa.org/doiLanding?doi=10.1037%2F1076-8971.6.1.33 - -### Ditch HR +=== Ditch HR Slava tangentially picks on HR, and I will digress on that a bit: -> A good rule of thumb is that if a question could be asked by an intern in HR, -> it's a non-differential signaling question. +____ +A good rule of thumb is that if a question could be asked by an intern in HR, +it's a non-differential signaling question. +____ -Stretching it, this is a rather snobbish view of HR. Why is it that an intern in -HR can't make signaling questions? Could the same be said of an intern in +Stretching it, this is a rather snobbish view of HR. Why is it that an intern +in HR can't make signaling questions? Could the same be said of an intern in engineering? -In other words: is the question not signaling because the one -asking is from HR, or because the one asking is an intern? If the latter, than -he's just arguing that interns have no place in interviewing, but if the former -than he was picking on HR. +In other words: is the question not signaling because the one asking is from HR, +or because the one asking is an intern? If the latter, than he's just arguing +that interns have no place in interviewing, but if the former than he was +picking on HR. Extrapolating that, it is common to find people who don't value HR's work, and only see them as inferiors doing unpleasant work, and who aren't capable enough -(or *smart* enough) to learn programming. +(or _smart_ enough) to learn programming. -This is equivalent to people who work primarily on backend, and see others working on -frontend struggling and say: "isn't it just building views and showing them on -the browser? How could it possibly be that hard? I bet I could do it better, -with 20% of code". As you already know, the answer to it is "well, why don't you -go do it, then?". +This is equivalent to people who work primarily on backend, and see others +working on frontend struggling and say: "isn't it just building views and +showing them on the browser? How could it possibly be that hard? I bet I could +do it better, with 20% of code". As you already know, the answer to it is +"well, why don't you go do it, then?". This sense of superiority ignores the fact that HR have actual professionals -doing actual hard work, not unlike programmers. If HR is inferior and so easy, +doing actual hard work, not unlike programmers. If HR is inferior and so easy, why not automate everything away and get rid of a whole department? I don't attribute this world view to Slava, this is only an extrapolation of a snippet of the article. -### Draconian mistreating of candidates +=== Draconian mistreating of candidates + +:bad-apple: https://www.paulgraham.com/apple.html +:be-good: https://www.paulgraham.com/good.html If I found out that people employed theatrics in my interview so that I could feel I've "earned the privilege to work at your company", I would quit. If your moral compass is so broken that you are comfortable mistreating me while I'm a candidate, I immediately assume you will also mistreat me as an employee, -and that the company is not a good place to work, as -[evil begets stupidity][evil-begets-stupidity]: - -> But the other reason programmers are fussy, I think, is that evil begets -> stupidity. An organization that wins by exercising power starts to lose the -> ability to win by doing better work. And it's not fun for a smart person to -> work in a place where the best ideas aren't the ones that win. I think the -> reason Google embraced "Don't be evil" so eagerly was not so much to impress -> the outside world as to inoculate themselves against arrogance. +and that the company is not a good place to work, as {bad-apple}[evil begets +stupidity]: + +____ +But the other reason programmers are fussy, I think, is that evil begets +stupidity. An organization that wins by exercising power starts to lose the +ability to win by doing better work. And it's not fun for a smart person to +work in a place where the best ideas aren't the ones that win. I think the +reason Google embraced "Don't be evil" so eagerly was not so much to impress the +outside world as to inoculate themselves against arrogance. +____ Paul Graham goes beyond "don't be evil" with a better motto: -"[be good][pg-be-good]". +"{be-good}[be good]". Abusing the asymmetric nature of an interview to increase the chance that the -candidate will accept the offer is, well, abusive. I doubt a solid team can +candidate will accept the offer is, well, abusive. I doubt a solid team can actually be built on such poor foundations, surrounded by such evil measures. And if you really want to give engineers "the measure of whoever they're going to be working with", there are plenty of reasonable ways of doing it that don't include performing fake interviews. -[pg-be-good]: http://www.paulgraham.com/good.html -[evil-begets-stupidity]: http://www.paulgraham.com/apple.html - -### Personality tests +=== Personality tests Personality tests around the world need to be a) translated, b) adapted and c) -validated. Even though a given test may be applicable and useful in a country, +validated. Even though a given test may be applicable and useful in a country, this doesn't imply it will work for other countries. Not only tests usually come with translation guidelines, but also its applicability needs to be validated again after the translation and adaptation is done to see if the test still measures what it is supposed to. -That is also true within the same language. If a test is shown to work in -England, it may not work in New Zealand, in spite of both speaking english. The +That is also true within the same language. If a test is shown to work in +England, it may not work in New Zealand, in spite of both speaking english. The cultural context difference is influent to the point of invalidating a test and making it be no longer valid. -Irregardless of the validity of the proposed "big five" personality test, -saying "just use attributes x, y and z this test and you'll be fine" is a rough +Irregardless of the validity of the proposed "big five" personality test, saying +"just use attributes x, y and z this test and you'll be fine" is a rough simplification, much like saying "just use Raft for distributed systems, after all it has been proven to work" shows he throws all of that background away. So much as applying personality tests themselves is not a trivial task, and psychologists do need special training to become able to effectively apply one. -### More cargo culting +=== More cargo culting + +:cult: https://calteches.library.caltech.edu/51/2/CargoCult.htm +:cult-archived: https://web.archive.org/web/20201003090303/https://calteches.library.caltech.edu/51/2/CargoCult.htm He calls the ill-defined "industry standard" to be cargo-culting, but his proposal isn't sound enough to not become one. -Even if the ideas were good, they aren't solid enough, or based on solid -enough things to make them stand out by themselves. Why is it that talent, -judgment and personality are required to determine the fitness of a good -candidate? Why not 2, 5, or 20 things? Why those specific 3? Why is talent -defined like that? Is it just because he found talent to be like that? +Even if the ideas were good, they aren't solid enough, or based on solid enough +things to make them stand out by themselves. Why is it that talent, judgment +and personality are required to determine the fitness of a good candidate? Why +not 2, 5, or 20 things? Why those specific 3? Why is talent defined like that? +Is it just because he found talent to be like that? Isn't that definitionally also -[cargo-culting][cargo-culting][^cargo-culting-archive]? Isn't he just repeating -whatever he found to work form him, without understanding why? +{cult}[cargo-culting]footnote:cargo-cult[ + {cult-archived}[Archived version]. +]? Isn't he just repeating whatever he found to work form him, without +understanding why? What Feynman proposes is actually the opposite: -> In summary, the idea is to try to give **all** of the information to help others -> to judge the value of your contribution; not just the information that leads -> to judgment in one particular direction or another. +____ +In summary, the idea is to try to give *all* of the information to help others +to judge the value of your contribution; not just the information that leads to +judgment in one particular direction or another. +____ What Slava did was just another form of cargo culting, but this was one that he believed to work. -[cargo-culting]: http://calteches.library.caltech.edu/51/2/CargoCult.htm -[^cargo-culting-archive]: [Archived version](https://web.archive.org/web/20201003090303/http://calteches.library.caltech.edu/51/2/CargoCult.htm). - -## What to do +== What to do I will not give you a list of things that "worked for me, thus they are -correct". I won't either critique the current "industry standard", nor what I've -learned from interviewing engineers. +correct". I won't either critique the current "industry standard", nor what +I've learned from interviewing engineers. Instead, I'd like to invite you to learn from history, and from what other professionals have to teach us. Programming isn't an odd profession, where everything about it is different from -anything else. It is just another episode in the "technology" series, which has -seasons since before recorded history. It may be an episode where things move a +anything else. It is just another episode in the "technology" series, which has +seasons since before recorded history. It may be an episode where things move a bit faster, but it is fundamentally the same. -So here is the key idea: what people did *before* software engineering? +So here is the key idea: what people did _before_ software engineering? -What hiring is like for engineers in other areas? Don't civil, electrical and +What hiring is like for engineers in other areas? Don't civil, electrical and other types of engineering exist for much, much longer than software engineering -does? What have those centuries of accumulated experience thought the world +does? What have those centuries of accumulated experience thought the world about technical hiring? What studies were performed on the different success rate of interviewing -strategies? What have they done right and what have they done wrong? +strategies? What have they done right and what have they done wrong? What is the purpose of HR? Why do they even exist? Do we need them, and if so, -what for? What is the value they bring, since everybody insist on building an HR -department in their companies? Is the existence of HR another form of cargo +what for? What is the value they bring, since everybody insist on building an +HR department in their companies? Is the existence of HR another form of cargo culting? What is industrial and organizational psychology? What is that field of study? What do they specialize in? What have they learned since the discipline -appeared? What have they done right and wrong over history? Is is the current -academic consensus on that area? What is a hot debate topic in academia on that -area? What is the current bleeding edge of research? What can they teach us -about hiring? What can they teach us about technical hiring? +appeared? What have they done right and wrong over history? Is is the current +academic consensus on that area? What is a hot debate topic in academia on that +area? What is the current bleeding edge of research? What can they teach us +about hiring? What can they teach us about technical hiring? -## Conclusion +== Conclusion If all I've said makes me a "no hire" in the proposed framework, I'm really glad. |