├── LICENSE ├── README.md ├── design-patterns ├── active-record.md ├── dont-repeat-yourself.md ├── inversion-of-control.md └── law-of-demeter.md └── snippets └── kill-the-if-chain.md /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Back-End Developer Interview Questions 2 | ====================================== 3 | 4 | This page has been translated to [Chinese](https://github.com/monklof/Back-End-Developer-Interview-Questions) by [monklof](https://github.com/monklof). 5 | 6 | I started writing down this list as my personal notes of topics I discussed with colleagues and friends, and that I wanted to deepen... 7 | 8 | I'm not a big fan of asking technical questions in job interviews: I rather prefer to sit together with candidates in front of some real code, hands on the keyboard, facing a real problem, and to have a full day of pair programming, hopefully rotating with all the other team members. It is one of the best opportunities to know each others' style and to let candidates know some details about their future job. 9 | 10 | Yet, I feel some categories of technical questions could be a good starting point to begin an engaging conversation. 11 | 12 | This repo collects a number of back-end related questions that can be used when vetting potential candidates. It is by no means recommended to use every single question on the same candidate: that would take hours, and would have no sense at all, as they cover a too broad set of topics for a single developer's to possibly know. Browse the section you find more relevant for your context, and pick the questions that give you more ideas on the conversation to have. 13 | 14 | This project is admittedly inspired by [Front-end Job Interview Questions](https://github.com/darcyclarke/Front-end-Developer-Interview-Questions) by [@darcyclarke](https://github.com/darcyclarke) 15 | 16 | ## Where are the answers? 17 | I didn't include any.
18 | Most of the questions are open-ended, and some of them just don't have a *right* or a *wrong* answer. On the contrary, they are intended to be used as the starting point for a conversation that hopefully tells you more about the person's capabilities than a straight answer would. Personally, I would even choose the questions whose answers are not yet clear to me. 19 | 20 | Feel free to open a [Discussion](https://github.com/arialdomartini/Back-End-Developer-Interview-Questions/discussions). 21 | 22 | 23 | 24 | 25 | 26 | ## Table of Contents 27 | 28 | * [Questions about Design Patterns](#patterns) 29 | * [Globals Are Evil](#globals-are-evil) 30 | * [Inversion of Control](#inversion-of-control) 31 | * [Law of Demeter](#law-of-demeter) 32 | * [Active-Record](#active-record) 33 | * [Data-Mapper](#data-mapper) 34 | * [Billion-Dollar Mistake](#billion-dollar-mistake) 35 | * [Inheritance vs Composition](#inheritance-vs-composition) 36 | * [Anti-Corruption Layer](#anti-corruption-layer) 37 | * [Singleton](#singleton) 38 | * [Data Abstraction](#data-abstraction) 39 | * [Don't Repeat Yourself](#dont-repeat-yourself) 40 | * [Dependency Hell](#dependency-hell) 41 | * [Goto Is Evil](#goto-is-evil) 42 | * [Robustness Principle](#robustness-principle) 43 | * [Separation of Concerns](#separation-of-concerns) 44 | 45 | * [Questions about Code Design](#design) 46 | * [High Cohesion, Loose Coupling](#high-cohesion-loose-coupling) 47 | * [Index 0](#index-0) 48 | * [TDD](#tdd) 49 | * [DRY Violation](#dry-violation) 50 | * [Cohesion vs Coupling](#cohesion-vs-coupling) 51 | * [Refactoring](#refactoring) 52 | * [Code Comments](#code-comments) 53 | * [Design vs Architecture](#design-vs-architecture) 54 | * [Early Testing](#early-testing) 55 | * [Multiple Inheritance](#multiple-inheritance) 56 | * [Domain Logic in Stored Procedures](#domain-logic-in-stored-procedures) 57 | * [OOP Took Over the World](#oop-took-over-the-world) 58 | * [Bad Design](#bad-design) 59 | 60 | * [Questions about languages](#languages) 61 | * [3 Worst Defects](#3-worst-defects) 62 | * [Functional Programming](#functional-programming) 63 | * [Closures](#closures) 64 | * [Generics](#generics) 65 | * [High-Order Functions](#high-order-functions) 66 | * [Loops and Recursion](#loops-and-recursion) 67 | * [Functions as First-Class Citizens](#functions-as-first-class-citizens) 68 | * [Anonymous Functions](#anonymous-functions) 69 | * [Static and Dynamic Typing](#static-and-dynamic-typing) 70 | * [Namespaces](#namespaces) 71 | * [Language Interoperability](#language-interoperability) 72 | * [Hate of Java](#hate-of-java) 73 | * [Good and Bad Languages](#good-and-bad-languages) 74 | * [Referential Transparency](#referencial-transparency) 75 | * [Stack and Heap](#stack-and-heap) 76 | * [Pattern Matching](#pattern-matching) 77 | * [Exceptions](#exceptions) 78 | * [Variant and Contravariant Inheritance](#variant-and-contravariant-inheritance) 79 | * [Constructors and Interfaces](#constructors-and-interfaces) 80 | * [Node.js](#node-js) 81 | * [Java and Time Traveling](#java-and-time-traveling) 82 | * [Eliminate Null](#eliminate-null) 83 | 84 | * [Web Questions](#web) 85 | * [3rd Party Cookies](#3rd-party-cookies) 86 | * [API Versioning](#api-versioning) 87 | * [SPAs](#spas) 88 | * [Statelessness](#statelessness) 89 | * [REST vs SOAP](#rest-vs-soap) 90 | * [MVC and MVVM](#mvc-and-mvvm) 91 | 92 | * [Databases Questions](#databases) 93 | * [DB Migrations](#db-migrations) 94 | * [NULL is special](#null-is-special) 95 | * [ACID](#acid) 96 | * [Schema Migrations](#schema-migrations) 97 | * [Lazy Loading](#lazy-loading) 98 | * [N+1 Problem](#n1-problem) 99 | * [Slowest Queries](#slowest-queries) 100 | * [Normalization](#normalization) 101 | * [Blue/Green Deployment](#bluegreen-deployment) 102 | 103 | * [NoSQL Questions](#nosql) 104 | * [Eventual Consistency](#eventual-consistency) 105 | * [CAP Theorem](#cap-theorem) 106 | * [NoSql](#nosql) 107 | * [NoSQL and Scalability](#nosql-and-scalability) 108 | * [Document and Relational DBs](#document-and-relational-dbs) 109 | 110 | * [Code Versioning Questions](#codeversioning) 111 | * [Branching in HG and in Git](#branching-in-hg-and-in-git) 112 | * [DVCS](dvcs) 113 | * [GitFlow and GitHubFlow](#gitflow-and-githubflow) 114 | * [Rebase](#rebase) 115 | * [Merging in HG and in Git](#merging-in-hg-and-in-git) 116 | 117 | * [Questions about Concurrency](#concurrency) 118 | * [Why?](#why) 119 | * [Testing Concurrency](#testing-concurrency) 120 | * [Race Conditions](#race-conditions) 121 | * [Deadlocks](#deadlocks) 122 | * [Process Starvation](#process-starvation) 123 | * [Free Algorithm](#free-algorithm) 124 | 125 | * [Questions about Distributed Systems](#distributed) 126 | * [Testing Distributed Systems](#testing-distributed-systems) 127 | * [Async Communication](#async-communication) 128 | * [Pitfalls of RPC](#pitfalls-of-rpc) 129 | * [Design of Distributed Systems](#design-of-distributed-systems) 130 | * [Fault Tolerance](#fault-tolerance) 131 | * [Failures](#failures) 132 | * [Network Partitions](#network-partitions) 133 | * [Fallacies of Distributed Computing](#fallacies-of-distibuted-computing) 134 | * [Request/Reply vs Publish/Subscribe](#requestreply-vs-publishsubscribe) 135 | * [Implement Transactions](#implement-transactions) 136 | 137 | * [Questions about Software Lifecycle and Team Management](#management) 138 | * [Agility](#agility) 139 | * [Legacy Code](#legacy-code) 140 | * [Legacy Code ELI5](#legacy-code-eli5) 141 | * [Sell me Kanban](#sell-me-kanban) 142 | * [Agile vs Waterfall](#agile-vs-waterfall) 143 | * [Death by Meetings](#death-by-meetings) 144 | * [Late Projects](#late-projects) 145 | * [Agile Manifesto](#agile-manifesto) 146 | * [If I were the CTO](#if-i-were-the-cto) 147 | * [PMs](#pms) 148 | * [Team Organization](#team-organization) 149 | * [Turn Over](#turn-over) 150 | * [Qualities](#qualities) 151 | * [3 Things About Code](#3-things-about-code) 152 | * [1 Month's Revolution](#1-months-revolution) 153 | 154 | * [Questions about logic and algorithms](#algorithms) 155 | * [FIFO with LIFO](#fifo-with-lifo) 156 | * [Stack Overflow](#stack-overflow) 157 | * [Tail Recursive n!](#tail-recursive-n) 158 | * [REPL](#repl) 159 | * [Defragger](#defragger) 160 | * [Mazes](#mazes) 161 | * [Memory Leaks](#memory-leaks) 162 | * [PRNG](#prng) 163 | * [Garbage Collecting](#garbage-collecting) 164 | * [Queues](#queues) 165 | * [Simple Web Server](#simple-web-server) 166 | * [Sorting Huge Files](#sorting-huge-files) 167 | * [Duplicates](#duplicates) 168 | 169 | * [Questions about Software Architecture](#architecture) 170 | * [No Cache](#no-cache) 171 | * [Event-Driven Architecture](#event-driven-architecture) 172 | * [Readability](#readability) 173 | * [Emergent and Evolutionary](#emergent-and-evolutionary) 174 | * [Scale-Out, Scale-Up](#scale-out-scale-up) 175 | * [Failures User Sessions](#failures-user-sessions) 176 | * [CQRS](#cqrs) 177 | * [n-tier](#n-tier) 178 | * [Scalability](#scalability) 179 | * [C10K](#c10k) 180 | * [P2P](#p2p) 181 | * [CGI](#cgi) 182 | * [Vendor Lock-in](#vendor-lock-in) 183 | * [Pub/Sub](#pubsub) 184 | * [CPUs](#cpus) 185 | * [Performance](#performance) 186 | * [DDOS](#ddos) 187 | * [Performance and Scalability](#performance-and-scalability) 188 | * [Tight Coupling](#tight-coupling) 189 | * [Cloud Readiness](#cloud-readiness) 190 | * [Emergent Architecture](#emergent-architecture) 191 | * [Design, Architecture, Functionality, Aesthetic](#design-architecture-functionality-aesthetic) 192 | 193 | * [Questions about Service Oriented Architecture and Microservices](#soa) 194 | * [Long-lived Transactions](#long-lived-transactions) 195 | * [SOA and Micro Services](#soa-and-micro-services) 196 | * [Versioning and Breaking Changes](#versioning-and-breaking-changes) 197 | * [Sagas and compensations](#sagas-and-compensations) 198 | * [Too Micro](#too-micro "Too Micro") 199 | * [Micro Services Architecture](#micro-services-architecture) 200 | 201 | * [Questions about Security](#security) 202 | * [Security by Default](#security-by-default) 203 | * [Don't Invent Cryptography](#dont-invent-cryptography) 204 | * [2-FA](#2-fa) 205 | * [Confidential Data in Logs](#confidential-data-in-logs) 206 | * [SQL Injection](#sql-injection) 207 | * [Detect SQL Injection](#detect-sql-injection) 208 | * [XSS](#xss) 209 | * [Cross-Site Forgery Attack](#cross-site-forgery-attack) 210 | * [HTTPS](#https) 211 | * [MITM Attack](#mitm-attack) 212 | * [Stealing Sessions](#stealing-sessions) 213 | 214 | * [General Questions](#general) 215 | * [Why FP?](#why-fp) 216 | * [Browsers](#browsers) 217 | * [TCP Sockets](#tcp-sockets) 218 | * [Encapsulation](#encapsulation) 219 | * [Real-time systems](#real-time-systems) 220 | * [Real-time and memory allocation](#real-time-and-memory-allocation) 221 | * [Immutability](#immutability) 222 | * [Mutable vs Immutable](#mutable-vs-immutable) 223 | * [Object-Relational Impedance Mismatch](#object-relational-impedance-mismatch) 224 | * [Sizing a Cache](#sizing-a-cache) 225 | * [TCP and HTTP](#tcp-and-http) 226 | * [Client-Side vs Server-Side](#client-side-vs-server-side) 227 | * [Reliable and non-reliable channels](#reliable-and-non-reliable-channels) 228 | 229 | * [Open Questions](#open) 230 | * [Resistance to Change](#resistance-to-change) 231 | * [Threading ELI5](#threading-eli5) 232 | * [Innovation and Predictability](#innovation-and-predictability) 233 | * [Good Code](#good-code) 234 | * [Streaming](#streaming) 235 | * [1 Week Improvement](#1-week-improvement) 236 | * [Learnt this week](#learnt-this-week) 237 | * [Aesthetic](#aesthetic) 238 | * [Last 5 books](#last-5-books) 239 | * [Introducing CI/CD](#introducing-cicd) 240 | * [Reinvent the Wheel](#reinvent-the-wheel) 241 | * [Not Invented Here](#not-invented-here) 242 | * [Next Thing to Automate](#next-thing-to-automate) 243 | * [Coding is Hard](#coding-is-hard) 244 | * [Green Fields and Brown Fields](#green-fields-and-brown-fields) 245 | * [Type "Google.com"](#type-googlecom) 246 | * [While idle](#while-idle) 247 | * [Unicode](#unicode) 248 | * [Defending Monoliths](#defending-monoliths) 249 | * [Professional Developers](#professional-developers) 250 | * [It's an art](#its-an-art) 251 | * [People who like this also like...](#people-who-like-this-also-like) 252 | * [Corporations vs Startups](#corporations-vs-startups) 253 | * [I'm proud of](#im-proud-of) 254 | 255 | * [Questions based on snippets of code](#snippets) 256 | * [Beware the Closure](#beware-the-closure) 257 | * [Type Erasure](#type-erasure) 258 | * [Memory Leak](#memory-leak) 259 | * [Kill the switch](#kill-the-switch) 260 | * [Kill the if](#kill-the-if) 261 | * [Kill the if-chain](#kill-the-if-chain) 262 | 263 | * [Bill Gates Style Questions](#billgates) 264 | * [Mirrors](#mirrors) 265 | * [Clones](#clones) 266 | * [Revert](#revert) 267 | * [Quora](#quora) 268 | * [Cobol](#cobol) 269 | * [10 years](#10-years) 270 | * [Fire me](#fire-me) 271 | * [From scratch](#from-scratch) 272 | * [Telling lies](#telling-lies) 273 | * [Your past self](#your-past-self) 274 | 275 | 276 | 277 | 278 | ### [[↑]](#toc) Questions about Design Patterns: 279 | #### Globals Are Evil 280 | Why are global and static objects evil? Can you show it with a code example? 281 | 282 | #### Inversion of Control 283 | Tell me about Inversion of Control and how it improves the design of code.
284 | [Resources](design-patterns/inversion-of-control.md) 285 | 286 | 287 | #### Law of Demeter 288 | The Law of Demeter (the Principle of Least Knowledge) states that each unit should have only limited knowledge about other units and it should only talk to its immediate friends (sometimes stated as "don't talk to strangers").
289 | Would you write code violating this principle, show why it is a bad design and then fix it?
290 | [Resources](design-patterns/law-of-demeter.md) 291 | 292 | #### Active-Record 293 | Active-Record is the design pattern that promotes objects to include functions such as Insert, Update, and Delete, and properties that correspond to the columns in some underlying database table. In your opinion and experience, which are the limits and pitfalls of the this pattern?
294 | [Resources](design-patterns/active-record.md) 295 | 296 | #### Data-Mapper 297 | Data-Mapper is a design pattern that promotes the use of a layer of Mappers that moves data between objects and a database while keeping them independent of each other and the mapper itself. On the contrary, in Active-Record objects directly incorporate operations for persisting themselves to a database, and properties corresponding to the underlying database tables. Do you have an opinion on those patterns? When would you use one instead of the other? 298 | 299 | #### Billion Dollar Mistake 300 | [Tony Hoare](https://en.m.wikipedia.org/wiki/Tony_Hoare) who invented the null reference once said "*I call it my billion-dollar mistake*" since it led to "*innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years*". 301 | 302 | Would you discuss the techniques to avoid it, such as the Null Object Pattern introduced by the GOF book, or Option types? 303 | 304 | #### Inheritance vs Composition 305 | Many state that, in Object-Oriented Programming, composition is often a better option than inheritance. What's you opinion? 306 | 307 | #### Anti-Corruption Layer 308 | What is an Anti-corruption Layer? 309 | 310 | #### Singleton 311 | Singleton is a design pattern that restricts the instantiation of a class to one single object. Writing a Thread-Safe Singleton class is not so obvious. Would you try? 312 | 313 | #### Data Abstraction 314 | The ability to change implementation without affecting clients is called Data Abstraction. Produce an example violating this property, then fix it. 315 | 316 | #### Don't Repeat Yourself 317 | Write a snippet of code violating the Don't Repeat Yourself (DRY) principle. Then, fix it. 318 | 319 | #### Dependency Hell 320 | How would you deal with Dependency Hell? 321 | 322 | #### Goto is Evil 323 | Is goto evil? You may have heard of the famous paper "Go To Statement Considered Harmful" by Edsger Dijkstra, in which he criticized the use of the `goto` statement and advocated structured programming instead. The use of `goto` has always been controversial, so much that even Dijkstra's letter was criticized with articles such as "'GOTO Considered Harmful' Considered Harmful". What's your opinion on the use of `goto`? 324 | 325 | #### Robustness Principle 326 | The robustness principle is a general design guideline for software that recommends "*be conservative in what you send, be liberal in what you accept*". It is often reworded as "*be a tolerant reader and a careful writer*". Would you like to discuss the rationale of this principle? 327 | 328 | #### Separation of Concerns 329 | Separation of Concerns is a design principle for separating a computer program into distinct areas, each one addressing a separate concern. There are a lot of different mechanisms for achieving Separation of Concerns (use of objects, functions, modules, or patterns such as MVC and the like). Would you discuss this topic? 330 | 331 | 332 | ### [[↑]](#toc) Questions about Code Design: 333 | 334 | #### High Cohesion, Loose Coupling 335 | It is often said that one of the most important goals in Object-Oriented Design (and code design in general) is to have High Cohesion and Loose Coupling. What does it mean? Why is it that important and how is it achieved? 336 | 337 | #### Index 0 338 | Why do array indexes start with '0' in most languages? 339 | 340 | #### TDD 341 | How do tests and TDD influence code design? 342 | 343 | #### DRY Violation 344 | Write a snippet of code violating the Don't Repeat Yourself (DRY) principle. Then, explain why it is a bad design, and fix it. 345 | 346 | #### Cohesion vs Coupling 347 | What's the difference between cohesion and coupling? 348 | 349 | #### Refactoring 350 | What is refactoring useful for? 351 | 352 | #### Code Comments 353 | Are comments in code useful? Some say they should be avoided as much as possible, and hopefully made unnecessary. Do you agree? 354 | 355 | #### Design vs Architecture 356 | What is the difference between design and architecture? 357 | 358 | #### Early Testing 359 | In TDD, why are tests written before code? 360 | 361 | #### Multiple Inheritance 362 | C++ supports multiple inheritance, and Java allows a class to implement multiple interfaces. What impact does using these facilities have on orthogonality? Is there a difference in impact between using multiple inheritance and multiple interfaces? Is there a difference between using delegation and using inheritance? [This question is from The Pragmatic Programmer, by Andrew Hunt and David Thomas] 363 | 364 | #### Domain Logic in Stored Procedures 365 | What are the pros and cons of holding domain logic in Stored Procedures? 366 | 367 | #### OOP Took Over the World 368 | In your opinion, why has Object-Oriented Design dominated the market for so many years? 369 | 370 | #### Bad Design 371 | What would you do to understand if your code has a bad design? 372 | 373 | 374 | ### [[↑]](#toc) Questions about Languages: 375 | 376 | #### 3 worst defects 377 | Tell me the 3 worst defects of your preferred language 378 | 379 | #### Functional Programming 380 | Why is there a rising interest on Functional Programming? 381 | 382 | #### Closures 383 | What is a closure, and what is useful for? What's in common between closures and classes? 384 | 385 | #### Generics 386 | What are generics useful for? 387 | 388 | #### High-Order Functions 389 | What are higher-order functions? What are they useful for? Write one, in your preferred language. 390 | 391 | #### Loops and Recursion 392 | Write a loop, then transform it into a recursive function, using only immutable structures (i.e. avoid using variables). Discuss. 393 | 394 | #### Functions as First-Class Citizens 395 | What does it mean when a language treats functions as first-class citizens? 396 | Why is it important that in a language functions are first-class citizens? 397 | 398 | #### Anonymous Functions 399 | Show me an example where an anonymous function can be useful. 400 | 401 | #### Static and Dynamic typing 402 | There are a lot of different type systems. Let's talk about static and dynamic type systems, and about strong and weak ones. You surely have an opinion and a preference about this topic. Would you like to share them, and discuss why and when would you promote one particular type system for developing an enterprise software? 403 | 404 | #### Namespaces 405 | What are namespaces useful for? Invent an alternative. 406 | 407 | #### Language Interoperability 408 | Talk about interoperability between Java and C# (in alternative, choose 2 other arbitrary languages) 409 | 410 | #### Hate of Java 411 | Why do many software engineers not like Java? 412 | 413 | #### Good and Bad Languages 414 | What makes a good language good and a bad language bad? 415 | 416 | #### Referential Transparency 417 | Write two functions, one referentially transparent and the other one referentially opaque. Discuss. 418 | 419 | #### Stack and Heap 420 | What is a stack and what is a heap? What's a stack overflow? 421 | 422 | #### Pattern Matching 423 | Some languages, especially the ones that promote a functional approach, allow a technique called pattern matching. Do you know it? How is pattern matching different from switch clauses? 424 | 425 | #### Exceptions 426 | Why do some languages have no exceptions by design? What are the pros and cons? 427 | 428 | #### Variant and Contravariant Inheritance 429 | If `Cat` is an `Animal`, is `TakeCare` a `TakeCare`? 430 | 431 | #### Constructors and Interfaces 432 | In Java, C# and many other languages, why are constructors not part of the interface? 433 | 434 | #### Node.js 435 | In the last years there has been a lot of hype around Node.js. What's your opinion on using a language that was initially conceived to run in the browser in the backend? 436 | 437 | #### Java and time-traveling 438 | * Pretend you have a time machine and pretend that you have the opportunity to go to a particular point in time during Java's (or C#, Python, Go or whatever) history, and talk with some of the JDK architects. What would you try to convince them of? Removing checked exceptions? Adding unsigned primitives? Adding multiple-inheritance? 439 | #### Eliminate Null 440 | Imagine you want to remove the possibility to have null references in your preferred language: how would you achieve this goal? What consequences would this have? 441 | 442 | 443 | ### [[↑]](#toc) Questions about Web development: 444 | 445 | #### 3rd Party Cookies 446 | Why are first-party cookies and third-party cookies treated so differently? 447 | 448 | #### API Versioning 449 | How would you manage Web Services API versioning? 450 | 451 | #### SPAs 452 | From a backend perspective, are there any disadvantages or drawbacks on the adoption of Single Page Applications? 453 | 454 | #### Statelessness 455 | Why do we usually put so much effort for having stateless services? What's so good in stateless code and why and when is statefulness bad? 456 | 457 | #### REST vs SOAP 458 | REST and SOAP: when would you choose one, and when the other? 459 | 460 | #### MVC and MVVM 461 | In web development, Model-View Controller and Model-View-View-Model approaches are very common, both in the backend and in the frontend. What are they, and why are they advisable? 462 | 463 | 464 | ### [[↑]](#toc) Questions about Databases: 465 | 466 | #### DB Migrations 467 | How would you migrate an application from a database to another, for example from MySQL to PostgreSQL? If you had to manage that project, which issues would you expect to face? 468 | 469 | #### NULL is special 470 | Why do databases treat null as a so special case? For example, why does ```SELECT * FROM table WHERE field = null``` not match records with null ``field`` in SQL? 471 | 472 | #### ACID 473 | ACID is an acronym that refers to Atomicity, Consistency, Isolation and Durability, 4 properties guaranteed by a database transaction in most database engines. What do you know about this topic? Would you like to elaborate? 474 | 475 | #### Schema Migrations 476 | How would you manage database schema migrations? That is, how would you automate changes to database schema, as the application evolves, version after version? 477 | 478 | #### Lazy Loading 479 | How is lazy loading achieved? When is it useful? What are its pitfalls? 480 | 481 | #### N+1 Problem 482 | The so called "N + 1 problem" is an issue that occurs when code needs to load the children of a parent-child relationship with a ORMs that have lazy-loading enabled, and that therefore issue a query for the parent record, and then one query for each child record. How to fix it? 483 | 484 | #### Slowest Queries 485 | How would you find the most expensive queries in an application? 486 | 487 | #### Normalization 488 | In your opinion, is it always needed to use database normalization? When is it advisable to use denormalized databases? 489 | 490 | #### Blue/Green Deployment 491 | One of the Continuous Integration's techniques is called Blue-Green Deployment: it consists in having two production environments, as identical as possible, and in performing the deployment in one of them while the other one is still operating, and than in safely switching the traffic to the second one after some convenient testing. This technique becomes more complicated when the deployment includes changes to the database structure or content. I'd like to discuss this topic with you. 492 | 493 | 494 | ### [[↑]](#toc) Questions about NoSQL: 495 | 496 | #### Eventual Consistency 497 | What is eventual consistency? 498 | 499 | #### CAP Theorem 500 | Brewer's Theorem, most commonly known as the CAP theorem, states that in the presence of a network partition (the P in CAP), a system's designer has to choose between consistency (the C in CAP) and availability (the A in CAP). Can you think about examples of CP, AP and CA systems? 501 | 502 | #### NoSQL 503 | How would you explain the recent rise in interest in NoSQL? 504 | 505 | #### NoSQL and Scalability 506 | How does NoSQL tackle scalability challenges? 507 | 508 | #### Document and Relational DBs 509 | When would you use a document database like MongoDB instead of a relational database like MySQL or PostgreSQL? 510 | 511 | 512 | ### [[↑]](#toc) Questions about code versioning: 513 | 514 | #### Branching in HG and in Git 515 | Why is branching with Mercurial or git easier than with SVN? 516 | 517 | #### DVCS 518 | What are the pros and cons of distributed version control systems like Git over centralized ones like SVN? 519 | 520 | #### GitFlow and GitHubFlow 521 | Could you describe GitHub Flow and GitFlow workflows? 522 | 523 | #### Rebase 524 | What's a rebase? 525 | 526 | #### Merging in HG and in Git 527 | Why are merges easier with Mercurial and Git than with SVN and CVS? 528 | 529 | 530 | ### [[↑]](#toc) Questions about Concurrency: 531 | 532 | #### Why? 533 | Why do we need concurrency, anyway? Explain. 534 | 535 | #### Testing Concurrency 536 | Why is testing multithreaded/concurrent code so difficult? 537 | 538 | #### Race Conditions 539 | What is a race condition? Code an example, using whatever language you like. 540 | 541 | #### Deadlocks 542 | What is a deadlock? Would you be able to write some code that is affected by deadlocks? 543 | 544 | #### Process Starvation 545 | What is process starvation? If you need, let's review its definition. 546 | 547 | #### Free Algorithm 548 | What is a wait free algorithm? 549 | 550 | 551 | ### [[↑]](#toc) Questions about Distributed Systems: 552 | 553 | #### Testing Distributed Systems 554 | How would you test a distributed system? 555 | 556 | #### Async Communication 557 | When would you apply asynchronous communication between two systems? 558 | 559 | #### Pitfalls of RPC 560 | What are the general pitfalls of remote procedure calls? 561 | 562 | #### Design of Distributed Systems 563 | If you are building a distributed system for scalability and robustness, what are the different things you'd think of if you are working in a closed and secure network environment versus when you are working in a geographically distributed and public system? 564 | 565 | #### Fault Tolerance 566 | How would you manage fault tolerance in a web application? What about in a desktop one? 567 | 568 | #### Failures 569 | How would you deal with failures in a distributed system? 570 | 571 | #### Network Partitions 572 | Let's talk about the several approaches to reconciliation after network partitions. 573 | 574 | #### Fallacies of Distributed Computing 575 | What are the fallacies of distributed computing? 576 | 577 | #### Request/Reply vs Publish/Subscribe 578 | When would you use request/reply and when publish/subscribe? 579 | 580 | #### Implement Transactions 581 | Suppose the system you are working on does not support transactionality. How would you implement it from scratch? 582 | 583 | 584 | ### [[↑]](#toc) Questions about Software Lifecycle and Team Management: 585 | 586 | #### Agility 587 | What is agility? 588 | 589 | #### Legacy Code 590 | How would you deal with legacy code? 591 | 592 | #### Legacy Code ELI5 593 | Say I'm your project manager, and I'm no expert in programming. Would you try explaining to me what legacy code is and why should I care about code quality? 594 | 595 | #### Sell me Kanban 596 | I'm the CEO of your company. Explain to me Kanban and convince me to invest in it. 597 | 598 | #### Agile vs Waterfall 599 | What is the biggest difference between Agile and Waterfall? 600 | 601 | #### Death by Meetings 602 | Being a team manager, how would you deal with the problem of having too many meetings? 603 | 604 | #### Late Projects 605 | How would you manage a very late project? 606 | 607 | #### Agile Manifesto 608 | "*Individuals and interactions over processes and tools*" and "*Customer collaboration over contract negotiation*" comprise half of the values of the Agile Manifesto. Discuss 609 | 610 | #### If I were the CTO 611 | Tell me what decisions would you take if you could be the CTO of your Company. 612 | 613 | #### PMs 614 | Are program managers useful? 615 | 616 | #### Team Organization 617 | Organize a development team using flexible schedules (that is, no imposed working hours) and "take as you need" vacation policy 618 | 619 | #### Turn Over 620 | How would you manage a very high turn over and convince developers not to leave the team, without increasing compensation? What could a company improve to make them stay? 621 | 622 | #### Qualities 623 | What are the top 3 qualities you look for in colleagues, beyond their code? 624 | 625 | #### 3 Things About Code 626 | What are the top 3 things you wish non-technical people knew about code? 627 | 628 | #### 1 month's revolution 629 | Imagine your company gives you 1 month and some budget to improve your and your colleagues' daily life. What would you do? 630 | 631 | 632 | ### [[↑]](#toc) Questions about logic and algorithms: 633 | 634 | #### FIFO with LIFO 635 | Make a FIFO queue using only LIFO stacks. Then build a LIFO stack using only FIFO queues. 636 | 637 | #### Stack Overflow 638 | Write a snippet of code affected by a stack overflow. 639 | 640 | #### Tail Recursive n! 641 | Write a tail-recursive version of the factorial function. 642 | #### REPL 643 | Using your preferred language, write a REPL that echoes your inputs. Evolve it to make it an RPN calculator. 644 | 645 | #### Defragger 646 | How would you design a "defragger" utility? 647 | 648 | #### Mazes 649 | Write a program that builds random mazes. 650 | 651 | #### Memory Leaks 652 | Write a sample program that produces a memory leak. 653 | 654 | #### PRNG 655 | Generate a sequence of unique random numbers. 656 | 657 | #### Garbage Collecting 658 | Write a simple garbage collection system. 659 | 660 | #### Queues 661 | Write a basic message broker, using whatever language you like. 662 | 663 | #### Simple Web Server 664 | Write a very basic web server. Draw a road map for features to be implemented in the future. 665 | 666 | #### Sorting Huge Files 667 | How would you sort a 10GB file? How would your approach change with a 10TB one? 668 | 669 | #### Duplicates 670 | How would you programmatically detect file duplicates? 671 | 672 | ### [[↑]](#toc) Questions about Software Architecture: 673 | 674 | #### No Cache 675 | When is a cache not useful or even dangerous? 676 | 677 | #### Event-Driven Architecture 678 | Why does Event-Driven Architecture improve scalability? 679 | 680 | #### Readability 681 | What makes code readable? 682 | 683 | #### Emergent and Evolutionary 684 | What is the difference between emergent design and evolutionary architecture? 685 | 686 | #### Scale-Out, Scale-Up 687 | Scale out vs scale up: how are they different? When to apply one, when the other? 688 | 689 | #### Failures User Sessions 690 | How to deal with failover and user sessions? 691 | 692 | #### CQRS 693 | What is CQRS (Command Query Responsibility Segregation)? How is it different from the oldest Command-Query Separation Principle? 694 | 695 | #### n-tier 696 | The so called "multitier architecture" is an approach to design a client–server system aimed to keep physically and logically separated presentation, application processing, data management and other functions. The most widespread of the multitier architectures is the three-tier architecture. Would you discuss the pros and cons of such an approach? 697 | 698 | #### Scalability 699 | How would you design a software system for scalability? 700 | 701 | #### C10K 702 | Someone gave the name "The "C10k problem" to the problem of optimising network sockets to handle over 10.000 open connections at once. While handling 10.000 concurrent clients is not the same as handling 10.000 open connection, the context is similar. It's a tough challenge anyway, and no one is expected to know every single detail to solve it. It may be interesting to discuss the strategies you know to deal with that problem. Would you like to try? 703 | 704 | #### P2P 705 | How would you design a decentralized (that is, with no central server) P2P system? 706 | 707 | #### CGI 708 | You may recall that Common Gateway Interface (CGI) is a standard protocol for web servers to execute programs (CGI scripts) that execute as Command-line programs on a server, and that dynamically generate HTML pages when invoked by a HTTP request. Perl and PHP used to be common languages for such scripts. In CGI, a HTTP request generally causes the invocation of a new process on the server, but FastCGI, SCGI and other approaches improved the mechanism, raising the performance, with techniques such as preforking processes. Can you discuss why CGI became obsolete, and was instead replaced with other architectural approaches? 709 | 710 | #### Vendor Lock-in 711 | How would you defend the design of your systems against vendor Lock-in? 712 | 713 | #### Pub/Sub 714 | What are the disadvantages of the publish-subscribe pattern at scale? 715 | 716 | #### CPUs 717 | What's new in CPUs since the 80s, and how does it affect programming? 718 | 719 | #### Performance 720 | In which part of the lifecycle of a software performance should be taken in consideration, and how? 721 | 722 | #### DDOS 723 | How could a denial of service arise not maliciously but due to a design or architectural problem? 724 | 725 | #### Performance and Scalability 726 | What’s the relationship between performance and scalability? 727 | 728 | #### Tight Coupling 729 | When is it OK (if ever) to use tight coupling? 730 | 731 | #### Cloud Readiness 732 | What characteristic should a system have to be cloud ready? 733 | 734 | #### Emergent Architecture 735 | Does unity of design imply an aristocracy of architects? Putting it simple: can good design emerge from a collective effort of all developers? 736 | 737 | #### Design, Architecture, Functionality, Aesthetic 738 | What's the difference between design, architecture, functionality and aesthetic? Discuss. 739 | 740 | 741 | 742 | ### [[↑]](#toc) Questions about Service Oriented Architecture and Microservices: 743 | 744 | #### Long-lived Transactions 745 | Why, in a SOA, long-lived transactions are discouraged and sagas are suggested instead? 746 | 747 | #### SOA and Micro Services 748 | What are the differences between SOA and microservice? 749 | 750 | #### Versioning and Breaking Changes 751 | Let's talk about web services versioning, version compatibility and breaking changes. 752 | 753 | #### Sagas and compensations 754 | What's the difference between a transaction and a compensation operation in a saga, in SOA? 755 | 756 | #### Too Micro 757 | When is a microservice too micro? 758 | 759 | #### Micro Services Architecture 760 | What are the pros and cons of microservice architecture? 761 | 762 | 763 | ### [[↑]](#toc) Questions about Security: 764 | #### Security by Default 765 | How do you write secure code? In your opinion, is it one of the developer's duties, or does it require a specialized role in the company? And why? 766 | 767 | #### Don't Invent Cryptography 768 | Why is it said that cryptography is not something you should try to invent or design yourself? 769 | 770 | #### 2-FA 771 | What is two factor authentication? How would you implement it in an existing web application? 772 | 773 | #### Confidential Data in Logs 774 | If not carefully handled, there is always a risk of logs containing sensitive information, such as passwords. How would you deal with this? 775 | 776 | #### SQL Injection 777 | Write down a snippet of code affected by SQL injection and fix it. 778 | 779 | #### Detect SQL Injection 780 | How would it be possible to detect SQL injection via static code analysis? I don't expect you to write an algorithm capable of doing this, as it is probably a huge topic, but let's discuss a general approach. 781 | 782 | #### XSS 783 | What do you know about Cross-Site Scripting? If you don't remember it, let's review online its definition and let's discuss about it. 784 | 785 | #### Cross-Site Forgery Attack 786 | What do you know about Cross-Site Forgery Attack? If you don't remember it, let's review online its definition and let's discuss about it. 787 | 788 | #### HTTPS 789 | How does HTTPS work? 790 | 791 | #### MITM Attack 792 | What's a man-in-the-middle Attack, and why does HTTPS help protect against it? 793 | 794 | #### Stealing Sessions 795 | How can you prevent the user's session from being stolen? Chances are you remember what session or cookie hijacking is, otherwise let's read its Wikipedia page together. 796 | 797 | 798 | ### [[↑]](#toc) General Questions: 799 | 800 | #### Why FP? 801 | Why does functional programming matter? When should a functional programming language be used? 802 | 803 | #### Browsers 804 | How do companies like Microsoft, Google, Opera and Mozilla profit from their browsers? 805 | 806 | #### TCP Sockets 807 | Why does opening a TCP socket have a large overhead? 808 | 809 | #### Encapsulation 810 | What is encapsulation important for? 811 | 812 | #### Real-time systems 813 | What is a real-time system and how is it different from an ordinary system? 814 | 815 | #### Real-time and memory allocation 816 | What's the relationship between real-time languages and heap memory allocation? 817 | 818 | #### Immutability 819 | Immutability is the practice of setting values once, at the moment of their creation, and never changing them. How can immutability help write safer code? 820 | 821 | #### Mutable vs Immutable 822 | What are the pros and cons of mutable and immutable values. 823 | 824 | #### Object-Relational Impedance Mismatch 825 | What's the Object-Relational impedance mismatch? 826 | 827 | #### Sizing a Cache 828 | Which principles would you apply to define the size of a cache? 829 | 830 | #### TCP and HTTP 831 | What's the difference between TCP and HTTP? 832 | 833 | #### Client-Side vs Server-Side 834 | What are the tradeoffs of client-side rendering vs. server-side rendering? 835 | 836 | #### Reliable and non-reliable channels 837 | How could you develop a reliable communication protocol based on a non-reliable one? 838 | 839 | 840 | 841 | 842 | ### [[↑]](#toc) Open Questions: 843 | 844 | #### Resistance to Change 845 | Why do people resist change? 846 | 847 | #### Threading ELI5 848 | Explain threads to your grandparents 849 | 850 | #### Innovation and Predictability 851 | As a software engineer you want both to innovate and to be predictable. How those two goals can coexist in the same strategy? 852 | 853 | #### Good Code 854 | What makes good code good? 855 | 856 | #### Streaming 857 | Explain streaming and how you would implement it. 858 | 859 | #### 1 Week Improvement 860 | Say your company gives you one week you can use to improve your and your colleagues' lifes: how would you use that week? 861 | 862 | #### Learnt this week 863 | What did you learn this week? 864 | 865 | #### Aesthetic 866 | There is an aesthetic element to all design. The question is, is this aesthetic element your friend or your enemy? 867 | 868 | #### Last 5 books 869 | List the last 5 books you read. 870 | 871 | #### Introducing CI/CD 872 | How would you introduce Continuous Delivery in a successful, huge company for which the change from Waterfall to Continuous Delivery would be not trivial, because of the size and complexity of the business? 873 | 874 | #### Reinvent the Wheel 875 | When does it make sense to reinvent the wheel? 876 | 877 | #### Not Invented Here 878 | Let's have a conversation about "*reinventing the wheel*", the "*not invented here syndrome*" and the "*eating your own food*" practice 879 | 880 | #### Next Thing to Automate 881 | What's the next thing you would automate in your current workflow? 882 | #### Coding is Hard 883 | Why is writing software difficult? What makes maintaining software hard? 884 | 885 | #### Green Fields and Brown Fields 886 | Would you prefer working on green field or brown field projects? Why? 887 | 888 | #### Type "Google.com" 889 | [What happens when you type google.com into your browser and press enter?](https://github.com/alex/what-happens-when) 890 | 891 | #### While idle 892 | What does an operating system do when it has got no custom code to run, and therefore it looks idle? I would like to start a discussions about interrupts, daemons, background services, polling, event handling and so on. 893 | 894 | #### Unicode 895 | Explain Unicode and database transactions to a 5 year old child. 896 | 897 | #### Defending Monoliths 898 | Defend the monolithic architecture. 899 | 900 | #### Professional Developers 901 | What does it mean to be a "professional developer"? 902 | 903 | #### It's an art 904 | Is developing software Art, Engineering, Crafts or Science? Your opinion. 905 | 906 | #### People who like this also like... 907 | "People who like this also like... ". How would you implement this feature in an e-commerce shop? 908 | 909 | #### Corporations vs Startups 910 | Why are corporations slower than startups in innovating? 911 | 912 | #### I'm proud of 913 | What have you achieved recently that you are proud of? 914 | 915 | 916 | 917 | ### [[↑]](#toc) Questions about snippets of code: 918 | 919 | #### Beware the Closure 920 | What's the output of this Javascript function? 921 | ```javascript 922 | function hookupevents() { 923 | for (var i = 0; i < 3; i++) { 924 | document.getElementById("button" + i) 925 | .addEventListener("click", function() { 926 | alert(i); 927 | }); 928 | } 929 | } 930 | ``` 931 | 932 | #### Type Erasure 933 | About Type Erasure, what's the output of this Java snippet, and why? 934 | ```java 935 | ArrayList li = new ArrayList(); 936 | ArrayList lf = new ArrayList(); 937 | if (li.getClass() == lf.getClass()) // evaluates to true 938 | System.out.println("Equal"); 939 | ``` 940 | 941 | #### Memory Leak 942 | Can you spot the memory leak? 943 | ```java 944 | public class Stack { 945 | private Object[] elements; 946 | private int size = 0; 947 | private static final int DEFAULT_INITIAL_CAPACITY = 16; 948 | 949 | public Stack() { 950 | elements = new Object[DEFAULT_INITIAL_CAPACITY]; 951 | } 952 | 953 | public void push(Object e) { 954 | ensureCapacity(); 955 | elements[size++] = e; 956 | } 957 | 958 | public Object pop() { 959 | if (size == 0) 960 | throw new EmptyStackException(); 961 | return elements[--size]; 962 | } 963 | 964 | /** 965 | * Ensure space for at least one more element, roughly 966 | * doubling the capacity each time the array needs to grow. 967 | */ 968 | private void ensureCapacity() { 969 | if (elements.length == size) 970 | elements = Arrays.copyOf(elements, 2 * size + 1); 971 | } 972 | } 973 | ``` 974 | 975 | #### Kill the witch 976 | `if`s and in general conditional statements lead to procedural and imperative programming. Can you get rid of this `switch` and make this snippet more object oriented? 977 | 978 | ```java 979 | public class Formatter { 980 | 981 | private Service service; 982 | 983 | public Formatter(Service service) { 984 | this.service = service; 985 | } 986 | 987 | public String doTheJob(String theInput) { 988 | String response = service.askForPermission(); 989 | switch (response) { 990 | case "FAIL": 991 | return "error"; 992 | case "OK": 993 | return String.format("%s%s", theInput, theInput); 994 | default: 995 | return null; 996 | } 997 | } 998 | } 999 | ``` 1000 | 1001 | #### Kill the if 1002 | Can you get rid of these `if`s and make this snippet of code more object oriented? 1003 | 1004 | ```java 1005 | public class TheService { 1006 | private final FileHandler fileHandler; 1007 | private final FooRepository fooRepository; 1008 | 1009 | public TheService(FileHandler fileHandler, FooRepository fooRepository) { 1010 | this.fileHandler = fileHandler; 1011 | this.fooRepository = fooRepository; 1012 | } 1013 | 1014 | public String Execute(final String file) { 1015 | 1016 | final String rewrittenUrl = fileHandler.getXmlFileFromFileName(file); 1017 | final String executionId = fileHandler.getExecutionIdFromFileName(file); 1018 | 1019 | if (executionId.equals("") || rewrittenUrl.equals("")) { 1020 | return ""; 1021 | } 1022 | 1023 | Foo knownFoo = fooRepository.getFooByXmlFileName(rewrittenUrl); 1024 | 1025 | if (knownFoo == null) { 1026 | return ""; 1027 | } 1028 | 1029 | return knownFoo.DoThat(file); 1030 | } 1031 | } 1032 | ``` 1033 | 1034 | #### Kill the if-chain 1035 | How would you refactor this code? 1036 | 1037 | ```js 1038 | function() 1039 | { 1040 | HRESULT error = S_OK; 1041 | 1042 | if(SUCCEEDED(Operation1())) 1043 | { 1044 | if(SUCCEEDED(Operation2())) 1045 | { 1046 | if(SUCCEEDED(Operation3())) 1047 | { 1048 | if(SUCCEEDED(Operation4())) 1049 | { 1050 | } 1051 | else 1052 | { 1053 | error = OPERATION4FAILED; 1054 | } 1055 | } 1056 | else 1057 | { 1058 | error = OPERATION3FAILED; 1059 | } 1060 | } 1061 | else 1062 | { 1063 | error = OPERATION2FAILED; 1064 | } 1065 | } 1066 | else 1067 | { 1068 | error = OPERATION1FAILED; 1069 | } 1070 | 1071 | return error; 1072 | } 1073 | ``` 1074 | [Resources](snippets/kill-the-if-chain.md) 1075 | 1076 | ### [[↑]](#toc) Bill Gates Style Questions: 1077 | This section collects some weird questions along the lines of the [Manhole Cover Question](https://en.wikipedia.org/wiki/Microsoft_interview#Manhole_cover_question). 1078 | 1079 | #### Mirrors 1080 | What would happen if you put a mirror in a scanner? 1081 | 1082 | #### Clones 1083 | Imagine there's a perfect clone of yourself. Imagine that that clone is your boss. Would you like to work for him/her? 1084 | 1085 | #### Revert 1086 | Interview me. 1087 | 1088 | #### Quora 1089 | Why are Quora's answers better than Yahoo Answers' ones? 1090 | 1091 | #### Cobol 1092 | Let's play a game: defend Cobol against modern languages, and try to find as many reasonable arguments as you can. 1093 | 1094 | #### 10 years 1095 | Where will you be in 10 years? 1096 | 1097 | #### Fire me 1098 | You are my boss and I'm fired. Inform me. 1099 | 1100 | #### From scratch 1101 | I want to refactor a legacy system. You want to rewrite it from scratch. Argument. Then, switch our roles. 1102 | 1103 | #### Telling lies 1104 | Your boss asks you to lie to the company. What's your reaction? 1105 | 1106 | #### Your past self 1107 | If you could travel back in time, which advice would you give to your younger self? 1108 | -------------------------------------------------------------------------------- /design-patterns/active-record.md: -------------------------------------------------------------------------------- 1 | # Active Record 2 | 3 | Related topics suggested by [Krzysztof Grzybek](https://github.com/krzysztof-grzybek) 4 | 5 | - How hard is to test code that uses Active Record? How is domain model tied or independent from data layer? 6 | - What's the relation between objects implementing Active Record and the Single Responsibility Principle? 7 | - How easy is to hit the database multiple times (e.g. in foreach loop) because of the leaking abstraction? 8 | -------------------------------------------------------------------------------- /design-patterns/dont-repeat-yourself.md: -------------------------------------------------------------------------------- 1 | # Don't Repeat Yourself 2 | 3 | ## [Krzysztof Grzybek](https://github.com/krzysztof-grzybek) 4 | 5 | Code violating the DRY principle: 6 | ```javascript 7 | class Employee { 8 | calculateSalaryNet() { 9 | return this.hoursWorked * this.hourlyWage; 10 | } 11 | 12 | calculateSalaryGross() { 13 | return this.hoursWorked * this.hourlyWage + TAX; 14 | } 15 | } 16 | ``` 17 | 18 | Fixed code: 19 | ```javascript 20 | class Employee { 21 | calculateSalaryNet() { 22 | return this.hoursWorked * this.hourlyWage; 23 | } 24 | 25 | calculateSalaryGross() { 26 | return this.calculateSalaryNet() + TAX; 27 | } 28 | } 29 | ``` 30 | -------------------------------------------------------------------------------- /design-patterns/inversion-of-control.md: -------------------------------------------------------------------------------- 1 | # Inversion of Control 2 | 3 | ## Links 4 | 5 | * [InversionOfControl - Fowler](https://martinfowler.com/bliki/InversionOfControl.html) 6 | * [Inversion of Control Containers and the Dependency Injection pattern - Fowler](https://martinfowler.com/articles/injection.html) 7 | * [DIP in the Wild - Brett L. Schuchert](https://martinfowler.com/articles/dipInTheWild.html) 8 | 9 | ## Related topics 10 | 11 | * Topics that might be confused with each other 12 | - Inversion of Control 13 | - Dependency Inversion Principle (from SOLID) 14 | - Dependency Injection 15 | 16 | They are all related, but in fact separate. 17 | 18 | ### Relation with Hollywood Principle 19 | For some the Hollywood Principle (or Law) is just a synonym of Inversion of Control; some others see subtle differences. See [Confusion between Inversion of Control and Hollywood Principle](https://stackoverflow.com/questions/43786221/confusion-between-inversion-of-control-and-hollywood-principle). 20 | 21 | In this context, another related topic is the difference between libraries and frameworks, as it is stated that frameworks follow the Hollywood Principle (see [What is the difference between a framework and a library?](https://stackoverflow.com/questions/148747/what-is-the-difference-between-a-framework-and-a-library)). 22 | -------------------------------------------------------------------------------- /design-patterns/law-of-demeter.md: -------------------------------------------------------------------------------- 1 | # Law of Demeter 2 | 3 | * [Law of Demeter - Wikipedia](https://en.wikipedia.org/wiki/Law_of_Demeter) 4 | * [Law of Demeter - WikiWikiWeb](https://wiki.c2.com/?LawOfDemeter) 5 | * [Introducing Demeter and its Laws](http://www.bradapp.net/docs/demeter-intro.html) 6 | 7 | ## Mnemonic for the Law of Demeter 8 | The post [Visualization Mnemonics for Software Principles](http://www.daedtech.com/visualization-mnemonics-for-software-principles) by [Erik Dietrich](https://github.com/erikdietrich) provides a very effective trick to understand (and never forget anymore) what the Law of Demeter is. An Italian translation is available [here](https://github.com/arialdomartini/mnemonics/blob/law-of-demeter/README-italian.md). 9 | -------------------------------------------------------------------------------- /snippets/kill-the-if-chain.md: -------------------------------------------------------------------------------- 1 | # Kill the if-chain 2 | 3 | The nested structure could be unrolled, as suggested by [Vahid Najafi](https://github.com/vahidvdn) 4 | 5 | ```js 6 | function() 7 | { 8 | HRESULT error = S_OK; 9 | 10 | if( !SUCCEEDED(Operation1() ) return OPERATION1FAILED; 11 | if( !SUCCEEDED(Operation2() ) return OPERATION2FAILED; 12 | if( !SUCCEEDED(Operation3() ) return OPERATION3FAILED; 13 | if( !SUCCEEDED(Operation3() ) return OPERATION3FAILED; 14 | if( !SUCCEEDED(Operation4() ) return OPERATION4FAILED; 15 | 16 | } 17 | ``` 18 | 19 | Actually, I feel there is way more space for refactoring, but it all depends on the economic of the projects. 20 | 21 | It is worth to discuss the smells and design flaws of that code, to set up the refactoring goals. 22 | 23 | ## Smells 24 | I see these problems: 25 | 26 | * The code violates some of the [SOLID principles][2]. It surely violates the [Open Closed Principle][3], as it is not possible to extend it without changing its code. E.g., adding a new operation would require adding a new `if`/`else` branch; 27 | * It also violate the [Single Responsibility Principle][4]. It just does too much. It performs error checks, it's responsible to execute all the 4 operations, it contains their implementations, it's responsible to check their results and to chain their execution in the right order; 28 | * It violates the [Dependency Inversion Principle][5], because there are dependencies between high-level and low-level components; 29 | * It has a horrible [Cyclomatic complexity][6] 30 | * It exhibits high coupling and low cohesion, which is exactly the opposite of [what is recommended][7]; 31 | * It contains a lot of code duplication: the function `Succeeded()` is repeated in each branch; the structure of `if`/`else`s is replicated over and over; the assignment of `error` is duplicated. 32 | * It could have a pure functional nature, but it relies instead on state mutation, which makes reasoning about it not easy. 33 | * There's an empty `if` statement body, which might be confusing. 34 | 35 | ## Refactoring 36 | Let's see what could be done.
37 | Here I'm using a C# implementation, but similar steps can be performed with whatever language.
38 | I renamed some of the elements, as I believe honoring a naming convention is part of the refactoring. 39 | 40 | ```csharp 41 | internal class TestClass 42 | { 43 | HResult SomeFunction() 44 | { 45 | var error = HResult.Ok; 46 | 47 | if(Succeeded(Operation1())) 48 | v { 49 | if(Succeeded(Operation2())) 50 | { 51 | if(Succeeded(Operation3())) 52 | { 53 | if(Succeeded(Operation4())) 54 | { 55 | } 56 | else 57 | { 58 | error = HResult.Operation4Failed; 59 | } 60 | } 61 | else 62 | { 63 | error = HResult.Operation3Failed; 64 | } 65 | } 66 | else 67 | { 68 | error = HResult.Operation2Failed; 69 | } 70 | } 71 | else 72 | { 73 | error = HResult.Operation1Failed; 74 | } 75 | 76 | return error; 77 | } 78 | 79 | private string Operation1() 80 | { 81 | // some operations 82 | return "operation1 result"; 83 | } 84 | private string Operation2() 85 | { 86 | // some operations 87 | return "operation2 result"; 88 | } 89 | private string Operation3() 90 | { 91 | // some operations 92 | return "operation3 result"; 93 | } 94 | private string Operation4() 95 | { 96 | // some operations 97 | return "operation4 result"; 98 | } 99 | 100 | private bool Succeeded(string operationResult) => 101 | operationResult == "some condition"; 102 | } 103 | 104 | internal enum HResult 105 | { 106 | Ok, 107 | Operation1Failed, 108 | Operation2Failed, 109 | Operation3Failed, 110 | Operation4Failed, 111 | } 112 | } 113 | ``` 114 | 115 | For the sake of simplicity, I supposed each operation returns a string, and that the success or failure is based on an equality check on the string, but of course it could be whatever. In the next steps, it would be nice if the code is independent from the result validation logic. 116 | 117 | ### Step 1 118 | It would be nice to start the refactoring with the support of some test harness. 119 | 120 | ```csharp 121 | public class TestCase 122 | { 123 | [Theory] 124 | [InlineData("operation1 result", HResult.Operation1Failed)] 125 | [InlineData("operation2 result", HResult.Operation2Failed)] 126 | [InlineData("operation3 result", HResult.Operation3Failed)] 127 | [InlineData("operation4 result", HResult.Operation4Failed)] 128 | [InlineData("never", HResult.Ok)] 129 | void acceptance_test(string failWhen, HResult expectedResult) 130 | { 131 | var sut = new SomeClass {FailWhen = failWhen}; 132 | 133 | var result = sut.SomeFunction(); 134 | 135 | result.Should().Be(expectedResult); 136 | } 137 | } 138 | ``` 139 | 140 | Our case is a trivial one, but being the quiz supposed to be a job interview question, I would not ignore it. 141 | 142 | 143 | ### Step 2 144 | The first refactoring could be getting rid of the mutable state: each if branch could just return the value, instead of mutating the variable `error`. Also, the name `error` is misleading, as it includes the success case. Let's just get rid of it: 145 | 146 | ```csharp 147 | HResult SomeFunction() 148 | { 149 | if(Succeeded(Operation1())) 150 | { 151 | if(Succeeded(Operation2())) 152 | { 153 | if(Succeeded(Operation3())) 154 | { 155 | if(Succeeded(Operation4())) 156 | return HResult.Ok; 157 | else 158 | return HResult.Operation4Failed; 159 | } 160 | else 161 | return HResult.Operation3Failed; 162 | } 163 | else 164 | return HResult.Operation2Failed; 165 | } 166 | else 167 | return HResult.Operation1Failed; 168 | } 169 | ``` 170 | 171 | We got rid of the empty `if` body, making in the meanwhile the code slightly easier to reason about. 172 | 173 | ### Step 3 174 | If now we invert each `if` statement (the step suggested by Sergio) 175 | 176 | ```csharp 177 | internal HResult SomeFunction() 178 | { 179 | if (!Succeeded(Operation1())) 180 | return HResult.Operation1Failed; 181 | 182 | if (!Succeeded(Operation2())) 183 | return HResult.Operation2Failed; 184 | 185 | if (!Succeeded(Operation3())) 186 | return HResult.Operation3Failed; 187 | 188 | if (!Succeeded(Operation4())) 189 | return HResult.Operation4Failed; 190 | 191 | return HResult.Ok; 192 | } 193 | ``` 194 | 195 | we make it apparent that the code performs a chain of executions: if an operation succeeds, the next operation is invoked; otherwise, the chain is interrupted, with an error. The GOF [Chain of Responsibility Pattern][8] comes to mind. 196 | 197 | ### Step 4 198 | We could move each operation to a separate class, and let our function receive a chain of operations to execute in a single shot. Each class would deal with its specific operation logic (honoring the Single Responsibility Principle). 199 | 200 | ```csharp 201 | internal HResult SomeFunction() 202 | { 203 | var operations = new List 204 | { 205 | new Operation1(), 206 | new Operation2(), 207 | new Operation3(), 208 | new Operation4() 209 | }; 210 | 211 | foreach (var operation in operations) 212 | { 213 | if (!_check.Succeeded(operation.DoJob())) 214 | return operation.ErrorCode; 215 | } 216 | 217 | return HResult.Ok; 218 | } 219 | ``` 220 | 221 | We got rid of the `if`s altogether (but one). 222 | 223 | Notice how: 224 | 225 | * The interface `IOperation` has been introduced, which is a preliminary move to decouple the function from the operations, complying the with the Dependency Inversion Principle; 226 | * The list of operations can easily be injected into the class, using the [Dependency Injection][9]. 227 | * The result validation logic has been moved to a separate class `Check`, injected into the main class (Dependency Inversion and Single Responsibility are satisfied). 228 | 229 | ```csharp 230 | internal class SimpleStringCheck : IResultCheck 231 | { 232 | private readonly string _failWhen; 233 | 234 | public Check(string failWhen) 235 | { 236 | _failWhen = failWhen; 237 | } 238 | 239 | internal bool Succeeded(string operationResult) => 240 | operationResult != _failWhen; 241 | } 242 | 243 | ``` 244 | 245 | We gained the ability to switch the check logic without modifying the main class (Open-Closed Principle). 246 | 247 | Each operation has been moved to a separate class, like: 248 | 249 | ```csharp 250 | internal class Operation1 : IOperation { 251 | public string DoJob() 252 | { 253 | return "operation1 result"; 254 | } 255 | 256 | public HResult ErrorCode => HResult.Operation1Failed; 257 | } 258 | ``` 259 | 260 | Each operation knows its own error code. The function itself became independent from it. 261 | 262 | ### Step 5 263 | There is something more to refactor on the code 264 | 265 | ```csharp 266 | foreach (var operation in operations) 267 | { 268 | if (!_check.Succeeded(operation.DoJob())) 269 | return operation.ErrorCode; 270 | } 271 | 272 | return HResult.Ok; 273 | } 274 | ``` 275 | 276 | * First, it's not clear why the case `return HResult.Ok;` is handled as a special case: the chain could contain a terminating operation never failing and returning that value. This would allow us to get rid of that last `if`. 277 | 278 | * Second, our function still has 2 responsibility: to visit the chain, and to check the result. 279 | 280 | An idea could be to encapsulate the operations into a real chain, so our function could reduce to something like: 281 | 282 | ``` 283 | return operations.ChainTogether(_check).Execute(); 284 | ``` 285 | 286 | We have 2 options: 287 | 288 | * Each operation knows the next operation, so starting from operation1 we could execute the whole chain with a single call; 289 | * Operations are kept unaware of being part of a chain; a separate, encapsulating structure adds to operations the ability to be executed in sequence. 290 | 291 | I'm going on with the latter, but that's absolutely debatable. I'm introducing a class modelling a ring in a chain, moving the code away from our class: 292 | 293 | ```csharp 294 | internal class OperationRing : IRing 295 | { 296 | private readonly Check _check; 297 | private readonly IOperation _operation; 298 | internal IRing Next { private get; set; } 299 | 300 | public OperationRing(Check check, IOperation operation) 301 | { 302 | _check = check; 303 | _operation = operation; 304 | } 305 | 306 | public HResult Execute() 307 | { 308 | var operationResult = _operation.DoJob(); 309 | 310 | if (_check.Succeeded(operationResult)) 311 | return Next.Execute(); 312 | 313 | return _operation.ErrorCode; 314 | } 315 | } 316 | ``` 317 | 318 | This class is responsible to execute an operation and to handle the execution to the next ring if it succeeded, or to interrupt the chain returning the right error code. 319 | 320 | The chain will be terminated by a never-failing element: 321 | 322 | ```csharp 323 | internal class AlwaysSucceeds : IRing 324 | { 325 | public HResult Execute() => HResult.Ok; 326 | } 327 | ``` 328 | 329 | Our original class reduces to: 330 | 331 | ```csharp 332 | internal class SomeClass 333 | { 334 | private readonly Check _check; 335 | private readonly List _operations; 336 | 337 | public SomeClass(Check check, List operations) 338 | { 339 | _check = check; 340 | _operations = operations; 341 | } 342 | 343 | internal HResult SomeFunction() 344 | { 345 | return _operations.ChainTogether(_check).Execute(); 346 | } 347 | } 348 | ``` 349 | 350 | In this case, `ChainTogether()` is a function implemented as an extension of `List`, as I don't believe that the chaining logic is responsibility of our class. 351 | 352 | 353 | ## That's not the *right* answer 354 | 355 | It's absolutely debatable that the responsibilities have been separated to the most appropriate classes. For example: 356 | 357 | * is chaining operations a task of our function? Or should it directly receive the chained structure? 358 | * why the use of an enumerable? As Robert Martin wrote in "Refactoring: Improving the Design of Existing Code": enums are code smells and should be refactored to polymorphic classes; 359 | * how much is too much? Is the resulting design too complex? Does the complexity of the whole application need this level of modularisation? 360 | 361 | Therefore, I'm sure there are several other ways to refactor the original function. 362 | 363 | 364 | [1]: https://stackoverflow.com/users/125816 365 | [2]: https://en.wikipedia.org/wiki/SOLID 366 | [3]: https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle 367 | [4]: https://en.wikipedia.org/wiki/Single_responsibility_principle 368 | [5]: https://en.wikipedia.org/wiki/Dependency_inversion_principle 369 | [6]: https://en.wikipedia.org/wiki/Cyclomatic_complexity 370 | [7]: https://en.wikipedia.org/wiki/Cohesion_(computer_science) 371 | [8]: https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern 372 | [9]: https://en.wikipedia.org/wiki/Dependency_injection 373 | [10]: https://refactoring.guru/smells/primitive-obsession 374 | --------------------------------------------------------------------------------