owned this note
<center> <!--<img src="/uploads/upload_c6cdc3e6ee8f9444d042724ca97c5d77.jpg" style="height: 180px;">--> <img src="https://docs.monadical.com/uploads/upload_f5b6f5b36a43d9326b7e2050b44a8099.jpg" style="height: 180px;"> # Monadical Job Application Process *Originally published 2017-02-13 on [docs.monadical.com](https://docs.sweeting.me/s/blog).* :::success <i>Tips and resources for developers thinking about applying to Monadical.</i><br/> <a href="https://apply.monadical.io/" class="btn btn-success" style="color:white">🐙 &nbsp; &nbsp; Apply Now ❯ &nbsp; &nbsp; 🐙 </a> ::: </center> Here's our study guide for the Monadical application process, including documentation for tools, design guidelines for take-home projects, and a list of sample projects to use as inspiration. Whether you're brushing up on your skills to [apply to for a position](https://apply.monadical.io/) or just interested in the technology we use, here are the resources to get started. --- [TOC] --- ## Overview > Total: 1-2 Weeks ### <a href="https://nick764452.typeform.com/to/foY2K2">1. Submit application form + quick coding quiz <code style="float:right">**30min**</code></a> - Application Form: https://apply.monadical.io/ The purpose of this test is to screen applicants for basic programming ability (at a level slightly harder than FizzBuzz). The quiz is untimed, but usually takes less than 30min. ### 2. Conversational Interview <code style="float:right">**~45 mins**</code> This is a non-technical interview where we discuss work experience, background, career goals, and the Monadical work environment. ### 3. Take-Home Project <code style="float:right">**~2-6hrs**</code> A take-home project concept should be chosen from the list below, or a new concept proposed to the interviewers. Optionally, this step can be skipped if the applicant can provide an original OSS project they authored to pair on. The take-home project is untimed, most applicants spend 2~6 hours on it over the course of a few days. ### 4. Pairing Interviews <code style="float:right">**1hr + 1hr**</code> Each of the final pairing interviews is with one lead. These interviews are to gague the experience of collaborating together on a technical project. One interview focuses on product-management, feature specc'ing, and feature implementation, and the other focuses on refactoring, code review, and testing. - **10min:** Discuss the take-home project codebase, walk through the code layout and design together. - **10min:** Step into the shoes of a product manager and spec out some potential features to add to the project. Frame it as if it's a client project and explain thought process for gathering requirements, prioritizing tickets, delegating, and making time estimates. - **40-60min:** Pair on adding a feature to the codebase together. This interview is to gague the experience of working together on a technical task, not to measure raw coding speed. We're more impressed by people who talk clearly through their thought process and code deliberately, than those who try to add as many features as possible in a short time. Treat the task of adding a feature as if it were an un-timed take-home task, and focus on explaining your decisions, more than sheer lines-of-code output during the interview. - **Extra time:** We've all had interview jitters, so if the feature was not completed during pairing or if you feel the interview wasn't a good representation of your abilities, you're welcome to push further commits up to 24 hours afterwards with a short description of the changes made, and we'll include it with equal weight when evaluating your code. --- ## Tips and Tricks ### In Code Submissions #### Resist overengineering Don't overengineer your answers, just solve the stated problems as straightforwardly as possible. Fix any obvious bugs, and make sure your submissions are succinct, runnable, and correct. #### Show off the quality of your code more than the quantity The purpose is not to produce a lot of code, but to build a small, stable codebase that will be easy for you to extend during the later pairing interviews. Build the codebase in a manner comfortable to you, that you feel confident you'll be able to extend without needing to bend your brain too much. We're more impressed by someone that writes a small, simple project that works, than someone who writes a big show-offy project with lots of features that ends up being sloppy. Optimize for showing off the skills that you think are your strongest. <!-- #### Use Log-Structured State For bonus points, try to store your application state in log-structured formats. This is a design pattern we use frequently at Monadical, so we’d like to make sure you’re comfortable working with immutable, append only data structures. The key idea is that any database can be abstracted as a log of changes to some initial state, such as game moves or canvas clicks. You should store the full log and a function that transforms that log into whatever state the frontend needs. For example, for a banking app you would store a list of the transactions in and out of a users wallet, and use a function to add up the credits & debits to display their total balance. To become more familiar with append-only log-structured data, read this article: https://engineering.linkedin.com/distributed-systems/log-what-every-software-engineer-should-know-about-real-time-datas-unifying --> ### In Interviews Here are some things we look for in interviews: - Deliberate, articulated thought process (think out loud and take your time) - Spend time confirming assumptions before diving into coding - Good clarifying questions that aim to understand the user's intent and overarching goals, not just the implementation details - Collaborative, blameless debugging. It's a shared search for a common solution, not a battle - Curiosity, and a willingness to say "I don't know" and look something up when needed - Test-driven or test-friendly iterative development process Googling and using Stack Overflow is allowed in our interviews, we try to simulate a realistic work-day pairing session as closely as possible. There are no whiteboarding problems or riddles in our interview process. We're aiming to get the most signal we can about what it's like to work with a person in a normal work environment. Of course, it's natural to be nervous during interviews, we try to take that into account and make the tasks as low-stress as possible (your keyboard, your environment, your code, all work is untimed, etc.). For more details on things we value, see our [company principles handbook](https://docs.monadical.com/s/principles-handbook). --- ## Take-Home Projects ### Project Setup Requirements #### The Frontend The frontend must be written in ES7 Javascript, you may use React, or no framework at all, but don’t use Angular, Vue, or another large JS framework (Lodash/jQuery/etc are fine). We tend to use the prettier.io JS style with no semicolons in our codebase, but we’re not strict about any specific code style in the interviews and take-homeprojects, just be consistent with whatever you choose. Javascript build environments can be tricky to set up, to avoid the hassle of dealing with a bundler, we recommend using standard ES6 with `import` syntax (it's supported by all modern browsers now), or sticking to a boilerplate system like `create-react-app`. We don’t require supporting older browsers for our tasks. #### The Backend If your task requires a backend, it can be written in JavaScript, Rust, or Python >=3.7. You may use any python backend framework or ORM as needed, e.g. Django, Flask, Bottle, Pyramids/Pylons, etc. The frontend and backend may interact via REST API, or websocket. You can choose how to implement it, but real-time streaming can be tricky, so you may choose to send drawing strokes or board moves when a user clicks a button instead of sending events continuously. If you’re familiar with websockets, then we recommend using them instead. --- ### Difficulty: Easy (only for internship applicants) #### Scuba Diving journal Write an app to keep track of scuba dives! You should be able to look at a table of dives with several columns, for example: * maximum depth * time below surface * starting and ending oxygen levels * location * date and time * outside temperature * water temperature * a description of what you saw Make sure to store time, location, and anything else in a standardized format. Don't forget that timezones exist, and for bonus points make it possible to sort the rows of the table by the values in any sortable column. Make sure to include a form for adding new dives to your database, and store them in a relational database server-side. If you're applying for a front-end position and are not comfortable building a simple server, you may store the dive data locally instead. In pairing, we can add a button to filter dives by time range. <!-- #### Simple Database App Write a small React redux application that displays a simple list of key:values in the frontend as a table with two columns (keys and values). It should store data in the redux store, and allow the user to add a new key : value, or delete an existing one. When you come in you can work on adding one or more of these features: - ability to filter the table using a search box - persist the table in localStorage - ability to download the table as JSON or CSV You should try to make the table look reasonably nice with CSS, you may use a CSS framework like bootstrap or material design, or hand-code the CSS, although don't over-engineer it. #### Multiplayer Game Build a multiplayer game frontend & backend with django-channels and redux-time. An example would be a drawing game where one player's canvas drawing is synced to another person's scree, and they have to guess which work the user is drawing out of a selection, within a certain amount of time. It should use websockets to transmit the connection state in real time between players, but it can be anything realtime, it doesn't have to be a drawing game. Games with moving characters are harder because collision physics over a connection with latency is difficult to syncronize. --> --- ### Difficulty: Intermediate (junior full-stack applicants) #### Scuba Diving journal pt 2 Build the scuba diving journal above, but also include a graph of oxygen use per minute -- calculate using (ending oxygen minus starting oxygen) divided by (end time minus start time) for all of the dives. The data for the graph should be sent from the backend and not calculated in the frontend (unless you are applying for a frontend position). <!-- #### Tic Tac Toe game Write a program that lets two humans play a game of Tic Tac Toe in a terminal. The program should let the players take turns to input their moves. The program should report the outcome of the game. When you come in, we will pair on adding support for a computer player to your game. We can start with random moves and then work on making the AI smarter after that. #### Lisp parser Write code that takes some Lisp code and returns an abstract syntax tree. The AST should represent the structure of the code and the meaning of each token. For example, if your code is given "(first (list 1 (+ 2 3) 9))", it could return a nested array like ["first", ["list", 1, ["+", 2, 3], 9]]. When you come in, we will pair on writing an interpreter to run the AST. We can start by implementing a single built-in function (for example, +) and add more if we have time. #### Space Invaders Write a game of Space Invaders that has computer-controller enemies that move left and right automatically and a human-controlled player that you can move left and right with the arrow keys. When you come in, we can add the ability to shoot bullets at the enemies and track your score. --> --- ### Difficulty: Advanced (front-end only applicants) #### Mars Mission Manager Create a dashboard for monitoring your Martian outpost. We'll send you some photos and martian rover data for you to use in this task. There should be at least four components in your dashboard. Ideas might include graphs of historical data, a printout of the current situation, a video feed (you can use a webcam or any video feed from the internet and pretend it's coming from mars), or a photo array. Think creatively, about the kind of UX you want to have for your martian rover! We can pair on adding the ability to reorganize, or move the components around in the dashboard. ### Difficulty: Advanced (senior full-stack applicants) #### Side-Stacker Game This is essentially connect-four, but the pieces stack on either side of the board instead of bottom-up. Two players see a board, which is a grid of 7 rows and 7 columns. They take turn adding pieces to a row, on one of the sides. The pieces stack on top of each other, and the game ends when there are no spaces left available, or when a player has four consecutive pieces on a diagonal, column, or row. For example, the board might look like this: 0 [ _ _ _ _ _ _ _ ] 1 [ o x _ _ _ _ o ] 2 [ x _ _ _ _ _ x ] 3 [ x _ _ _ _ _ o ] 4 [ o _ _ _ _ _ _ ] 5 [ _ _ _ _ _ _ _ ] 6 [ _ _ _ _ _ _ _ ] in this case, it is x’s turn. If x plays (2, R), the board will look like this: 0 [ _ _ _ _ _ _ _ ] 1 [ o x _ _ _ _ o ] 2 [ x _ _ _ _ x x ] 3 [ x _ _ _ _ _ o ] 4 [ o _ _ _ _ _ _ ] 5 [ _ _ _ _ _ _ _ ] 6 [ _ _ _ _ _ _ _ ] The take-home task is to implement the 2-player version of this game, where each player sees the board in their frontend and can place moves that the other player sees, and the game should display “player 1 won” “player 2 lost” when the game is complete. Please store the game in the backend using a relational database; how you define your models is up to you. You should not have to refresh the page to see your opponent's moves. <!-- #### Video conference app Requires researching a complex API and implementing a redux-based store to manage a stateful API in a functional deterministic manner. Build a video conferencing app with WebRTC that has clean management of connection state and an easy UX to video chat with other people by sharing a websocket link. #### Shared Whiteboard This is a two-person shared chalkboard/whiteboard, where there is a canvas that both peoplecan draw on, each person’s stokes are visible in a color specific to that person. The take-home task is to start by allowing a single person to draw on a canvas, and download their drawing from the server as TXT, CSV, or JSON file. The drawing should be saved continously to the server, as an append-only log of strokes, so that if the user refreshes it is displayed without any data loss. Then, during the interview we will pair on adding the ability for a second user to share the canvas in real-time and color each persons strokes with a color unique to that user. #### Pictionary Game https://en.wikipedia.org/wiki/Pictionary This is a game where one player draws a picture, and the other player tries to guess which word the person is trying to draw out of a selection. The objective is to guess the word as soon as possible, before the person has drawn the entire thing (a popular app that did this is Words with Friends), so you should display a timer to both users once they start drawing. The take home task is to allow a single person’s drawing to be displayed on another person’s screen in real-time. the pairing task is to add the words for the first person to draw, and build a system for the second person to select the right word and display whether they won or lost. --> --- ### Difficulty: Advanced (Dev-Ops) **Overview:** Your goal is to set up a simple hello-world Django/Python app called "banana" on a server. The server should be running Nginx >=1.15, Postgresql >=11, Python >=3.7. It should store all its code and data in one place, with simple server-side bash commands available for deploying, updating, and doing backups. The stack outlined in this task is very similar to what we run internally, so it's a good representation of the real dev-ops tasks you'd be assigned if hired. **Timeline:** We expect this task to take between 2-6 hours, depending on how comfortable you are with the technologies and patterns involved. Time is not used as a grading factor though, so feel free to take as long as you need (up to six weeks if necessary, e.g. if you're busy with your current day-job). **Costs:** As it involves purchasing a domain and a VPS server, we're happy to transfer you the ~$10 USD needed to get started, or we can send it afterwards once you know the total ($15 maximum). We recommend the $3.50/mo Vultr.com droplet, but you may use any hosting provider you're comfortable with. **Process:** You can code the setup manually, or you may use orchestration/deploy tools like Ansible/Docker/Puppet/Chef/etc, it's up to you. Results are partly graded on simplicity / minimalism, so optimize for having as little uncessary config as possible. Make sure all config and scripts used for setup are placed in version control. We use `supervisord` and `docker-compose` internally, so we ask that applicants use one or both of those for process management, but the server setup process can still be automated with other tools like Ansible/Chef/etc, just make sure to provide any Ansible playbooks or equivalents when submitting your final setup. **Goals:** The goal of this task is to evaluate your level of comfort with setting up and securing common backend stacks in Unix environments. If you don't manage to complete all the tasks exactly as described, that's ok, you'll have an opportunity to explain which tasks were skipped or modified during the call. The final setup doesn't have to match the description exactly, the end goal is just to make sure it works and that the choices made along the way were reasonable, not to test your ability to strictly adhere to a spec. **Security Model:** For this task you can assume the server is running in a trusted hosting environment with only root admins having shell access, there is no need to use disk encryption or guard exessively against internal attacks, just make sure to change SSH to port 44 and ensure sure only 44, 80, and 443 are publicly accessible (e.g. no need to install fail2ban). **Before starting:** read this post about how Monadical manages servers, and try to match the style outlined when you build your own: https://docs.monadical.com/s/an-intro-to-the-opt-directory **When finished:** enable access to the server using SSH with the following key: `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMdwUnQvH0opeOLJi3HTBIHKMgOIAwBNfWdZUa7gWZWD squash@sweeting.me`, and send us the public IP. During the interview call afterwards, we will SSH in and inspect the setup and you'll walk us through your setup over the call, explaining any decisions made and answering any questions we might have. We'll ask you to run the scripts in `bin/` on the call as well to confirm they work. Don't hesitate to ask if you have questions about this task, the interview process, or Monadical in general! Just send me an email here: <img src="https://i.imgur.com/4w0TJur.png" height="30px"> #### Requirements ##### Server Setup - must work in a fresh Ubuntu >=20.04 environment (e.g. don't use the "one-click django" droplet template provided by DigitalOcean) - must be running nginx, postgres, and django, managed by a service manager other than `systemd`/`initd`, you can use `supervisord` or `docker-compose` - app code, data, binaries, config, and backups must be stored entirely in subfolders under `/opt/banana` (hint, use a virtualenv for the code, and supervisord/docker to save output to logfiles in `./data/logs`) - app must be an empty django app created using `django-admin startproject banana` (you can fork https://github.com/Monadical-SAS/example-devops-app, don't waste time writing code in the app, this project is testing your devops skills, not your python backend skills) - django must point to the local PostgreSQL >=v11 database for data - nginx/apache/caddy must be running in front of Django, serving staticfiles directly from the filesystem (proxying only page requests to Django) - must have 4 easily executable bash scripts in `/opt/banana/bin` (these should just contain the ~1-10 lines of bash needed to accomplish the task, they shouldn't be complicated): + `bin/stop`: stop django, nginx, and postgresql + `bin/start`: start django, nginx, and postgresql + `bin/deploy`: pull the latest version of the app code from github, run migrations, and restart the necessary services + `bin/backup`: dump the postgresql database to a `.sql` file in `/opt/banana/data/backups` - for simplicty and time-savings, we recommend just running the app with django `runserver` in `DEBUG=False` mode and `--noreload --insecure` passed, with no WSGI server between Django and Nginx ##### Network Setup - Must have a public IPv4 address - Must have SSH open only on port 44 (not 22), accepting pubkey authentication (no passwords) - Must have a valid, public SSL certificate (using letsencrypt/CloudFlare/etc) - Must redirect all port 80 HTTP requests to HTTPS - Django runserver and Postgres must not be directly accessable via WAN (only nginx) - Must have no other ports besides 80, 443, and 44 publicly accessable ##### Bonus Points The dev-ops take-home project described above is already a decent amount of work, but that's because we're currently looking for relatively experienced devops engineers that are already comfortable setting up this type of server environment. If this task sounds easy and you feel it's not enough to show off your awesome chops, we've provided some additional tasks below as inspiration, but feel free to add anything else you feel would improve the setup. Keep in mind, simplicity is key, this is not a production application with all its associated complexity, so try to keep it as small and lean as you can. Part of our grading criteria is how well applicants can weigh the value of additional features against the cost of adding config surface-area and management overhead. - store all logs, cache files, tmp files, and other data in `/opt/banana/data` (this includes nginx logs, django logs, postgres logs, and the postgresql database files) - make all code and data files only be readable/writable by their respective users and root (i.e. run nginx and django as `www-data`, postgres as the `postgres` user, etc.) - accept http2 requests and return http2 responses (using the nginx http2 module) - in `bin/backup`: compress the backups with gzip and rsync them to an external server passed as `$1` - backup and deploy automatically whenever the code on the github `master` branch changes - log ssh access events and any shell commands run to a file in `/opt/banana/data/logs` - improve app security by servering better HTTP security headers (`X-Frame-Options`, `X-Content-Type-Options`, `X-XSS-Protection`, `Referrer-Policy`, `Strict-Transport-Security`, and any others you want to add) - use the `bjoern` WSGI server or `django-channels`'s `runworker` to serve the app to nginx - close port 80 and 443 by using a cloudflare argo tunnel to serve the app (which avoids exposing the app server's IP address to the public) - do the whole thing on FreeBSD/OpenBSD/Nix/Debian instead of Ubuntu - extreme bonus points: set up multiple web worker servers with one database server, with orchestration like Puppet/Chef/Ansible/Kubernetes/etc) --- ## Monadical Stack Documentation ### Backend - Python - Beginner: https://learnxinyminutes.com/docs/python/ - Beginner: https://wiki.python.org/moin/BeginnersGuide - Beginner: https://docs.python.org/3/tutorial/index.html - Docs: https://docs.python.org/3/ - Itermediate & Advanced: http://intermediate-and-advanced-software-carpentry.readthedocs.io/en/latest/day1.html - PEP8: http://dcjtech.info/wp-content/uploads/2015/12/Python-Syntax-Checker-Codes-Cheatsheet.pdf - Django - https://docs.djangoproject.com/en/3/ - https://docs.djangoproject.com/en/3/intro/ - https://docs.djangoproject.com/en/3/intro/overview/ ### Frontend - JavaScript - https://learnxinyminutes.com/docs/javascript/ - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode - https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript - https://www.toptal.com/javascript/javascript-es6-cheat-sheet - https://hackernoon.com/javascript-es6-exploring-the-new-built-in-methods-b62583b0a8e6 - `react` - https://facebook.github.io/react/docs/ - https://facebook.github.io/react/docs/hello-world.html - https://facebook.github.io/react/tutorial/tutorial.html - `redux` - http://redux.js.org/ - https://www.scribd.com/document/311967613/Redux-Cheat-Sheet - http://redux.js.org/docs/basics/UsageWithReact.html - https://github.com/uanders/react-redux-cheatsheet - `redux-time` - https://github.com/Monadical-SAS/redux-time - https://monadical-sas.github.io/redux-time/#documentation - `react-bootstrap` - https://react-bootstrap.github.io/components.html - http://fontawesome.io/icons/ --- <center><i> Check out our other technical [blog posts](https://monadical.com/blog) to learn more <br/>about our philosophy and approach to software engineering! </i></center> :::success <center> Interested in joining Monadical? &nbsp;Check out our [team page](https://monadical.com/team.html#join) or apply now.<br/> <img src="/uploads/upload_b1a12c430204a4d8e76fdd8c982e5dd1.png" style="height: 80px;"><br/> <img src="/uploads/upload_06e24dd75bbd5c39b20ea61c654201c1.png" style="height:30px"/> <br/><a href="https://careers.monadical.com/" class="btn btn-success" style="color:white">🐙 &nbsp; &nbsp; Apply Now ❯ &nbsp; &nbsp; 🐙 </a> </center>