tag:jzerwick.svbtle.com,2014:/feedJulius Zerwick2020-05-10T19:13:40-07:00Julius Zerwickhttps://jzerwick.svbtle.comSvbtle.comtag:jzerwick.svbtle.com,2014:Post/failover-conf-first-conference-talk2020-05-10T19:13:40-07:002020-05-10T19:13:40-07:00Failover Conf - First Conference Talk<p>On April 21, 2020, I gave my first conference talk as a software engineer! It was at <a href="https://failover-conf.heysummit.com/#" rel="nofollow">Failover Conf</a>, a virtual conference on building reliable software systems. Failover Conf was created and produced by Gremlin, who wanted to provide a virtual conference for people to present their talks at given the wave of conference cancelations due to COVID-19.</p>
<p>My talk was titled <em>Improving a Distributed System Post-Incident</em> and detailed my experience as a first time responder to a long running incident that occurred at DigitalOcean and shared some lessons that I learned from the incident. The video for my talk can be found here:</p>
<p><a href="https://www.youtube.com/watch?v=MssnKhNa7L4&list=PLLIx5ktghjqItStdp_NUh3CQ_y4M49Gb1&index=13&t=0s" rel="nofollow">Improving a Distributed System Post-Incident</a></p>
tag:jzerwick.svbtle.com,2014:Post/improving-your-iteration-speed2020-04-11T09:19:57-07:002020-04-11T09:19:57-07:00Improving Your Iteration Speed<p>I’ve been reading <a href="https://www.amazon.com/Effective-Engineer-Engineering-Disproportionate-Meaningful/dp/0996128107" rel="nofollow"><em>The Effective Engineer</em></a> by Edmond Lau and finished a chapter which I found very interesting. The chapter is titled <em>Invest in Iteration Speed</em> and the crux of the content is that effective engineers take the time to reflect on their iteration speed and how to improve it while working on problems or projects.</p>
<p>By iteration speed, we can mean any process which exhibits a cyclical nature in our work and speed at which we complete each cycle. Some processes can contain many steps and can take up more time than we like for each iteration which slows down our progress. Other processes are very streamlined and complete very quickly which allows us to complete each cycle, improve, and repeat at a more rapid pace.</p>
<p>As an example, let’s say that you’re debugging an issue in your code where you receive a request, do some processing with the request’s data, and return a response. But the response your code returns is not what you expect and you need to figure out what’s causing this issue. To debug this issue, you may have the code running locally and you manually send it requests.</p>
<p>You may be tempted to use requests which mirror what you would see in production, but if the request contains a lot of data it can be difficult to parse through everything in the return as you debug. Instead, you can simply choose to send a request containing the smallest amount of data possible so that it’s easier to see what’s being returned. Reducing the amount of data to parse and understand can dramatically improve how quickly you iterate on solving a problem.</p>
<p>Another example could be some new features that you’re writing for a project and you’ve already written some tests to verify the behavior of your code. You may be tempted to code for several hours and have everything written out before running your tests or even any linting programs on your code to check your syntax. This can create issues if you have a bunch of failing tests or lint errors and you now have to overhaul a lot of code.</p>
<p>Instead, you could have a process in which you write a small piece of your planned changes and then run your linting program to check your syntax. If it all looks good, write the next small set of changes and repeat. By the time you’re ready to run your tests, you’ll likely have caught a good number of issues with your changes and fixed them!</p>
<p>In improving my iteration speed, I’ve found one tool to be especially helpful: <a href="https://github.com/watchexec/watchexec" rel="nofollow"><strong>watchexec</strong></a>. This tool can be used to automatically run other programs or commands once any changes have been made to a file which can greatly speed up your workflow! As an example, here’s how I use <strong>watchexec</strong> in my work.</p>
<p>At DigitalOcean, I mostly work in Go which is a compiled language. The codebase for my team has a Makefile which specifies commands we can execute to run other programs. If I want to properly format my newly written code, I can run <code class="prettyprint">make gofmt</code> and if I want to lint my code I run <code class="prettyprint">make analyze</code>. To use these with <strong>watchexec</strong>, I cd into the root directory of our codebase on the git branch I’m working on and run the following:<br>
<code class="prettyprint">watchexec --exts go ‘clear; make gofmt; make analyze’</code></p>
<p>This sets up <strong>watchexec</strong> to watch any files that end with the extension .go and if any of the files are changed it will run <code class="prettyprint">clear; make gofmt; make analyze</code> which will clear the terminal screen, run my formatting program, and lint my code. With this, I’ll typically work on my code in one terminal tab and once I’ve saved my changes I’ll flip over to a second tab running <strong>watchexec</strong> which will already have formatted my code and checked my syntax. Pretty neat and efficient! </p>
<p>I can even further and have another terminal tab open to run a separate <strong>watchexec</strong> program that will rerun my tests after any changes are saved. The command to do this in Go is the following:<br>
<code class="prettyprint">watchexec --exts go ‘clear; go test -v -count=1 -run=TestFunctionName ./relative_path_to_test_file</code></p>
<p>With that setup, I now have my code formatted, linted, and tested automatically with each save made to a file. Now we’re zipping!</p>
<p>There are many other ways to improve your iteration speed and a fantastic way to level up as a software engineer is to figure out how you can improve on it. It’ll vary depending on the work you’re doing and what processes you have to follow for a project or team, but there are always opportunities to improve your effectiveness. A couple of suggestions include:</p>
<pre><code class="prettyprint">* Using Docker to run local instances of your programs for testing and debugging
* Having a checklist of all the steps you should complete before submitting a PR for review
* Finding or building tools which save you time over the long run, even if they take some time to get set up -> even better if you can get other teammates to use the tool
* Setting up small experiments to test your program’s performance after a set of changes to verify a performance improvement or spot a regression
</code></pre>
<p>Next time you’re about to start a new piece of work and feel the urge to dive right into coding a solution or new feature, I encourage you to instead take a moment and consider what processes you’ll be executing and what your iteration speed will be like. Then contemplate how you can improve that iteration speed so that you can more efficiently complete your work. You may notice a whole bunch of things you can do that’ll make you a more high performing engineer.</p>
tag:jzerwick.svbtle.com,2014:Post/starting-with-open-source2020-02-01T14:24:09-08:002020-02-01T14:24:09-08:00Starting with Open Source<p>For many developers, contributing to open source is one of the most impactful parts of being a developer or in tech. The ability to contribute to high-impact projects which help thousands, even millions, of people build software systems is an amazing thing to be a part of. They also tell me that they’ve grown by leaps and bounds in their skills by working on open source projects.</p>
<p>As a developer who is early in my career, I’ve always had an urge to jump on the open source train and start making contributions. But my main hangup has always been the time it requires. For me, working 8+ hours at my day job as a developer at DigitalOcean is pretty tiring and it’s been difficult to balance adding open source to my schedule while also making time to recharge and relax. Additionally, I’ve found myself floundering a bit in finding which project to contribute to given the huge number of projects out there. And so for the past year I’ve mainly been focusing on my work and have put off diving into open source until “the right thing comes along”.</p>
<p>That perspective changed recently when I met a coworker who had just started on-boarding at my work. He had found his way to joining DigitalOcean through his open source contributions, which immediately peaked my interest. It turns out that while he when he joined his last company he had to switch programming languages, and he didn’t want to get rusty in his prior language (C++). So he looked for an open source project to contribute to and found Envoy, a load balancer created by Lyft that was made open source.</p>
<p>For over a year, he put a few hours a week into working on Envoy which was the only open source project that he contributed to. The project had an extremely high bar for pull requests & testing, and it could take several months for a pull request to be accepted and merged. But through this experience, he kept his C++ skills sharp and leveled up as an engineer until one day he got an email from a recruiter at DigitalOcean. Our load balancer team had an open position and they knew the quality of engineering involved in Envoy, so they started reaching out to contributors, and 2 months later he had joined the load balancer team here!</p>
<p>I thought this was an awesome story and ask for his recommendations on getting started with open source. He laid out several points that I thought were really insightful and should be shared with the Dev community:</p>
<ul>
<li><p>Pick just one project. It can seem like you’re limiting yourself, but if you are squeezed on time it’s best to focus the time you have on learning one codebase, it’s testing methods, & how to debug issues. If you’re working on multiple projects, it can be slow to make progress since you’re mentally <br>
juggling several codebases.</p></li>
<li><p>Look for a project that is regularly used and has the backing of one or more major companies. These projects will likely have several engineers from these companies that work mostly, if not solely, on the project because it is vital to the company. This means that it will have consistent work done on it.</p></li>
<li><p>See if the project has a high standard of engineering. Indicators include rigorous testing, plenty of healthy discussions or debates on pull requests & issues, and an established process for contributing to the project and rolling out releases.</p></li>
</ul>
<p>Thinking back on these points, it’s clear that not everyone who wants to contribute to open source will want a project displaying these features. Some developers may want to work on smaller projects or not face so much rigor in getting contributions accepted. Some of us may want to keep “serious work” with our day jobs and work on something more lighthearted, even silly, in our off-hours.</p>
<p>For me, I want to grow my skills as a developer and work on projects that not only demand a level of rigor, but also see a high amount of use. So I started looking around for projects that fit the above points and found several listed below (majority are in Go since that’s the language I use the most):</p>
<ul>
<li><a href="https://github.com/etcd-io/etcd" rel="nofollow">etcd</a></li>
<li><a href="https://github.com/kubernetes/kubernetes" rel="nofollow">Kubernetes</a></li>
<li><a href="https://github.com/envoyproxy/envoy" rel="nofollow">Envoy</a></li>
<li><a href="https://github.com/hashicorp/consul" rel="nofollow">Consul</a></li>
<li><a href="https://github.com/hashicorp/terraform" rel="nofollow">Terraform</a></li>
<li><a href="https://www.openbsd.org/faq/faq1.html" rel="nofollow">OpenBSD</a></li>
</ul>
<p>And with that, I’ve decided that for next year I will pick one project (likely one from the list above) and commit to it for the whole year. I hope that by doing so, I can be able to dive into the codebase and get several contributions accepted in the time I have available. I plan to report back at the end of the year with my progress and thoughts!</p>
<p>What do you all think about the points here that my co-worker made regarding open source? What projects are you currently contributing to and how did you decide on them? I’d love to hear everyone’s thoughts!</p>
tag:jzerwick.svbtle.com,2014:Post/git-cherrypick2019-10-06T11:38:41-07:002019-10-06T11:38:41-07:00git cherry-pick<p>Over the past 10 months working at DigitalOcean, I’ve come to learn more about git and how it can save me from my mistakes. This past week, I used <code class="prettyprint">git cherry-pick</code> for the first time and wanted to share how you can use it as well.</p>
<p>While working on a ticket in a separate branch of my team’s project, I had to pause and jump back onto my <code class="prettyprint">master</code> branch to debug some errors we were seeing in production. I proceeded to commit my changes, hop onto <code class="prettyprint">master</code>, and resolve our issue. My mistake occurred when I dove back into my ticket work and somehow accidentally didn’t checkout to my separate branch. Always run <code class="prettyprint">git branch</code> before picking up where you left off!</p>
<p>I finished up my work and was about to commit my changes when I realized my mistake and that I was still on the <code class="prettyprint">master</code> branch. Before getting frustrated about how I was going to transfer my work to the correct branch, I thought to myself “hey, since git essentially allows us to write and edit our project history, there must be a way for me to move these changes from one branch to another”.</p>
<p>Off to Google I went and found the <code class="prettyprint">git cherry-pick</code> command! If you didn’t know, <code class="prettyprint">cherry-pick</code> allows you to grab a commit from one branch and write it to another branch. All you need to do is grab the the commit ID of the commit I wanted to move. Let’s breakdown the workflow.</p>
<p>I have my two branches <code class="prettyprint">master</code> and <code class="prettyprint">ticket-work</code>, and we want to move a commit from <code class="prettyprint">master</code> to <code class="prettyprint">ticket-work</code>. First, I commit those changes that I accidentally made to <code class="prettyprint">master</code>. Then, I use <code class="prettyprint">git log</code> to see the history of the commits on <code class="prettyprint">master</code>.</p>
<pre><code class="prettyprint">$ git log
commit 0a5e736cvcf6b89894894b921d4858bb34417g21
Author: jzerwick <jrzerwick@gmail.com>
Date: Wed Oct 2 00:11:23 2019 +0200
Implemented changes
</code></pre>
<p>I’ll grab the commit ID of the commit I want to move <code class="prettyprint">0a5e736cvcf6b89894894b921d4858bb34417g21</code>, hop onto my other branch, and execute <code class="prettyprint">cherry-pick</code> like so:</p>
<pre><code class="prettyprint">$ git checkout ticket-work
$ git cherry-pick 0a5e736cvcf6b89894894b921d4858bb34417g21
</code></pre>
<p>Now all that’s left is for me to delete that unwanted commit on <code class="prettyprint">master</code>.<br>
This can be done by using the <code class="prettyprint">reset</code> command with the <code class="prettyprint">--hard</code> flag like so:</p>
<pre><code class="prettyprint">$ git checkout master
$ git reset --hard HEAD^
</code></pre>
<p>The <code class="prettyprint">HEAD^</code> targets the last commit, which you can also target with <code class="prettyprint">HEAD~1</code>. If you want to delete multiple commits, just specify the number of last commits after the <code class="prettyprint">~</code> symbol. Removing the last two commits would use <code class="prettyprint">HEAD~2</code>.</p>
<p>And that’s it! I now have the commit on the branch I wanted and <code class="prettyprint">master</code> is back to its rightful state.</p>
tag:jzerwick.svbtle.com,2014:Post/social-contracts-in-learning2019-09-29T17:35:54-07:002019-09-29T17:35:54-07:00Social Contracts in Learning<p>Recently, I’ve been thinking about how I approach my learning of new topics in software engineering and a big theme has been the use of social contracts. When I say social contract, I don’t mean the philosophical theory or model but rather the idea of an agreement for mutual benefit between an individual or group and the community as a whole.</p>
<p>In the most basic sense, the forms of social contract I’m talking about is when I put myself in situations in which I teach others something I’ve learned like a tech talk, presentation, or article. By making a commitment to put together material and talking points to help others learn something, I in turn force myself to learn the topic at a deeper level and explain it in simple words.</p>
<p>The power of this approach is two fold: for one it requires a more rigorous attempt to understand a topic, and second it puts me on a timeline. I think the first point is obvious in its benefit, but the second one is of particular interest to me. I’ve always made earnest attempts to study new tools, topics, or practice my programming skills, but have found that life has a number of ways to distract me or pull my time away. However, when I have a hard deadline and responsibility to deliver to others I find that I’m able to be more disciplined in my learning and focused with my time.</p>
<p>This is the reason that I so often agree to give tech talks to Launch School, the online software engineering school that I studied at. It’s also why I have this blog that I’m attempting to write articles for on a consistent basis. Putting a contract in place between myself and others to deliver material has forced me to learn at a deeper level and not let life pull my studies by the wayside.</p>
<p>Another form of social contract that I’ve started doing is taking online classes at the <a href="https://bradfieldcs.com/" rel="nofollow">Bradfield School of CS</a>. Based in San Francisco, Bradfield is a school for professional software developers who want to learn CS fundamentals from a mastery based approach. I’ve had my eye on the classes for several years, but since they have all been in-person only and I live in New York City I’ve mainly been hoping for a future sabbatical from work to take them.</p>
<p>However, at the end of 2019 they started offering online classes and I’ve since started taking their Computer Networking class. I’ve also registered to take their Computer Architecture class in 2020 and plan to take more of their classes as they come online. The reason for this is that while there are many free resources available online to learn the topics these classes offer, I still face the same issues mentioned before. </p>
<p>But by putting money down for these classes, having a directed curriculum to learn from on a set schedule, and having fellow students to engage with in a flipped classroom style each week, I’ve essentially created a social contract between myself and the school. This has forced me to place my learning before other distractions in my life and ensured that I put the time aside to understand the material. </p>
<p>I highly recommend that readers of this blog consider what social contracts they can engage in to accelerate their learning. It can be intimidating to put yourself in such a situation, but I think you’ll find yourself growing more rapidly than expected if you try it out and put your best effort into it.</p>
tag:jzerwick.svbtle.com,2014:Post/leveraging-the-command-line-for-increased-productivity2019-09-29T17:10:38-07:002019-09-29T17:10:38-07:00Leveraging the Command Line for Increased Productivity<p>As working developers growing their career, we should always be seeking ways to improve our productivity and effectiveness. Many of us are drawn to the dazzling array of extensions, plugins, and third-party tools that claim to “boost our productivity”, but there is actually one area full of fertile ground for improvement that we all use everyday: the command line.</p>
<p>Nestled within the command line are a host of features and commands that can drastically improve how effectively we work, and in this article I’d like to highlight several that I’ve found to boost my productivity. I’ll also show you how I use them on a day-to-day basis with examples. Whether you’re a beginner just starting their career or a working developer with some experience, this article is for you.</p>
<h2 id="io-redirection_2">I/O Redirection <a class="head_anchor" href="#io-redirection_2" rel="nofollow">#</a>
</h2>
<p>We’ll start with directing the standard input and output of your terminal, which I found essential in getting more out of the command line. For example, let’s say that you’re working on an application and it’s outputting a ton of logs that you want to look over. Rather than having the logs simply output to your terminal requiring you to scroll through them, you can do the following:</p>
<p><code class="prettyprint">$ command_to_run_application &2> log-file.txt</code></p>
<p>What this does is it runs your application and then directs all standard output including errors to a new file called <code class="prettyprint">log-file.txt</code>. Thus all of your logs will be saved into a separate file that you can search through and share with other developers if you need help.</p>
<p>You can use the same method to save the output of running a large test suite into a file. Here is an example from running the test files for a Golang project:</p>
<p><code class="prettyprint">$ go test -v ./ &2> test-output.txt</code></p>
<h2 id="pbcopy-amp-pbpaste_2">pbcopy & pbpaste <a class="head_anchor" href="#pbcopy-amp-pbpaste_2" rel="nofollow">#</a>
</h2>
<p>Two of my favorite little commands are <code class="prettyprint">pbcopy</code> and <code class="prettyprint">pbpaste</code> which are the copy and paste functions on the command line for MacOS. For Linux users, there are similar commands that you can download: <a href="https://www.ostechnix.com/how-to-use-pbcopy-and-pbpaste-commands-on-linux/" rel="nofollow">How To Use Pbcopy And Pbpaste Commands On Linux - OSTechNix</a></p>
<p>I love these commands because they allow me to copy information from the command line without taking my hands away from the keyboard. They also make it easy to copy & paste file contents that may be difficult to accomplish with a mouse, such as copying RSA keys to Github or other sites like so:</p>
<p><code class="prettyprint">$ cat public_rsa.sh | pbcopy</code></p>
<p>You can then simply use your keyboard shortcut for paste to dump the contents where you need to.</p>
<h2 id="grep-amp-rgrep_2">grep & rgrep <a class="head_anchor" href="#grep-amp-rgrep_2" rel="nofollow">#</a>
</h2>
<p>With <code class="prettyprint">grep</code> we obtain a massive superpower: the ability to find all the occurrences of a given expression in all folders and files found in a given path. This is incredibly useful for when you’re editing a file and come across a function that you need to modify or look up for more information. Using <code class="prettyprint">grep</code> we can find every place that the function is used in milliseconds.</p>
<p>For example, let’s say I’m working on an API endpoint that has a <code class="prettyprint">validateRequest</code> function and I want to see how this function is implemented. I can use <code class="prettyprint">grep</code> in the directory to easily find where the function is defined in any files like so:</p>
<p><code class="prettyprint">$ grep validateRequest ./*</code></p>
<p>The output will give all the occurrences of <code class="prettyprint">validateRequest</code> being invoked or defined. If you want to search all subdirectories and their files, execute the following:</p>
<p><code class="prettyprint">$ grep -r validateRequest ./*</code></p>
<p>This is extremely helpful when working with a large codebase and the execution is much faster than using the Github search feature (or what every source control solution you use). You can also have <code class="prettyprint">grep</code> output the line number for each occurrence by adding the <code class="prettyprint">-b</code> flag like so:</p>
<p><code class="prettyprint">$ grep -rb validateRequest ./*</code></p>
<p>As a bonus, I’d recommend that you look into <code class="prettyprint">ripgrep</code> which is a re-implementation of <code class="prettyprint">grep</code> written in Rust that is several orders faster than <code class="prettyprint">grep</code>. Additionally, by default the basic command will show the line number for each occurence in the respective file, highlights the occurence, and will recursively search all subdirectories and their files where as <code class="prettyprint">grep</code> requires the flags mentioned above to do the same. <a href="https://github.com/BurntSushi/ripgrep" rel="nofollow">Check it out here!</a></p>
<h2 id="less-bat_2">less / bat <a class="head_anchor" href="#less-bat_2" rel="nofollow">#</a>
</h2>
<p>The next tool that I want to cover is <code class="prettyprint">less</code> which allows you to interactively view the contents of a file in your terminal. This differs from <code class="prettyprint">cat</code> or <code class="prettyprint">tail</code> in that you can view the whole file, not just a defined set of lines at either the top or bottom of the file. </p>
<p>And with <code class="prettyprint">less</code>, you can can search through the file quickly using the <code class="prettyprint">/</code> or <code class="prettyprint">?</code> commands. To search in a file from your cursor down use <code class="prettyprint">/</code> plus an expression, and to search from your cursor up use <code class="prettyprint">?</code>. The reason you should know both is because searching in <code class="prettyprint">less</code> does not wrap around to the beginning or end of a file, unlike with vim.</p>
<p>I use <code class="prettyprint">less</code> all the time in my work because it makes it so easy to reference a file while I edit another file. If you use iTerm2 then you can edit the file in one pane while using <code class="prettyprint">less</code> in the other. I personally use <code class="prettyprint">tmux</code> to generate my panes and do the same.</p>
<p>But the real magic comes when you use <code class="prettyprint">grep</code> and <code class="prettyprint">less</code> together to boost your workflow! Working on a file and need to find & reference another piece of code in the codebase? Just open up another terminal tab or window (or create another pane with iTerm2 or tmux), <code class="prettyprint">grep</code> for the code you’re looking for, and then use <code class="prettyprint">less</code> to see the inner workings!</p>
<p>I’ve found <code class="prettyprint">less</code> to be a huge boost in my productivity and recently I’ve discovered <code class="prettyprint">bat</code>, which is a re-implemenation of <code class="prettyprint">less</code> that provides syntax highlighting, line numbering, and many other features. <a href="https://github.com/sharkdp/bat" rel="nofollow">Give it a try here!</a></p>
<h2 id="tmux_2">tmux <a class="head_anchor" href="#tmux_2" rel="nofollow">#</a>
</h2>
<p>I’ve already mentioned <code class="prettyprint">tmux</code> in previous sections, and here I’d like to give a brief peek at how I use it. Essentially, <code class="prettyprint">tmux</code> is a terminal multiplexer that acts as a window manager for your terminal. It allows you to create “windows” that you can cycle through, with each window serving as a complete terminal for separate tasks or processes. And in each window you can create panes that can split your screen so that you can perform separate operations in the same terminal window.</p>
<p>The way that <code class="prettyprint">tmux</code> achieves this is through “sessions” which you can attach and detach from. When attached to a session, you can create a new window with a unique layout of panes that can have files open or processes running, and later detach from a session while retaining your pane layout. Many sessions, each potentially having many windows and each window with many panes.</p>
<p>It’s best understood with some images, so here you go:</p>
<p>There are a ton of things that you can do with <code class="prettyprint">tmux</code> and my goal here is just to introduce it as an essential tool in my workflow. If you’re interested in learning more about <code class="prettyprint">tmux</code>, check out the following links:</p>
<p><a href="https://www.hamvocke.com/blog/a-quick-and-easy-guide-to-tmux/" rel="nofollow">https://www.hamvocke.com/blog/a-quick-and-easy-guide-to-tmux/</a><br>
<a href="https://danielmiessler.com/study/tmux/" rel="nofollow">https://danielmiessler.com/study/tmux/</a><br>
<a href="https://sanctum.geek.nz/arabesque/zooming-tmux-panes/" rel="nofollow">https://sanctum.geek.nz/arabesque/zooming-tmux-panes/</a><br>
<a href="https://medium.com/@matthewmain/tmux-getting-started-3842b57435c0" rel="nofollow">https://medium.com/@matthewmain/tmux-getting-started-3842b57435c0</a><br>
<a href="https://medium.com/@lamdbui/faster-command-line-workflow-with-tmux-a6539c8eae2c" rel="nofollow">https://medium.com/@lamdbui/faster-command-line-workflow-with-tmux-a6539c8eae2c</a><br>
<a href="https://thoughtbot.com/upcase/tmux" rel="nofollow">https://thoughtbot.com/upcase/tmux</a></p>
<h2 id="vim_2">vim <a class="head_anchor" href="#vim_2" rel="nofollow">#</a>
</h2>
<p>Last but not least we have vim, a text editor that comes pre-installed with every Linux and MacOS operating system. It has a reputation for being difficult to learn, but I actually found that it’s not that hard so long as you have patience and learn in small chunks.</p>
<p>Vim allows you to edit and navigate all of your files entirely from the keyboard and those who are proficient in vim find themselves rarely using their mouse while coding. While using vim, you can navigate your cursor with the h, j, k, l keys much like old school computer games. It also has a TON of commands that you can chain together to rapidly change your code. For example, you can delete everything within a function between the <code class="prettyprint">{}</code> characters simply by putting your cursor in the function body and typing <code class="prettyprint">di{</code> which stands for “delete inside {}”. You can perform similar functions with words, lines, paragraphs, and text inside “” or () characters, and after spending time learning vim you’ll be amazed at how much more productive you can be.</p>
<p>The other huge plus in using vim is how customizable it is. Not only are there plenty of plugins that you can download to get specific key shortcuts, syntax coloring, and more, but you can also setup your own shortcuts by modifying your vim’s configurations in a <code class="prettyprint">.vimrc</code> file. Vim truly is a tool that you make your own and time invested in learning it is well spent.</p>
<p>To get started learning vim, simply go to your command line if you’re on Linux or MacOS, type <code class="prettyprint">vimtutor</code>, and hit Enter. You’ll be taken to an interactive tutorial of vim that’ll teach you the basics. After that, check out the following resources:</p>
<p><a href="https://thoughtbot.com/upcase/onramp-to-vim" rel="nofollow">https://thoughtbot.com/upcase/onramp-to-vim</a><br>
<a href="https://thoughtbot.com/upcase/the-art-of-vim" rel="nofollow">https://thoughtbot.com/upcase/the-art-of-vim</a><br>
<a href="http://vimcasts.org/blog/" rel="nofollow">http://vimcasts.org/blog/</a><br>
<a href="https://pragprog.com/book/dnvim2/practical-vim-second-edition" rel="nofollow">https://pragprog.com/book/dnvim2/practical-vim-second-edition</a></p>
<h2 id="closing-thoughts_2">Closing Thoughts <a class="head_anchor" href="#closing-thoughts_2" rel="nofollow">#</a>
</h2>
<p>There is another plus I’ve found in using vim, and it’s really a side effect of using it alongside <code class="prettyprint">tmux</code> and all the other tools I’ve mentioned in this article. By having as much of my development workflow located in the terminal as possible, I’ve drastically cut down on the amount of context switching that I experience. I no longer jump between a editor where I type code to a terminal where I execute my code and tests to a browser to look at another file in the codebase on Github. I know simply start a session with tmux, create a splitscreen of two or more panes, and edit my code in vim in one pane while performing all sorts of other processes in the other panes.</p>
<p>In a field of work where mental energy and focus is a premium in order to perform at a high level, this benefit has helped me enormously in boosting my productivity and practicing essential command line skills. I recommend that you give it a try yourself, and start small so that you don’t overload yourself. Pick up a few of the tools I’ve mentioned here at a time and incorporate them into your daily work. Soon enough, you’ll be zipping along on the command line.</p>
<h2 id="bonus_2">Bonus! <a class="head_anchor" href="#bonus_2" rel="nofollow">#</a>
</h2>
<p>I gave a lightning talk on <em>Command Line: Tips & Tricks</em> to students at Launch School, the online software engineering school I studied at prior to joining DigitalOcean. In the talk I go over the tools described above, along with several others and some general command line tips & tricks. You can find <a href="https://docs.google.com/presentation/d/1W-O0EFuGQL9xhhNkZA5PXir1qmka1EZm7dtu1Hj5wsk/edit?usp=sharing" rel="nofollow">the slides for the talk here!</a></p>
tag:jzerwick.svbtle.com,2014:Post/how-i-navigated-the-job-hunt-and-landed-my-dream-job2019-09-08T18:52:13-07:002019-09-08T18:52:13-07:00How I navigated the job hunt and landed my dream job<p>This article is about how I went through my job hunt for a full time position as a software engineer in New York City and ended up with my dream job. I had spent two years building my skills and had aspirations to work at a top tech company with a high bar for engineering excellence.</p>
<p>I knew this goal would not be easy to achieve, especially without a CS degree, barely having any network in New York City, and having to compete against engineers from top schools. It would be a long shot, and I was prepared for the long haul.</p>
<h3 id="9-weeks-later_3">9 weeks later… <a class="head_anchor" href="#9-weeks-later_3" rel="nofollow">#</a>
</h3>
<p><img src="https://media.giphy.com/media/l4JySAWfMaY7w88sU/giphy.gif" alt=""></p>
<p>I’m ecstatic to say that I’ve accepted an offer from DigitalOcean to work as a Software Engineer II from their NYC HQ!</p>
<p>This success came after countless study sessions, mock interviews, hours of practice, and facing numerous challenges & rejections. But I kept my spirits up and came out the other end happier than I imagined possible.</p>
<h3 id="how-did-you-go-from-start-to-finish_3">How did you go from start to finish? <a class="head_anchor" href="#how-did-you-go-from-start-to-finish_3" rel="nofollow">#</a>
</h3>
<p>That question is what this article is all about! I’ll be detailing my preparation process for interviews, how I built my network, and managed myself during this job hunt.</p>
<p>That being said, everyone’s experiences are different and should pull from this article what they feel will benefit them. No two job hunts are the same and there are different factors in each one.</p>
<p>With that said, let’s dive in!</p>
<h1 id="first-things-first-build-a-solid-foundation_1">First things first: build a solid foundation <a class="head_anchor" href="#first-things-first-build-a-solid-foundation_1" rel="nofollow">#</a>
</h1>
<p><img src="https://miro.medium.com/max/13440/1*bkJzT9fx13c_oOfUbHIb6g.jpeg" alt=""></p>
<p>Before anything else, it’s vital that you have a rock solid foundation in the fundamentals of software engineering. Instead of chasing after the hottest technologies, what’s important is to have the technical foundation needed to learn new things quickly and deeply.</p>
<p>In my opinion, the best way to do this is to pick one industry-proven language and stick with it while learning about variables, functions, tools, software design, databases, APIs, and building web applications. This allowed me focus on depth in my knowledge, proficiency in solving coding challenges, and experience in building quality projects.</p>
<p>To build my fundamentals, I chose to study at <a href="https://launchschool.com/" rel="nofollow">Launch School</a> which offers an extensive curriculum and rigorous assessment process that ensured that I had deeply learned the fundamentals before progressing.</p>
<h1 id="build-a-project-that-impresses-employers-amp_1">Build a project that impresses employers & engineers <a class="head_anchor" href="#build-a-project-that-impresses-employers-amp_1" rel="nofollow">#</a>
</h1>
<p><img src="https://miro.medium.com/max/2332/1*PodXWdegqPnOmtgZDT94kQ.gif" alt=""></p>
<p>In the current day, there are multitudes of bootcamps and online tutorials that provide aspiring software developers with projects to help them land a job.</p>
<p>However, there is now a saturation in the market of developers with simple CRUD apps or clones of popular apps like Instagram, Netflix, Reddit, etc. These projects no longer impress employers or other engineers as they once did.</p>
<p>That said, many engineers need some way to evaluate you before giving you a referral and there is no replacement for showing your skills off with a solid project.</p>
<p>That’s why <a href="https://gooi.tech/" rel="nofollow">Gooi</a>, <a href="https://njohnson7.github.io/" rel="nofollow">Nick</a>, and I built <a href="https://spacecraft-repl.com/" rel="nofollow">SpaceCraft</a>, a real-time collaborative REPL that allows developers to write and execute code in the browser for Ruby, JavaScript, and Python.</p>
<p>It was an incredible experience, and also a TON of work. You can read more about how we built SpaceCraft in this <a href="https://hackernoon.com/building-spacecraft-a-real-time-collaborative-repl-deebcf084ed9" rel="nofollow">article</a> or read our <a href="https://spacecraft-repl.com/whitepaper" rel="nofollow">case study</a>.</p>
<p>We spent hundreds of hours researching how to build a REPL, enable real-time collaboration, use Docker to create isolated user sessions, and handle user requests with a proxy server.</p>
<h1 id="market-yourself-effectively_1">Market yourself effectively <a class="head_anchor" href="#market-yourself-effectively_1" rel="nofollow">#</a>
</h1>
<p><img src="https://livestream.com/accounts/686369/events/8535115/videos/186248334/player?autoPlay=true&height=360&mute=false&referrer=https:%2F%2Fmedium.com%2Ffree-code-camp%2Fhow-i-navigated-the-job-hunt-and-landed-my-dream-job-b37bf3d0d630&width=640" alt=""></p>
<p>While SpaceCraft may showcase our skills, I still needed to get people to look at it. Since I had relocated to NYC for my job hunt, my professional network was close to nil and I did my best to put myself in front of as many engineers as possible.</p>
<p>That’s why our team wrote our case study, an article on HackerNoon, and presented at Meetups. These efforts helped us stand out among the sea of other applicants and generated interest from employers & engineers.</p>
<p>Presenting at Meetups were a game changer for me as they got my name out there and procured referrals to several companies, along with giving me the chance to practice and refine my communication skills.</p>
<p>I also built a <a href="https://rouxcaesar.github.io/" rel="nofollow">personal website</a> and beefed up my <a href="https://www.linkedin.com/in/julius-zerwick-842000b2/" rel="nofollow">LinkedIn</a> & <a href="https://angel.co/julius-zerwick?al_content=view+your+profile&al_source=transaction_feed%2Fnetwork_sidebar" rel="nofollow">AngelList</a> profiles in order to make it easier for prospective companies to find me and see my work.</p>
<p>Devoting time to market yourself and skill set through writing articles, presenting at events, and professional networking sites can lead to a big payoff in the interview process.</p>
<p>I had a big increase in the number of engineers and companies reaching out to me after seeing my updated profiles and hearing me present, and having a video of my presentation to include in my outreach emails resulted in a higher response rate and more interviews.</p>
<h1 id="reach-out-to-engineers-amp-companies_1">Reach out to engineers & companies <a class="head_anchor" href="#reach-out-to-engineers-amp-companies_1" rel="nofollow">#</a>
</h1>
<p><img src="https://media.giphy.com/media/mW05nwEyXLP0Y/giphy.gif" alt=""></p>
<p>In the same vein, I made sure to consistently reach out to engineers at companies I was interested in. Using LinkedIn Connect requests, I had over a dozen coffee meetings with engineers from DigitalOcean, Cockroach Labs, Oscar Health, DataDog, Peloton, and more. These meetings helped me get a feel for the job market in NYC, hear an insider perspective on company culture and teams, and gain referrals.</p>
<p>My advice is to approach these meetings casually and with interest in your fellow engineer’s work, career, and company. Don’t go in asking for a referral at the beginning, many times they will offer to refer you if you’re nice and the conversation goes well.</p>
<p><img src="https://miro.medium.com/max/960/1*hhoIR1BlNh0uYDiXSFEQpg.gif" alt=""></p>
<p>Another form of outreach that I did was more directly emailing engineers. Whenever I found a job posting that I really liked, I would reach out to an engineer who works at the company through LinkedIn Inmail, using <a href="https://chrome.google.com/webstore/detail/clearbit-connect-supercha/pmnhcgfcafcnkbengdcanjablaabjplo?hl=en" rel="nofollow">Clearbit Connect</a> when needed to find contact info.</p>
<p>In the email, I would include an introduction on my background, my most impressive project, a link to one of my presentations, and ask if they were open to chatting about the position.</p>
<p>This form of outreach lead to my highest response rate out of any other avenue with nearly 1/3 of all my emails getting a response. Remember, the job hunt is entirely a numbers game and it’s best to try out all forms of outreach to see which nets you the highest returns.</p>
<h1 id="study-practice-repeat_1">Study, practice, repeat <a class="head_anchor" href="#study-practice-repeat_1" rel="nofollow">#</a>
</h1>
<p><img src="https://miro.medium.com/max/10804/1*JU7-Ksjiq4PaSbnS1-A6gw.jpeg" alt=""></p>
<p>That said, none of these efforts would go anywhere if I didn’t have the skills to succeed in the technical interviews. With a solid foundation in the fundamentals, I needed to spend my time solving coding challenges and studying topic relevant to the positions.</p>
<p>The types of questions and challenges you can face in interviews are VAST and often times you won’t know what to expect. Many of the top companies will focus on algorithms and data structures, while startups and mid-size companies may focus on more “practical” problems like refactoring an existing class or adding features to a basic project.</p>
<p>My advice is to study a variety of coding challenges and do your best to predict the questions they will ask you. For algorithms and data structures, my main resources for building a foundation and conceptual understanding were:</p>
<ul>
<li><a href="https://www.amazon.com/Common-Sense-Guide-Data-Structures-Algorithms/dp/1680502441" rel="nofollow">A Common-Sense Guide to Data Structures and Algorithms</a></li>
<li><a href="https://www.amazon.com/Cracking-Coding-Interview-Programming-Questions/dp/0984782850/ref=sr_1_1?crid=3B576YLQLTSY8&keywords=cracking+the+coding+interview&qid=1553352055&s=gateway&sprefix=cracking%2Caps%2C285&sr=8-1" rel="nofollow">Cracking the Coding Interview</a></li>
<li><a href="https://medium.com/basecs" rel="nofollow">BaseCS</a></li>
</ul>
<p>I also solved 2–3 problems a day on <a href="https://leetcode.com/" rel="nofollow">LeetCode</a> for 5–6 days a week.</p>
<p><img src="https://miro.medium.com/max/940/1*t_azHzMuCidoyf_ItbhIhA.gif" alt=""></p>
<p>Many companies will also have a system design interview to assess what level to hire you for. If you’re aiming for mid-to-senior level roles, you’ll need to devote more time to this area.</p>
<p>I found the best resources to be <a href="https://www.educative.io/collection/5668639101419520/5649050225344512?authorName=Design%20Gurus" rel="nofollow">Grokking the System Design Interview</a> and reading various blogs on specific topics. Here are a few blogs I’d recommend:</p>
<ul>
<li><a href="https://www.allthingsdistributed.com/2018/06/purpose-built-databases-in-aws.html" rel="nofollow">All Things Distributed</a></li>
<li><a href="http://highscalability.com/" rel="nofollow">High Scalability</a></li>
<li><a href="http://blog.gainlo.co/index.php/2017/03/24/chapter-5-system-design-interviews-part-complete-guide-google-interview-preparation/" rel="nofollow">Gainlo</a></li>
<li><a href="https://medium.com/baseds" rel="nofollow">BaseDS</a></li>
</ul>
<p>Another very common step is to complete a take home challenge. The variety of these challenges can make it hard to prepare for, but there are some common topics. Several that I saw were:</p>
<ul>
<li>Build a RESTful API that handles several provided cURL requests</li>
<li>Build a CLI app that stores inputs (like albums, artists, and release year) and allows users to retrieve them</li>
<li>Build a game using React/Rails (ex: Tic-Tac-Toe, Blackjack, Minesweeper)</li>
<li>Given a spec and example of the finished product, create a web page that is as close to pixel perfect to the example as possible.</li>
</ul>
<p>The upside is that you have more time to complete them in the comfort of your own home, and there are lots of opportunities to impress by writing a comprehensive test suite, identifying & addressing edge cases, and finding extra touches to add.</p>
<p>Over my job hunt, I typically spent Monday-Thursday applying to companies, doing outreach, and solving LeetCode challenges or studying system design. I reserved Friday-Saturday to practice building a take home project. Here are some to consider:</p>
<ul>
<li><a href="https://x-team.com/blog/how-to-create-a-ruby-api-with-sinatra/" rel="nofollow">https://x-team.com/blog/how-to-create-a-ruby-api-with-sinatra/</a></li>
<li><a href="https://www.discoverdev.io/blog/series/js30/" rel="nofollow">https://www.discoverdev.io/blog/series/js30/</a></li>
<li><a href="https://daveceddia.com/react-practice-projects/" rel="nofollow">https://daveceddia.com/react-practice-projects/</a></li>
<li><a href="https://medium.freecodecamp.org/how-to-build-a-react-js-chat-app-in-10-minutes-c9233794642b" rel="nofollow">https://medium.freecodecamp.org/how-to-build-a-react-js-chat-app-in-10-minutes-c9233794642b</a></li>
<li><a href="https://codeburst.io/writing-a-crud-app-with-node-js-and-mongodb-e0827cbbdafb" rel="nofollow">https://codeburst.io/writing-a-crud-app-with-node-js-and-mongodb-e0827cbbdafb</a></li>
<li><a href="https://codeburst.io/learning-react-js-by-building-a-minesweeper-game-ced9d41560ed" rel="nofollow">https://codeburst.io/learning-react-js-by-building-a-minesweeper-game-ced9d41560ed</a></li>
<li><a href="https://github.com/karan/Projects" rel="nofollow">https://github.com/karan/Projects</a></li>
</ul>
<p>To prepare for live coding challenges, I used <a href="https://www.pramp.com/#/" rel="nofollow">Pramp</a> for mock interviews 3–4 times a week, which improved my performances by leaps and bounds.</p>
<p>I’ve written before on this topic in <a href="https://medium.com/launch-school/why-you-need-an-interview-script-b86e18d0200a" rel="nofollow">Why You Need an Interview Script</a>, but essentially when under pressure our mental abilities can suffer due to the feeling of being evaluated. The best way to combat this issue is to have mock interviews to recreate the experience until we’ve adjusted to it. Having a problem solving process also really helped to give me a leg up, and the best one that I’ve found is <a href="https://medium.com/launch-school/solving-coding-problems-with-pedac-29141331f93f" rel="nofollow">PEDAC</a>.</p>
<h1 id="know-what-youre-looking-for-in-a-role-amp-com_1">Know what you’re looking for in a role & company <a class="head_anchor" href="#know-what-youre-looking-for-in-a-role-amp-com_1" rel="nofollow">#</a>
</h1>
<p><img src="https://miro.medium.com/max/11232/1*4yMpTIs2F_svLXmDhgndbw.jpeg" alt=""></p>
<p>With all that said, it’s important to take the time and consider exactly what you’re looking. Do you have a strong preference between backend, frontend, or full stack positions? How big of a company do you want to join? Which industries interest you? And in which direction do you want to grow your career?</p>
<p>Your answers to these questions can have a dramatic effect on which companies you choose to interview with. As software developers, we’re lucky to have no shortage of jobs and companies looking to hire, but it’s important to remember these points:</p>
<ol>
<li><p>There is a large variety of roles and areas of work to choose from, and you should consider which areas of software development you want to specialize in.</p></li>
<li><p>You should try to find a role and company that you’ll be happy to work in for several years. My personal opinion is that it’s important to build your experience, credibility, and professional network as an engineer and it’s best to work 1–2 years minimum in each role, rather than job hopping every 6 months — 1 year.</p></li>
<li><p>Just as there are a lot of good jobs in software, there are also a lot of bad jobs that you want to avoid. Not every job will have you work on mature, experienced teams building ambitious, challenging projects. There are jobs in which you could mainly handle tedious tasks, clean up legacy code, or simply minor UI components day-in & day-out.</p></li>
</ol>
<p>So take the time to think about what you want and list the things that you look for in your dream job. For myself, I wanted a role that focused mainly on backend development with the opportunity to:</p>
<ul>
<li>Learn a compiled language like Go.</li>
<li>Work on distributed systems and possibly microservices.</li>
<li>Join an experienced team of engineers to learn from.</li>
<li>Have the ability to work remotely from time-to-time.</li>
<li>Work at a company that values diversity and inclusion.</li>
<li>Have benefits toward continued education.</li>
</ul>
<p>I aggressively sought out companies that offered most of them and didn’t spend time applying to those that didn’t. While not every company would have everything I was looking for, I knew that I would be happier with the end result than if I just mass applied everywhere.</p>
<p>A side benefit was that by targeting the specifics of my next role, I was able to focus my studies on relevant topics that allowed me to improve with every interview, which I feel gave me the needed edge to land my role at DigitalOcean.</p>
<h1 id="manage-the-interview-cycle_1">Manage the interview cycle <a class="head_anchor" href="#manage-the-interview-cycle_1" rel="nofollow">#</a>
</h1>
<p><img src="https://miro.medium.com/max/3820/1*z_8tiXSzygrOwlWXC0wxUw.jpeg" alt=""></p>
<p>The interview process for software development is grueling, and the potential for burn out is very high. Typically, the process can comprise of 3–5 steps, or even more, like so:</p>
<ul>
<li>Initial phone screen with HR or a recruiter</li>
<li>Phone call with a company engineer or hiring manager</li>
<li>Live code challenge with a company engineer</li>
<li>Take home project</li>
<li>Onsite at the company</li>
<li>Potential offer extended</li>
</ul>
<p>Exhausting, right? And every company is different, with some having only 1–2 interviews before the onsite and others taking months!</p>
<p>From my job hunt, I experienced a cycle that repeated itself. First, I would have initial phone screens with multiple companies. These would then lead to code challenges, take home projects, or technical phone screens. After several of these steps and opportunities getting filtered out, any onsites would get clustered into the same week or two.</p>
<p>Since the intensity of these stages increased the further I went in the process, I had less time for new applications due to increased studying, culminating with my onsites which had me studying full-time without sending fresh applications. If no suitable offers were extended, then I would start again with fresh applications and the cycle would start over.</p>
<p>Here are some tips when going through this cycle:</p>
<ul>
<li>Try to keep your application activity high throughout the cycle. It’s important to keep applying and doing outreach in order to fill your interview funnel with new opportunities.</li>
<li>Have a daily goal of applications and outreach to complete. My daily goal for Monday-Thursday was to submit at least 5 applications (often with cover letters) and reach out to 5 engineers for coffee or to ask about open positions.</li>
<li>Think critically about what to expect in each interview. You may get some details in your initial phone screen about the interview process, but always ask for more info in order to prepare.</li>
<li>If you have a call with a CTO, know that it’s common for them to ask you technical questions regarding your resume as well as behavioral questions.</li>
<li>Don’t schedule onsites on back-to-back days. They are by far the most exhausting steps and need more preparation. Always give yourself at least one day of rest in-between onsites to recharge, review topics, and mentally prepare.</li>
</ul>
<h1 id="avoiding-burnout-through-the-process_1">Avoiding burnout through the process <a class="head_anchor" href="#avoiding-burnout-through-the-process_1" rel="nofollow">#</a>
</h1>
<p><img src="https://miro.medium.com/max/760/1*3QVuXfNawq8dGKfkXbs3eA.gif" alt=""></p>
<p>At this point, I want to address the importance of avoiding burn out during the job hunt. With the sheer number of interviews to complete and associated stress, it can easily feel overwhelming at times.</p>
<p>Don’t overwork yourself by studying & coding for 6+ hours a day on top of interviews, and dedicate time each week to disconnect and recharge. It’ll help you maintain your energy & focus as you steadily ramp up the intensity of later stage interviews.</p>
<p>At most, I studied 4 hours a day and prioritized deep work as described in Cal Newport’s <a href="https://www.amazon.com/Deep-Work-Focused-Success-Distracted/dp/1455586692" rel="nofollow">Deep Work</a>, which is where you focus intensely for a period of time on a task that is more difficult than what you’re used to without any distractions.</p>
<p>This meant solving algorithm problems or practicing projects that were harder than what I had already completed. This made sure that I kept improving my skills, while also identifying where I struggled and needed to study more.</p>
<p>And no matter how busy my week was, I always took at least one day off to relax and recharge for upcoming interviews.</p>
<h1 id="in-the-end_1">In the end… <a class="head_anchor" href="#in-the-end_1" rel="nofollow">#</a>
</h1>
<p>I’m extremely happy with the results of my job hunt and feel that the approaches I detailed above worked well for me. For those of you out job hunting now, I hope that this article proves helpful to you. I also recommend reading the following article, which I found very helpful for my job hunt:</p>
<p><a href="https://hackernoon.com/what-it-took-to-land-my-dream-software-engineering-job-17c01240266b" rel="nofollow">What it took to land my dream software engineering job — Sun-Li Beatteay</a></p>
<p>Good luck to everyone out there job hunting, keep it up!</p>
<p>Please let me know what you think in the comments! I’d love to hear more about your job hunt experiences and what has worked for you.</p>
tag:jzerwick.svbtle.com,2014:Post/a-practical-guide-to-containers2019-09-08T18:19:47-07:002019-09-08T18:19:47-07:00A practical guide to containers<p>Containers have taken over the software world by storm — and for good reason.</p>
<p>They’ve proven vital for DevOps and deployment, and have a multitude of uses for developers. And this goes not only for large companies, but for independent developers as well. In fact, containers played a vital role in the development and deployment of our project <a href="https://spacecraft-repl.com/" rel="nofollow">SpaceCraft</a>.</p>
<p>In this article, we’re going to give an introduction to containers and explain their core features. We’ll then showcase their uses in software development and cover some important topics regarding security and resource management. Along the way, we’ll give a peek into <a href="https://spacecraft-repl.com/" rel="nofollow">how containers were utilized in SpaceCraft</a>. Let’s dive in!</p>
<h1 id="what-is-a-container_1">What Is A Container? <a class="head_anchor" href="#what-is-a-container_1" rel="nofollow">#</a>
</h1>
<p>So what exactly is a container?</p>
<p>At its core, a container can be described as a single unit of encapsulated software. It’s essentially a box in which you can place all of your project dependencies and run a single service or an entire development environment, while keeping everything inside the box isolated from the host system.</p>
<p><img src="https://miro.medium.com/max/2874/0*yvWotn70SyhmChBl" alt="Container Overview"></p>
<p>As an example, imagine that you need to work on a new project and know all of the needed dependencies. But some of these dependencies may conflict with what you already have installed on your computer, like a language version number.</p>
<p>If you were to work on the project on your computer, you’d have to go through the tedious process of managing your dependencies and deactivating versions while activating the versions that you need.<br>
This issue is compounded when it’s a whole team of developers working on the same project, and no two developers have the same configurations on their computer.</p>
<p>With a container, you can simply put all your needed dependencies inside it and then work on your project from within the container. This saves a ton of a headache by eliminating the dependency management issues and instead providing us with an isolated area to work in.</p>
<h1 id="how-are-containers-made_1">How are containers made? <a class="head_anchor" href="#how-are-containers-made_1" rel="nofollow">#</a>
</h1>
<p>So we now know what a container is. But how exactly do we create them?</p>
<p>Well, to start we need to create an image. This is simply a package that includes all of the dependencies that should exist in our container. It’s a snapshot of everything that should be inside our container when we run it.</p>
<p><img src="https://miro.medium.com/max/2614/0*scsKCR90km2tHBVt" alt=""></p>
<p>An easy way to visualize this is to think of an image as a class and a container as an object that is instantiated from that class. So our image will serve as a blueprint for creating our containers, and we can create any number of identical containers from the same image.</p>
<h1 id="how-are-images-built_1">How are images built? <a class="head_anchor" href="#how-are-images-built_1" rel="nofollow">#</a>
</h1>
<p>Images are built by <a href="https://www.aquasec.com/wiki/display/containers/Docker+Images+101" rel="nofollow">executing a set of commands</a>. In Docker, the set of commands are written in a text file called Dockerfile.</p>
<p>When the image build process starts, each command <a href="https://docs.docker.com/storage/storagedriver/#images-and-layers" rel="nofollow">forms a layer</a> that comprises the final image. The last layer specifies what command to run within a container when a container is started.</p>
<p><img src="https://miro.medium.com/max/2618/0*EwCkQvNdRGkNLRPv" alt="An example Dockerfile that builds into an image. Each layer represents an instruction from the Dockerfile.<br>
“></p>
<p>In <a href=">SpaceCraft, we bundled a <a href="https://hub.docker.com/r/phusion/baseimage/" rel="nofollow">modified version of Ubuntu</a>, our language runtimes, and a copy of our application code into an image to start multiple containers that each run an instance of our application.</p>
<p>Images do not necessarily need to be stored or built on just your local machine. Containers are meant to be deployable anywhere and thus we should be able to access our images from any physical machine. This is accomplished through <a href="https://docs.docker.com/registry/introduction/#understanding-image-naming" rel="nofollow">registries</a>, which are essentially a place to remotely store and access images.</p>
<h1 id="why-should-we-use-containers_1">Why should we use containers? <a class="head_anchor" href="#why-should-we-use-containers_1" rel="nofollow">#</a>
</h1>
<p>Now we can dive into the many use cases of containers.</p>
<p>Remember how we said that containers can provide us with an isolated box to hold a development environment with a specific set of dependencies? Each developer can simply download the needed image from a registry onto their local computer and then create a container from that image.</p>
<p>This way, they can start contributing to existing projects in no time.</p>
<h2 id="ease-of-deployment_2">Ease of deployment <a class="head_anchor" href="#ease-of-deployment_2" rel="nofollow">#</a>
</h2>
<p>As you can see, one of the biggest advantages of containers is that they are easily deployable on a variety of systems, due to their isolation. This allows developers to uncouple their software from their physical machines and launch a container from anywhere.</p>
<h2 id="run-multiple-services-on-one-machine_2">Run multiple services on one machine <a class="head_anchor" href="#run-multiple-services-on-one-machine_2" rel="nofollow">#</a>
</h2>
<p>Another use case involves placing a single service in a container and then communicating with that service.</p>
<p>In this situation, you can build a system that houses individual services in separate containers. This allows you to isolate each piece of your system architecture and run multiple services on the same host while making it easy to swap services in and out of your system as needed.</p>
<p>To demonstrate how this works, each service can communicate with each other through <a href="https://docs.docker.com/v17.09/engine/userguide/networking/" rel="nofollow">Docker container networking</a> by their IP addresses. With this, containers can, for instance, send HTTP requests with the destination container’s IP address as part of the URL.</p>
<p><img src="https://miro.medium.com/max/1748/1*iWhuxKeM7ydMfZQb2GQLkA.png" alt="Containers can communicate with each another via their IP addresses."></p>
<p>In fact, we use this technique in <a href="https://spacecraft-repl.com/" rel="nofollow">SpaceCraft</a>. We’ve built a <a href="https://www.incapsula.com/cdn-guide/glossary/reverse-proxy.html" rel="nofollow">reverse proxy server</a> that forwards clients’ requests to the appropriate containers. To enable communication between our reverse proxy server and the containers, we retrieve the containers’ IP addresses during initialization and use them as destinations for proxying.</p>
<h2 id="isolation-for-security_2">Isolation for Security <a class="head_anchor" href="#isolation-for-security_2" rel="nofollow">#</a>
</h2>
<p>Another important use case is that containerized applications are isolated from the host system. This prevents unwanted user access to the host’s file system. This is important, especially for an application like <a href="http://repl.space/" rel="nofollow">SpaceCraft</a> that gives users the ability to execute code.</p>
<p>We can also add security measures to strengthen the isolation and further prevent malicious activity from reaching our host system. We’ll explore these strategies in the following section.</p>
<h1 id="containers-versus-virtual-machines_1">Containers versus Virtual Machines <a class="head_anchor" href="#containers-versus-virtual-machines_1" rel="nofollow">#</a>
</h1>
<p>At this point, we want to make clear the distinction between containers and virtual machines, as this can heavily impact your decision on which to use.</p>
<p>Virtual machines came before containers, and were used to address the same pain points as containers. Essentially, they provide an isolated environment for services and development and are deployable on multiple systems.</p>
<p>However, there are some significant differences between them and containers.</p>
<h2 id="containers-are-more-lightweight-and-faster-to_2">Containers are more lightweight, and faster to spin up <a class="head_anchor" href="#containers-are-more-lightweight-and-faster-to_2" rel="nofollow">#</a>
</h2>
<p>First, containers are more lightweight in memory requirements than virtual machines. Depending on what you place in a container, they generally run in the tens to hundreds of MBs for memory size.</p>
<p>Virtual machines are far heavier and run into the GBs. This is mainly due to one big inclusion: the operating system kernel.</p>
<p><img src="https://miro.medium.com/max/2048/0*a8oStcuvBWIU9Vx6.png" alt=""></p>
<p>Virtual machines contain not only all of your dependencies for your service or environment, but also a full copy of an operating system kernel to run all of your dependencies. This addition can add a lot of memory to an instance of a virtual machine.</p>
<p>On the other hand, containers don’t contain a kernel and instead make system calls to the host system kernel. This dramatically lowers their memory footprint. It allows for more containers to be created and used on a system, as opposed to the number of virtual machines you can run on the same system.</p>
<p>In addition to a smaller memory footprint, the lack of a kernel in a container makes their startup time a lot faster. Container startup can happen in seconds, whereas virtual machines will take much longer.</p>
<h2 id="vms-are-more-secure-by-default_2">VMs are more secure by default <a class="head_anchor" href="#vms-are-more-secure-by-default_2" rel="nofollow">#</a>
</h2>
<p>However, there are always tradeoffs. When it comes to virtual machines versus containers, the big tradeoff is security.</p>
<p>Because containers need access to the host system kernel to make system calls, they are not as airtight on security as a virtual machine.<br>
In fact, resourceful malicious users can find ways to use this security disadvantage to break out of a container and gain access to the host system.</p>
<p>With virtual machines, this risk is mitigated because each instance of a virtual machine contains a kernel for its system calls. Thus there is stronger isolation between a virtual machine and the host system than with a container.</p>
<p>However, the security risks of containers can be addressed by implementing a few security measures that we incorporated into <a href="https://spacecraft-repl.com/" rel="nofollow">SpaceCraft</a>, which we will look at now.</p>
<h1 id="security-measures_1">Security measures <a class="head_anchor" href="#security-measures_1" rel="nofollow">#</a>
</h1>
<p>One huge security issue that you should know about is that users generally run as root users in containers by default.</p>
<p>This means that anyone who works inside a container, whether a developer on your team or a user who is using an application that is housed in a container on the back end, will have privileged access to the container file system.</p>
<p>If you’re concerned about giving this level of control over to the container user, then you should consider ways to limit their privileges.</p>
<p>This issue can be addressed by creating an unprivileged user profile in the container filesystem, and having users run as that user profile while in the container.</p>
<p>This will restrict their ability to access the container filesystem and run commands that could harm your container environment and any services running inside it.</p>
<p>Another security issue that can rear its head is the ability for users to break out of containers and access the file system of the host system.</p>
<p>As we mentioned before, containers make system calls to the host system kernel in order to run processes. This opens the door for malicious users to break out of a container and attach the host system.</p>
<p><img src="https://miro.medium.com/max/2610/0*1foYXcmqkxT5MF_z" alt="Containerization alone provides weak isolation, where all system calls made by our application are accepted by the host kernel. Source: gVisor Github"></p>
<p>One of the methods we use to prevent this situation is to use a container runtime sandbox to intercept the system calls made by a container. The sandbox acts as a guest kernel and creates a strong level of isolation between the container and host kernel. This prevents malicious users from attacking our host system.</p>
<p>If you’re interested in using a container runtime sandbox, check out <a href="https://github.com/google/gvisor" rel="nofollow">gVisor</a> which is an open-source solution provided by Google that we utilized with <a href="https://spacecraft-repl.com/" rel="nofollow">SpaceCraft</a>.</p>
<h1 id="container-resource-control_1">Container resource control <a class="head_anchor" href="#container-resource-control_1" rel="nofollow">#</a>
</h1>
<p>One more issue that we want to address pertains to potential abuse of a container’s resources.</p>
<p>Since a container runs on a host system and uses the host kernel, it essentially consumes CPU and memory resources from the host system to complete its processes and tasks.</p>
<p>While this is usually not a problem on an individual level with developers using containers, it does become a bigger problem once we use containers to deploy applications to be used by external users.</p>
<p>Let’s say that your system architecture includes using containers to run separate instances of your application that users can access. And something happens with one of those containerized instances that requires more CPU and memory from the host system than expected.</p>
<p>What this can result in is that one instance hogs system resources away from the other instances which causes their performances to drop and create a poor user experience.</p>
<p>Obviously, this is a situation that we want to avoid if possible. Thankfully we can do so with cgroups, which is short for ‘control groups’.</p>
<p>With cgroups, you can limit the amount of system resources used by a container and thereby prevent the situation we just described.</p>
<p>For example, you can set the cgroups on a container to be a maximum of 100MB of memory and 20% of CPU. With those limits set, that container will never be able to use more than 100MB of memory or utilize more than 20% of CPU from the host system for its lifetime. You can rest easy knowing that the performance of your other containerized application instances will not drop.</p>
<p>In SpaceCraft, we utilized cgroups to limit the maximum amount of memory and CPU that a single session can consume. If a session happens to run an expensive computation and consume all available resource within that container, only that session will be affected.</p>
<p><img src="https://miro.medium.com/max/2882/0*4AuQsNiYE-xTqP5z" alt="With each session isolated and controlled through cgroups, a single spike in resource consumption will only affect that session, while leaving others unaffected."></p>
<h1 id="where-can-i-get-started_1">Where can I get started? <a class="head_anchor" href="#where-can-i-get-started_1" rel="nofollow">#</a>
</h1>
<p>There are many container services that you can choose from. We used Docker for <a href="https://spacecraft-repl.com/" rel="nofollow">SpaceCraft</a> due to its ease of use and excellent documentation. We highly recommend it for your next project.</p>
<p>Other options include:</p>
<ul>
<li>Redhat OpenShift</li>
<li>Amazon EC2 Container Service</li>
<li>AWS Elastic Container Registry</li>
<li>Google Cloud Container Registry</li>
<li>Azure Kubernetes</li>
<li>HashiCorp</li>
<li>Quay</li>
</ul>
<h2 id="integration-with-nodejs_2">Integration with Node.js <a class="head_anchor" href="#integration-with-nodejs_2" rel="nofollow">#</a>
</h2>
<p>If you use Node.js primarily for your development, <a href="https://github.com/apocas/dockerode" rel="nofollow">Dockerode</a> can help you to interact with Docker from within a Node.js environment. We leveraged Dockerode to help us perform some important container actions, including:</p>
<ul>
<li>Starting and destroying a container</li>
<li>Reading a container’s IP address</li>
<li>Placing limits on a container’s memory and CPU usage</li>
</ul>
<p>Those operations are important to help us handle multiple sessions and scale our application.</p>
<h1 id="conclusion_1">Conclusion <a class="head_anchor" href="#conclusion_1" rel="nofollow">#</a>
</h1>
<p>Containers are an extremely useful tool in your arsenal as a software developer to simplify and speed up your project deployment.</p>
<p>Whether it’s creating an isolated development environment for building projects, setting up a microservices architecture, or helping to onboard a new team member, the utility of containers continues to grow over time. Give it a try in your next project and see how they can benefit you!</p>
<p>If you enjoyed reading this article, we’ve also written a detailed case study on how we built SpaceCraft and the challenges that we faced. You can <strong><a href="https://spacecraft-repl.com/whitepaper" rel="nofollow">read it here</a></strong>.</p>
<p><em>Co-written by Julius, Gooi, and Nick of the <a href="https://spacecraft-repl.com/team" rel="nofollow">SpaceCraft Team</a>.</em></p>
<h1 id="references_1">References <a class="head_anchor" href="#references_1" rel="nofollow">#</a>
</h1>
<ul>
<li><a href="https://www.docker.com/resources/what-container" rel="nofollow">What is a container</a></li>
<li><a href="https://blog.octo.com/en/i-am-a-developer-why-should-i-use-docker/" rel="nofollow">I am a Developer: why should I use Docker?</a></li>
<li><a href="https://dev.to/petermbenjamin/docker-security-best-practices-45ih" rel="nofollow">Docker Security Best-Practices</a></li>
<li><a href="https://cloud.google.com/blog/products/gcp/open-sourcing-gvisor-a-sandboxed-container-runtime" rel="nofollow">Open-sourcing gVisor, a sandboxed container runtime</a></li>
<li><a href="https://devops.stackexchange.com/questions/447/why-it-is-recommended-to-run-only-one-process-in-a-container" rel="nofollow">Why it is recommended to run only one process in a container?</a></li>
<li><a href="https://medium.com/@mccode/processes-in-containers-should-not-run-as-root-2feae3f0df3b" rel="nofollow">Processes In Containers Should Not Run As Root</a></li>
</ul>
tag:jzerwick.svbtle.com,2014:Post/elevate-your-learning2019-09-08T17:56:34-07:002019-09-08T17:56:34-07:00Elevate Your Learning<p>In this article, I wanted to write about the changes I’ve made in my own ability to learn new subjects and material through my journey at Launch School. I think that it’s crucial for anyone in a knowledge-driven field to analyze how they learn and improve these skills, and that goes double for software developers.</p>
<p>Software development demands a near constant learning of new technologies and areas in order to stay sharp, stand on the forefront of technology, and remain hirable in the future. And thus it is vital that we not only learn new subjects deeply, but also improve our ability to learn more effectively.</p>
<p>Over the past 1.5 years of studying at Launch School, I’ve continually improved my learning process and revamped the techniques I use on a daily basis. I’ve gone through the Learning How to Learn course on Coursera and read multiple books that have influenced how I learn, which I’ve listed at the end of this article. I’d like to share with you what I’ve found useful and what I’ve discarded as useless. Let’s begin!</p>
<h1 id="spaced-repetition_1">Spaced Repetition <a class="head_anchor" href="#spaced-repetition_1" rel="nofollow">#</a>
</h1>
<p>This technique is a process in which you review material on a delayed time scale and is often implemented through flashcards. The goal is to review material that you find difficult more frequently, and to review material at the point that you’re just about to forget it. This helps to build a stronger neural connection to the information so that you can recall it more effectively.</p>
<p>Let’s say that you’re studying JavaScript and have created a flashcard deck covering everything you need to know about it. Traditionally, one would review the entire deck every time they study and they would review it every day or so.</p>
<p>Spaced repetition has you review the deck once, separate the cards based on whether you recalled the card’s info easily or not, and then review the cards again at different intervals. If you got a card right immediately, review it again in a week. If you struggled with a card, then review it tomorrow. Repeat this process over time and extend the intervals if you continually recall a card’s information. And if you struggle with a card, then “reset” it’s interval to tomorrow.</p>
<p>This technique requires consistency and offers huge payoffs by improving your ability to remember key information while also giving you a system to study a reasonable amount of cards each day. Thankfully, there is a free program called Anki that you can download to create and store your flashcards, and it even calculates the time intervals for you! I highly suggest you use it instead of keeping your own flashcards on hand.</p>
<h1 id="deep-work_1">Deep Work <a class="head_anchor" href="#deep-work_1" rel="nofollow">#</a>
</h1>
<p>This is a game changer and was made mainstream by Cal Newport in his book Deep Work, which I highly recommend. The book’s key takeaway is that in order to thrive in the knowledge economy of today (which software development firmly sits in), we need to develop the ability to quickly master hard things and produce at a high level in terms of both quality and speed. And the way to do so is through deep work, which is when you work/learn in a state of distraction-free concentration that pushes your abilities to the limit.</p>
<p>For example, if you’re studying blocks in Ruby and want to utilize deep work, then you need to study somewhere quiet without any distractions (no social media, email, phone, music, etc.) and push your brain to soak in the information by filling in the gaps of your knowledge and solving problems. You’ll likely find that doing so will be hard as your focus will constantly want to shift to something new and your brain will feel strained by having all your concentration on the material.</p>
<p>However, this technique is extremely important as it builds your brain like a muscle. In the beginning, I couldn’t perform deep work for more than about 40 min at a time before I needed a break. But now I’m able to do 1.5 hours at a time 3–4x a day. There is a reason that deep work is often discussed at Launch School, as it truly improves your ability to learn a new topic and work through challenging situations.</p>
<h1 id="deliberate-practice_1">Deliberate Practice <a class="head_anchor" href="#deliberate-practice_1" rel="nofollow">#</a>
</h1>
<p>Another technique that is closely related to deep work is deliberate practice, which is the focused practice of a weak area/skill in order to improve it. Just like deep work, it requires you to work distraction free and to focus entirely on the task at hand. The task should be a challenge that is just above your current skill level in order to facilitate and push your growth. The steps I follow for deliberate practice are generally:</p>
<ol>
<li>Identify a weak area/skill that I need to improve.</li>
<li>Create a goal that I want to achieve by the end of my practice.</li>
<li>Work distraction free on this area/skill for a set amount of time (typically 1–1.5 hours is the limit for most people).</li>
<li>Review my progress and determine if I’ve met my goal.</li>
</ol>
<p>To make this more concrete, let’s use the example of me improving my front-end development skills in the 230 course. While in the course, I had identified that I felt struggled with building small projects from barebones HTML & CSS all the way up to adding the user interactions with JavaScript. My deliberate practice would then be to:</p>
<ol>
<li>Identify that my weak skill was on building up the UI, not the HTML/CSS or basic JavaScript.</li>
<li>Set my goal to be a completed small project that allows user interactions through event listeners, handlers, & managing HTTP requests.</li>
<li>Set up my work area to be removed of distractions and start with a barebones project that already had HTML/CSS and a backend to receive HTTP requests (there are plenty of such projects to practice with in the 230 course).</li>
<li>Work on this project for 1–1.5 hours with complete focus.</li>
<li>Once the time is up, I’ll quickly review my progress and determine what areas in the project I needed to practice further.</li>
</ol>
<p>You can use deliberate practice on almost any subject or project so long as you follow a similar process. Soon enough, you’ll see a considerable improvement in what was once a weak area for you.</p>
<p>I do want to make a quick note of the distinction between deliberate practice and deep work. They can seem to be the same thing and there is a lot of overlap, however there are some important differences. I consider deep work to be related to learning new material or working on an existing project with extreme focus. Examples of these include:</p>
<ul>
<li>Building a side project.</li>
<li>Reading up on a new subject and organizing your understanding (like Ruby in the 101 course).</li>
<li>Writing a blog post.</li>
<li>Reviewing some material you may have forgotten.</li>
</ul>
<p>Now, deliberate practice does incorporate deep work in requiring focus and lack of distractions. But the goal of deliberate practice is to improve an existing skill or to take your current understanding of material to another level. Examples include:</p>
<ul>
<li>Practicing concepts to improve on through small projects.</li>
<li>Solving coding problems that are harder than those you’ve previously solved.</li>
<li>Improving your ability to explain a difficult/complex concept (like prototypical inheritance in JavaScript)</li>
<li>Practice system design and algorithms in preparation for an interview.</li>
</ul>
<p>Try to implement both deep work and deliberate practice into your daily studies and see for yourself how a big difference they can make.</p>
<h1 id="the-feynman-method_1">The Feynman Method <a class="head_anchor" href="#the-feynman-method_1" rel="nofollow">#</a>
</h1>
<p>This last technique is one of my favorites and has shown up in quite a few articles. It’s a method popularized by Richard Feynman, a Nobel Prize winning physicist who is widely regarded as one of the greatest teachers for explaining complex ideas in simple terms. One of his most famous quotes is how he would explain the concept of atoms:</p>
<blockquote>
<p><em>If, in some cataclysm, all of scientific knowledge were to be destroyed, and only one sentence passed on to the next generations of creatures, what statement would contain the most information in the fewest words? I believe it is the atomic hypothesis (or the atomic fact, or whatever you wish to call it) that all things are made of atoms — little particles that move around in perpetual motion, attracting each other when they are a little distance apart, but repelling upon being squeezed into one another. In that one sentence, you will see, there is an enormous amount of information about the world, if just a little imagination and thinking are applied. — Richard Feynman</em></p>
</blockquote>
<p>During his graduate school days, Richard Feynman would take a brand new notebook and title it “Things I Don’t Know”. In this notebook, we would identify the gaps in his knowledge on a subject and dissect each detail until he had formed a complete understanding of the material. His process was actually quite simple:</p>
<ol>
<li>Identify the subject and write out everything you know about the subject. 2. Do this without looking at any notes or resources, but instead recalling your subject knowledge from memory.</li>
<li>Explain the subject to someone who wouldn’t know anything about the subject. With this step, you are forced to use simple terms and focus on brevity.</li>
<li>Identify any gaps in your explanation, whether in your difficulty explaining a piece of the subject or questions from your audience that you couldn’t easily or simply answer. This is where the true learning begins.</li>
<li>Return to learning the gaps you discovered. Organize and simplify your explanation into a narrative that’s easy to convey.</li>
</ol>
<p>The power of this technique comes from the recall of information completely from memory (similar to spaced repetition) and the cycle of learning a subject, refining your understanding, trying to make it understandable to someone else, and identifying what you still need to improve on. Our brains are exceptionally good at making us believe that we are more fluent with a subject than we actually are (known as the illusion of fluency) and this technique makes it brutally clear how fluent you actually are on a subject.</p>
<p>Now this likely sounds like a lot of work, and it can be if you use it for every single concept in a larger subject area. So I would recommend that you pick a broad subject (like the fundamentals of Ruby or how HTTP works), and as you write out the details and follow the process you’ll naturally find the gaps to focus on. And of course, this technique is best implemented using deep work!</p>
<h1 id="conclusion_1">Conclusion <a class="head_anchor" href="#conclusion_1" rel="nofollow">#</a>
</h1>
<p>I hope that you try these techniques out and find them as useful as I have. Learning how to learn can be a rewarding and enlightening journey, and I highly recommend that you explore a range of techniques to find what works for you. If you have any tips or tricks that I didn’t cover or want to share your experiences with the ones that I have shared, please leave a comment. Thanks for reading!</p>
<h1 id="book-list_1">Book List <a class="head_anchor" href="#book-list_1" rel="nofollow">#</a>
</h1>
<p>Deep Work — Cal Newport<br>
Mastery — Robert Greene<br>
The Art of Learning — Josh Waitzkin<br>
The 5 Elements of Effective Thinking— Burger & Starbird<br>
Mindset — Carol Dweck<br>
Learning How to Learn — Dr. Barbara Oakley (Coursera)</p>
tag:jzerwick.svbtle.com,2014:Post/why-you-need-an-interview-script2019-09-08T17:45:51-07:002019-09-08T17:45:51-07:00Why You Need an Interview Script<p>There are few things as anxiety-inducing as being interviewed for a job or as an assessment over coursework. It goes beyond merely stressful and creates a host of physical reactions: sweaty palms, shaky legs, labored breathing, a queasy stomach, and much more. All while your performance will ultimately determine your potential grades, salary, and career opportunities.</p>
<p>It’s no wonder that our ability to solve problems and answer technical questions degrades substantially under these conditions! And yet, many people brush off these concerns and hold onto an illusion of superior competence while under trial by fire. With so much depending on our ability to perform under stress, we should be smart about setting ourselves up for success and create a process to reduce this mental degradation while under pressure to perform.</p>
<p>That is why you need an interview script. Having a prepared script to follow will help you get into the flow of solving a problem before your anxiety can make you freeze and sink your performance. To illustrate its effectiveness, I’ll take you through a coding challenge using an interview script that I’ve created for myself and has helped me succeed in my assessments at Launch School.</p>
<h1 id="step-1-read-the-problem-and-load-it-into-your_1">Step 1: Read the problem and load it into your brain <a class="head_anchor" href="#step-1-read-the-problem-and-load-it-into-your_1" rel="nofollow">#</a>
</h1>
<p>First and foremost, you need to slowly read the problem and start processing it so that you can understand what you are being asked to solve. Start by writing out the problem’s main points in your own words.</p>
<p>Here is our code challenge:</p>
<pre><code class="prettyprint">Write a method that takes a string argument and returns a new string that contains the value of the original string with all consecutive duplicate characters collapsed into a single character.
</code></pre>
<p>Now, your first thought after reading may range from “This looks so easy!” to “Where do I even begin?”. Believe me, if you think this problem will be no sweat during an interview, that is the illusion of competence speaking to you. Every problem will seem more difficult when you are under the interview spotlight and can feel the gaze of your interviewer boring into you. Even problems that you may have handled with ease in the comfort of your home will suddenly morph into frightening monsters while under pressure.</p>
<p>Let’s take the prompt apart and write it out into something simpler to read:</p>
<pre><code class="prettyprint">- You are given a string argument for a method.
- This string may contain consecutive duplicate characters.
- Write a method that will take this string argument and return a new string.
- This return value will have all consecutive duplicate characters collapsed into a single character.
</code></pre>
<p>Include some examples of string arguments and the expected return values to illustrate what you want your solution to achieve.</p>
<pre><code class="prettyprint">Input: ‘bbbbbbbbb’ → Output: ‘b’
Input: ‘wwooonndeerrfull woorrlldd’ → Output: ‘wonderful world’
</code></pre>
<p>Great! This is more manageable and captures the main points, while also showing the interviewer how you can break down a problem into understandable parts. This will help to anchor you during the interview and serve as a reference while you craft your solution. The key is small victories along the way that demonstrate your skills and help you progress through the challenge while maintaining your confidence and flow. Breaking the challenge into smaller, manageable pieces is the first victory.</p>
<h1 id="step-2-write-out-your-approach-in-a-stepbyste_1">Step 2: Write out your approach in a step-by-step process. <a class="head_anchor" href="#step-2-write-out-your-approach-in-a-stepbyste_1" rel="nofollow">#</a>
</h1>
<p>Our next step will be to carefully layout our process for creating the solution in a step-by-step process. Doing so will allow you to focus on each individual step one at a time, while also making it easier to see the flow of the solution. Additionally, once you’ve solved the problem and receive some questions regarding refactoring or extra features, you can more easily see where in the flow to make your changes.</p>
<p>Here is my step-by-step process template:</p>
<pre><code class="prettyprint">Approach:
(1)
(2)
(3)
…
</code></pre>
<p>Using this template, I write out my high-level approach to solving the problem and then list each step in the solution’s execution. Here is my completed template for this challenge:</p>
<pre><code class="prettyprint">Approach: Use a loop within the method to check each character in the string. In this loop, we will check whether the character is equal to the next character. If it’s a duplicate, we will skip it. If it is not, then we will add it to a new string. At the end of the method, we will return the new string.
(1) Write a method definition that takes a string argument.
(2) Initialize a local variable assigned to a blank string.
(3) Initialize a local variable called index assigned to 0 to track which character we are checking in the loop.
(4) Create a loop that starts at index = 0 and repeats until index = string[-1].
(5) For each loop execution, check if the current character matches the following character.
(i) If true, increment the index and start the next loop execution.
(ii) If false, add the current character to the local string variable.
(6) Once the loop is complete, return the local string variable containing the string of distinct characters.
</code></pre>
<p>Phew! That may seem like a lot of writing, but it will make crafting the actual solution much faster and it will help you to answer any curveballs the interviewer may throw at you later. Another victory achieved!</p>
<h1 id="step-3-if-no-tests-are-provided-write-some-ou_1">Step 3: If no tests are provided, write some out with your expected output. <a class="head_anchor" href="#step-3-if-no-tests-are-provided-write-some-ou_1" rel="nofollow">#</a>
</h1>
<p>Remember, good engineers test their code! Your interviewer may provide you with some tests, but be prepared to write some yourself. Here are some tests that I would write for this problem:</p>
<pre><code class="prettyprint">collapse(‘bbbbbbbbb’) == ‘b’
collapse(‘wwooonndeerrfull woorrlldd’) == ‘wonderful world’
collapse(‘222xyzxyzyx’) == ‘2xyzxyzyx’
collapse(‘Q’) == ‘Q’
collapse(‘AAbbCC’) == ‘AbC’
collapse(‘’) == ‘’
</code></pre>
<p>Do not take this step for granted! It is a vital component in the process to show your value as a strong applicant. An engineer that thoroughly and consistently tests their code will stand out among other applicants, and the best places to work highly value good testing practices.</p>
<h1 id="step-4-layout-your-rough-draft-of-the-problem_1">Step 4: Layout your rough draft of the problem with pseudocode. <a class="head_anchor" href="#step-4-layout-your-rough-draft-of-the-problem_1" rel="nofollow">#</a>
</h1>
<p>At this time, we can start writing out the skeleton of our solution. Start with the basic method definition, and then write out the steps from your approach in your solution. Note: you should prioritize completing a working solution, even if it is a brute force solution with some redundancy. Once it’s finished, you can and should refactor your code.</p>
<pre><code class="prettyprint">def collapse(string)
INITIALIZE A NEW EMPTY STRING VARIABLE collapsed_string
INITIALIZE index AT ZERO.
while index <= string[-1]
START WITH FIRST CHARACTER AND EXAMINE NEXT CHARACTER.
if THEY ARE THE SAME,
INCREMENT index BY 1
SKIP TO NEXT CHARACTER FOR LOOP.
else
ADD CURRENT CHARACTER TO NEW STRING VARIABLE.
end
INCREMENT index BY 1
end
RETURN collapsed_string
end
</code></pre>
<p>Now, this step may seem extraneous considering that you already wrote your steps out in the template above. However, using pseudocode to outline your solution is like writing your first draft of a paper. It provides the skeleton that you’ll flesh out moving forward, and there is already some code written. Remember, small victories along the way will keep you in the flow and prevent your confidence from wavering under the spotlight.</p>
<h1 id="step-5-rewrite-solution-in-actual-code_1">Step 5: Rewrite solution in actual code. <a class="head_anchor" href="#step-5-rewrite-solution-in-actual-code_1" rel="nofollow">#</a>
</h1>
<p>Now take each line of pseudocode and replace it with actual, functioning code.</p>
<pre><code class="prettyprint">def collapse(string)
collapsed_string = ‘’
index = 0
while index <= string.length
if string[index] == string[index + 1]
index += 1
next
else
collapsed_string << string[index]
end
index += 1
end
collapsed_string
end
</code></pre>
<p>No sweat right? At this point, you have been running a consistent train of thought on how to solve this challenge and avoided freezing up.</p>
<h1 id="step-6-test-your-code_1">Step 6: Test your code. <a class="head_anchor" href="#step-6-test-your-code_1" rel="nofollow">#</a>
</h1>
<p>Now it’s time to test! If given the chance to use a computer, run your tests and see if they all pass. If you’re on a whiteboard, go through some tests by hand to make sure that your solution executes as expected.</p>
<p>If you encounter any issues, this is a good thing! You’ve shown that you are willing to check your code and can handle fixing bugs. Remember: very rarely does ANY code work on the first run and it’s completely normal to undergo a few revisions before a successful run. It’s more important to show that you are comfortable with the process of creating, testing, and refactoring your code to completion, and will do so with any code you work on.</p>
<h1 id="step-7-refactor-your-code_1">Step 7: Refactor your code. <a class="head_anchor" href="#step-7-refactor-your-code_1" rel="nofollow">#</a>
</h1>
<p>So now you’ve gotten all your tests to pass and you’ve cleared the challenge. Awesome job! But it doesn’t stop there, and you will likely be asked by your interviewer if you can refactor your code to improve it. Hopefully, the previous steps have given you an in-depth understanding of the problem and your own solution to easily identify areas of improvement.<br>
Let’s go through our code and look for areas to refactor:</p>
<pre><code class="prettyprint">def collapse(string)
collapsed_string = ‘’
index = 0
while index <= string.length
# condense conditional into a single line using “unless”
if string[index] == string[index + 1]
index += 1
next
else
collapsed_string << string[index]
end
# remove redundant “index += 1” line
index += 1
end
collapsed_string
end
</code></pre>
<p>By condensing the if else conditional into one line with the ‘unless’ keyword and removing the redundant ‘index += 1’ line, we can shorten our solution by 6 lines!</p>
<pre><code class="prettyprint">def collapse(string)
collapsed_string = ‘’
index = 0
while index <= string.length
collapsed_string << string[index] unless string[index] ==
string[index + 1]
index += 1
end
collapsed_string
end
</code></pre>
<p>And there you go! We now have a more compact and readable solution with just a bit of refactoring.</p>
<h1 id="step-8-handle-any-curveballs_1">Step 8: Handle any curveballs. <a class="head_anchor" href="#step-8-handle-any-curveballs_1" rel="nofollow">#</a>
</h1>
<p>It’s no secret that once you’ve solved and refactored the initial problem, your interviewers will likely ask how you would modify it to handle a new scenario. This is another reason why we’ve taken such a detailed approach to solving the problem, as you’ll be much more comfortable with the conditions of the problem and can adjust to these curveballs.</p>
<pre><code class="prettyprint">Potential Curveballs:
(1) What about a string that’s a mix of upper & lower case letter? Ex: ‘AaABBb’
(2) What about an invalid input, like integer values? Ex: 1234
(3) What about a mix of string characters and integer values? Ex: ‘AbC’45’deF’
</code></pre>
<p>These can be addressed either through refactoring your solution or using exceptions to handle invalid input. I’ll leave these as an exercise for the readers to attempt for practice. By this point, I hope that my script has gotten you into the flow of solving this challenge and made you feel confident about handling these curveballs.</p>
<h1 id="practice-and-improve-the-script_1">Practice and Improve the Script <a class="head_anchor" href="#practice-and-improve-the-script_1" rel="nofollow">#</a>
</h1>
<p>Now that you have the script, you need to practice using it in order to reap the maximum benefit from it. Incorporate it into every coding problem you face, no matter how simple it may seem. While the steps laid out above may help you solve difficult problems, it’s main purpose is to anchor your thinking, maintain your flow and confidence, and fight the mental degradation during an interview or assessment.</p>
<p>The more problems that you complete using the script, the easier it’ll become to get started solving a problem while under the pressure to perform. In fact, I believe that it will help you stand out among other interviewees who don’t have a practiced script and end up floundering around a bit before making any progress on the problem. Every inch counts in your interview and against your competition, so make use of this script because I can assure you that there will be others who won’t.</p>
<p>Note that this is the script that has worked for me thus far, and I will improve upon it as time goes on. You should make your own modifications that suit your style, whether it’s creating your own step-by-step process template or how you initially identify the main points of the problem. Just make sure that you follow the overall process and methodology of the script, which is breaking down problems into smaller, digestible pieces that you can manage while under pressure and will earn you small victories along the way.</p>
<h1 id="conclusion_1">Conclusion <a class="head_anchor" href="#conclusion_1" rel="nofollow">#</a>
</h1>
<p>I hope that this script proves useful to you in your future interviews and assessments. If you have any additional points that I may have missed or a particular technique/step that you have found helpful in your own problem solving, please leave a comment below. I’m interested in hearing your thoughts and experiences and look forward to the discussion. Thank you for reading!</p>