The Well Rounded Engineer

The Well Rounded Engineer

What does it take to do a software engineering job well? Are you interested in deepening your skills but haven’t had the opportunity to lay a solid foundation? It turns out the high-level answer to this is simple, and it is a skill and knowledge-based system balanced on these two load-bearing pillars:

1. Individual technical ability
2. Collaborating and working with others

Take either one away, and it comes crashing down. In this talk, we aim to deconstruct the former: individual technical skill. What is the foundation on which lays the pyramid of skills?

We will take a look at a roster of abilities, and we will talk about one or two concrete steps you can take to make progress in each.

This roster is aimed primarily at software engineers who want to write modern web-based systems.


Swanand Pagnis

February 13, 2019


  1. The Well Rounded Engineer: Critical Path One step at a

    time. !
  2. Swanand Pagnis " Director of Engineering at Deserve

  3. None
  4. This talk is about crossing or getting near the horizontal

    blue line.
  5. Target Audience: Web based application developers, with a slight lean

    towards back-end developers.
  6. A core skill or category of core skills What can

    you do to improve them?
  7. Some interview skills What can you do to improve them?

  8. Before we begin…

  9. Some process tips:

  10. Find peers; learn together Be accountable Hold them accountable

  11. Get rid of the trial- and-error method Take a very

    analytical approach
  12. Learn how to read research papers, specially older papers. Bleeding

    edge is often overrated
  13. Write summaries of things you study Spaced repetition helps you

    get over the I'll- never-use-this-syndrome
  14. 1. Paradigm Polyglot

  15. Be proficient in two paradigms.

  16. Preferably OOP and FP.

  17. Proficient = Being able to write non- trivial programs.

  18. e.g. A Message Broker, A Web Crawler, An API Wrapper

  19. Boundaries are being blurred by languages like Go and Scala.

  20. - Go, Java, Javascript - Ruby, Python - Haskell, OCaml

  21. Pick one from each. Choose based on comfort & current

  22. Bonus: - Prolog, Factor, Idris - Lisp, Scheme, Clojure

  23. My personal choice: Ruby, OCaml, Prolog

  24. For Ruby: Avdi Grimm's Confident Ruby

  25. For OCaml: Real World OCaml by Yaron Minsky et al

  26. For Haskell: Haskell Book by Chris A. and Julie M.

  27. For Prolog: Exercism Track and 99 Prolog Problems

  28. Strongly recommended: Prof. Dan Grossman's "Programming Languages" on Coursera. Life

    changing course.
  29. This course will help you understand programming languages on a

    fundamental level.
  30. 2. Database Polyglot

  31. Be proficient in using two types of databases.

  32. The two types are: RDBMS and NoSQL*. Duh. *NoSQL is

    too broad, but again, pick something closer to your preferred stack.
  33. Conversant = - Model your data - Be performance aware

    - Write raw SQL
  34. Proficient = - Idiomatic design - Be operations aware -

    Grok SQL
  35. In general, proficiency is about understanding trade-offs.

  36. In depth understanding of SQL is a competitive advantage.

  37. - MySQL, PostgreSQL - Dynamo, Bigtable - Redis, Spanner, Neo4j

  38. For PostgreSQL: Dmitri Fontaine's Mastering PostgreSQL in Application Development

  39. For MySQL: Baron Schwartz's High Performance MySQL

  40. For DynamoDB:, AWS's Dynamo Paper

  41. Books and guides are just a start, specially when it

    comes to DBs.
  42. 3. Protocol Polyglot

  43. Be proficient in using two types of network protocols. )

  44. Preferably TCP/IP and HTTP.

  45. Proficient = - How it works - How to debug

    issues - Design considerations
  46. Proficient = - Familiarity w/ SSL, TLS - App layer

    integration - Sockets & ports
  47. Start here: Ilya Grigorik's High Performance Browser Networking

  48. For TCP and Sockets: Jesse Storimer's Working With TCP Sockets

  49. For HTTP: - Read RFC 7231 - Optionally: RFC 2616

  50. 4. Proficiency with build tooling, packaging and distribution of software

  51. How does the code you write reach your users?

  52. Proficiency = Being able to use these tools and tweak,

    change what's needed
  53. For a Go programmer: Intimately understand go build

  54. For a Rubyist: Understand how Gems are packaged, distributed, and

    loaded at runtime.
  55. For a Rubyist:

  56. For everyone: Write a simple build tool.

  57. What does it do? - Takes an opinionated directory structure

    - Compiles / runs your multi-file program
  58. What does it do next? - Tackle simple dependencies -

    Build a jar / zip like package
  59. 5. Ability to analyse, reason about and debug programs.

  60. Reading & reviewing code Debug running programs Observability & instrumentation

  61. Reading & reviewing code

  62. Develop a habit of reading, reviewing, and explaining every single

    line of code you write or review.
  63. This includes whitespaces, empty lines, config files, dotfiles, comments

  64. The 5-whys are your friend.

  65. Develop a habit of reading library and open source code.

    They're often idiomatic.
  66. Debug running programs

  67. Use GDB or your favourite step-by-step debugger on a process

    running in QA / Staging
  68. Setup IntelliJ or your favourite editor to trivially run debug

    mode, and step through code
  69. Write a *very simple* sampling profiler for your language.

  70. Julia Evans' talk about her building rbspy is full of

    good information
  71. Optionally: Read the ptrace manpages. 3 times.

  72. Observability and instrumentation

  73. Inculcate observability in your process of writing software.

  74. 's Observability Guide.

  75. Cindy Sridharan's Observability Book

  76. How can I reliably answer a question about a system,

    without prying open the system.
  77. 6. Deployments, Infrastructure, and DevOps

  78. Proficiency != Writing an Ansible clone

  79. Proficiency = Understanding when you need Ansible clone

  80. Write a simple Capistrano like deployment system

  81. Keep it opinionated, and bare minimum.

  82. 7. Familiarity with software architecture principles, and basic scaling techniques.

  83. Understand how to design commonly used systems

  84. e.g. How to use workers, queues, and async processing

  85. e.g. How to design a data pipeline

  86. e.g. How to design simple load balancers

  87. e.g. MapReduce™ and similar data processing patterns

  88. Martin Kleppmann's Designing Data Intensive Applications

  89. Michael Keeling's Design It!

  90. Solve a few "scaling" problems from Gayle McDowell's Cracking the

    Coding Interview.
  91. 8. Ability to write toy compilers, interpreters, and parsers

  92. None
  93. This is the most fun section.

  94. This is also a very useful interview skill.

  95. Start with parsers, then interpreters, and finally compilers.

  96. Do not start at book

  97. Work through Graham Hutton's "Higher Order Functions for Parsing"

  98. Then work through Peter Norvig's Lispy:

  99. Once you're confident, attempt to write a JSON or YAML

  100. Recursive descent parsers open you up to a whole new

    coding style
  101. Racket/Scheme/ Haskell/OCaml are ideal for writing compilers.

  102. For compilers, work through "An incremental approach to compiler construction"

  103. 9. Ability to write toy games

  104. Again a very useful interview skill

  105. Games can have arbitrary changing requirements.

  106. Games typically adhere to a specific set of rules

  107. With games, come game playing bots.

  108. Write a simple game with minimal or ascii graphics: Snake,

    Minesweeper, Jumper Frog, etc
  109. Avoid unity or other frameworks, try from first principles.

  110. Then write a bot that plays that game

  111. If you like doing that, read about general game play:

    Bots that can play *any* game.
  112. 10. Ability to understand algorithmic analysis and solve algorithmic problems

  113. Yet another useful interview skill

  114. But an equally useful programming skill

  115. Understand the fundamental approach of solving problems recursively.

  116. Understand the "master method" to analyse recursive solutions.

  117. Cracking The Coding Interview

  118. InterviewCake

  119. Tim Roughgarden's Course on Coursera - This is a challenging

  120. Putting it all together

  121. Make a plan One thing at a time Focus hard

    on it Prioritize fundamental, foundational skills
  122. Do not go too far away from current skillset Get

    in the habit of writing things down: notes, reviews, retrospectives.
  123. Process tips again, they're that important

  124. Find peers; learn together Be accountable Hold them accountable

  125. Get rid of the trial- and-error method Take a very

    analytical approach
  126. Learn how to read research papers, specially older papers. Bleeding

    edge is often overrated
  127. Write summaries of things you study Spaced repetition will get

    you get over the I'll- never-use-this syndrome
  128. Thank you! Tell me about your process.

  129. Swanand Pagnis " Director of Engineering at Deserve