© Dan Moore 2020
D. MooreLetters to a New Developerhttps://doi.org/10.1007/978-1-4842-6074-6_4

4. Tools to Learn

Dan Moore1 
(1)
Boulder, CO, USA
 

As software developers, we stand on the shoulders of giants. Software engineers are both toolmakers and tool consumers. Amazingly, many of these useful tools are freely distributed and free to use.

Tools like text editors, version control, and automated tests are used every day in the development and operation of systems. Knowing the syntax of your programming language isn’t enough. You should learn these widely used tools too.

Leverage

Dear new developer,

You need to deliver more with less. Leverage makes you more productive, able to build and deliver better solutions in less time. Tools offer leverage. They also make the job more fun. It is a joy to write software, but for me the true delight of development is building solutions to help people. Tools accelerate development, increase stability, and provide additional functionality beyond what a team can build in a given timeline and budget.

Here are some tools to increase your software delivery capacity:
  • A test suite —A suite provides leverage by serving as living documentation and allowing others to understand the code. It also guarantees that fixed bugs remain fixed so that changes to the system can be made without affecting software that depends on it. This lets you fearlessly evolve the system and incorporate new libraries, algorithms, or techniques.

  • Libraries and frameworks , such as Ruby on Rails—By solving common problems, libraries let you build software faster. Because of their wide usage, they handle edge cases that your users would find if you built your own solution.

  • IaaS (infrastructure as a service) offerings, like AWS EC2—These services provide servers and other infrastructure which you can use APIs (application programming interfaces) to manage. You can apply software engineering techniques to the environment in which your code runs. This lets you ensure consistency of your infrastructure and make deployments repeatable.

  • PaaS (platform as a service) solutions, like Heroku—These offerings constrain your application’s architecture, but remove a whole host of operations tasks and choices from your plate, such as deployment tooling and patching servers. When a bug affects a web server, you don’t spend time checking each of your servers—the provider does. This allows you to focus on business logic.

  • SaaS (software as a service) solutions, like Google Apps—These are an entire snap-in service for a fee, rather than a service you write custom code to use, like IaaS and PaaS solutions. These vary in size and scope, but may integrate with your software.

Leverage makes you more productive . Seek it.

Sincerely,

Dan

The command line

Dear new developer,

I remember the first time I saw a senior engineer struggle with the command line. He had just rolled onto a client project. If memory serves, he was trying to set up his IDE for a Java application.

I noticed him with the command-line window open, trying to navigate around source code directories. I wondered why he was having difficulty. I felt the same way some developers probably feel about me when I struggle with CSS or cutting up a PDF or reading C—“how are you a developer without understanding this?” It cemented in my mind why a new developer should learn the command line inside and out.

It’s a baseline.

The command-line interface (also known as the CLI) will always be available—wherever you are (unless you are on an old Mac, pre-Mac OS X, in which case, why?). This is in contrast to the graphical user interface (GUI) which is omnipresent on desktop machines but missing from many other software environments.

Unlike the other skills I mentioned earlier, knowing how to navigate the command line will make your developer experience better no matter where you work. It’s a general-purpose skill, like understanding how to use version control or learning a text editor.

Let’s take a simple task—I need to move a file into a directory, change the permissions on that file, then look through the file for a certain phrase: “rosebud.” With a CLI , I can:
  • Accomplish the task in less time—I can move files, change permissions, and search the files far faster with CLI tools than I can with any GUI tools. The first few times I try this, I will be slower on the command line than if I were using a GUI. You must learn the CLI and the cues to help you do so are minimal. You also must learn a GUI, but there are more hints—this is why most computers nowadays have GUIs. But once I know the CLI commands, typing will be much quicker than moving the mouse through the GUI.

  • Redo or repeat the tasks—If I’m trying to do this sample task, I can do this one time in the GUI easily, using the mouse and menu commands. But repeating this task, whether once a day, once a month, or on every software release, becomes tedious and error prone. On the other hand, I can do it once in the CLI and then take the CLI commands and put them into a script. A script is a text file with commands that can run them one after the other. The same commands will be run every time I execute the script. My example is simple, but if the task is complex, getting it right once and having a script will save time and energy. All the commands in the script will run in exactly the same way every time. If you don’t do the task often, you will save time with a script because you won’t have to reconstruct the exact commandsexecuted.

  • Easily share the task script with others—If others want to perform this task, using a GUI you could record a video of yourself clicking around. Or you could write down each step in detail and share the document. If you are physically collocated, you could walk over and show someone how to do it. With a CLI, it’s much easier. You send someone an executable script they can run. If they have access to the same command-line programs and data, they’ll get the same results. However, the same command-line program can have different versions, so beware of that possibility.

Hopefully, I’ve convinced you of the benefits of the command line. Now, what are good ways to learn it?

I think that one path is to jump in. Find the “terminal” program if you use a Mac or the “cmd” program if you use Windows. Open it up. Search on the Web for “command-line tutorial <your platform here>” and work through a tutorial. I personally learn best when I have a real task. If you do too, think of a task you do frequently: opening up a number of files for a project or copying files to a backup directory. Do it once in the GUI. Then do it once in the CLI. Then make a script for it. See how that process feels. If you worry about destroying your computer, use a temporary directory and fake files.

Another option is to map between a GUI program such as your code editor and the CLI. Every time you do a task in the GUI, drop down into the CLI and repeat it. For many programs, if it can be done in the GUI, it can be done in the CLI. CLI-compatible tasks can be as simple as renaming a file and as complex as a many step process to build multiple programs.

As you become more comfortable, you may have the option of sharing your keybindings between your editor and your shell. A keybinding is a fancy way to say assigning commands to various keys on your keyboard. Search for “keybindings <editor> <shell>”. I use vi keybindings for my bash shell, and it lets me easily move around the CLI. And every time I learn a new way to move around the editor, my CLI experience improves.

The command line is present on every modern computer. Learning it will save you time, allow you to automate common actions, and let you share those solutions. Well worth the effort.

Sincerely,

Dan

jq, awk, and sed

Dear new developer,

You will work with text files containing structured data at some point in your development career. These are stored in many different formats, including tab-separated variables (TSV), comma-separated variables (CSV), or JavaScript Object Notation (JSON). You may want to extract data, ingest information, or examine log entries. You may be transforming data from one format to another.

If this happens frequently, you should write a tool to help you. Sometimes, though, processing these files is a one-off, and writing a full-fledged tool is overkill. An alternative is to learn some of the Unix tools. Here are three that I consider “table stakes” for a developer. In Listing 4-1, you can see sample lines from a web server log. We’ll process these lines in a few different ways.
54.147.20.92 - - [26/Jul/2019:20:21:04 -0600] "GET /wordpress HTTP/1.1" 301 241 "-" "Slackbot 1.0 (+https://api.slack.com/robots)"
185.24.234.106 - - [26/Jul/2019:20:20:50 -0600] "GET /wordpress/archives/date/2004/02 HTTP/1.1" 200 87872 "http://www.mooreds.com" "DuckDuckBot/1.0; (+http://duckduckgo.com/duckduckbot.html)"
185.24.234.106 - - [26/Jul/2019:20:20:50 -0600] "GET /wordpress/archives/date/2004/08 HTTP/1.1" 200 81183 "http://www.mooreds.com" "DuckDuckBot/1.0; (+http://duckduckgo.com/duckduckbot.html)"
Listing 4-1

Web server access log lines, stored in a file named logs.txt

awk

awk is a multipurpose line processing utility. I often want to refine the data in a log file to highlight certain aspects. This helps me figure out what’s going on.

For example, if we want to see only the IP addresses (the first string in the line which looks like 54.147.20.92) from the file in Listing 4-1, we can use awk to extract that field. awk uses numbers to reference the position in the line, so the IP address is $1. You can see in Listing 4-2 that only the IP addresses are printed.
$ awk '{print $1}' logs.txt
54.147.20.92
185.24.234.106
185.24.234.106
Listing 4-2

The awk command and output to print IP addresses

You can pull out specific fields, or you can print rows with fields that match a certain string. You can sum up values of numeric fields. awk is on every modern Unix system and is useful for such field extraction or manipulation.

sed

sed is another utility that operates on each line of a file. I typically use it to search and replace text in a file. Let’s process the log file in Listing 4-1 to anonymize the IP address and the user agent (the string that contains the name of the program which retrieved the web page, like “Slackbot”). Perhaps we’re going to ship the log file to long-term storage and are concerned about users’ privacy. Using sed, we can easily remove this sensitive data, as seen in Listing 4-3.
$ sed 's/^[^ ]*//' logs.txt |sed 's/"[^"]*"$//'
- - [26/Jul/2019:20:21:04 -0600] "GET /wordpress HTTP/1.1" 301 241 "-"
- - [26/Jul/2019:20:20:50 -0600] "GET /wordpress/archives/date/2004/02 HTTP/1.1" 200 87872 "http://www.mooreds.com"
- - [26/Jul/2019:20:20:50 -0600] "GET /wordpress/archives/date/2004/08 HTTP/1.1" 200 81183 "http://www.mooreds.com"
Listing 4-3

Removing fields using sed

Yes, the strings like 's/^[^ ]*//' may look like line noise, but this is a regular expression. I won’t talk much about regular expressions, but they are present in every modern language and let you match and modify text easily. sed gives you the power of regular expressions at the command line to process text files.

jq

If you work with modern software , chances are you have encountered JSON. It’s used for configuration, web API requests, and log files. Sometimes you need to parse JSON and extract part of the data. Tools like sed and awk are suboptimal for this task because they expect newlines to separate records, not curly braces and commas. Sure, you could use regular expressions to parse simple JSON; I’ve done this in a pinch. But using jq is a far superior experience. I use it whenever I am working with an API that returns JSON. I can retrieve the API with curl (another great CLI tool) and parse it with jq.

If the processing is in any way complicated, I put these commands in a script and then I can repeat my use of this API easily.

A few months ago, I was exploring the Elasticsearch API. I crafted the queries with curl and then used jq to parse the results so I could understand them. Yes, I could have done this same API exploration with a programming language like Python or Ruby, but it would have taken longer. I could also have used a GUI tool like Postman, but then it would have been harder to repeat and refine the process.

sed and awk should be on every system you run across; jq is not usually installed but is a single, free, stand-alone downloadable binary.

Spend time getting to know these tools. Next time you extract information from a text file, reach for sed or awk. If you need to pull out the third element of the objects with a 'foo' key from a JSON file, look to jq. I think you’ll be happy with the results .

Sincerely,

Dan

Version control

Dear new developer,

If in doubt, put it under version control.

Version control lets you keep track of the nuts and bolts of a software system, the files which contain the code and logic. Keeping these under version control lets you make changes. If you screw things up, you can roll back to working code. Version control also lets you see who made what changes when to which files. When you need to find out who to ask about the bizarre function in class XYZ, you can. By the way, don’t be surprised if that person is you—that’s happened to me before.

There are many version control systems. What you use should depend on your needs, but one determinant is how many people interact with your codebase. These days you’ll likely use a distributed version control system like git or mercurial. But any version control system, even a crufty old one like RCS or CVS, is far better than nothing.

Version control systems can be expensive, but some are free. If you aren’t using anything to version control your code, please start. The easiest way is to use a hosted service. GitHub, Bitbucket, and GitLab all are online services with free tiers; they are happy to store your codebase for you. Learning one of the modern version control systems will help on the job, because running a software project of any size without version control is a rare, foolhardy endeavor.

If you are on a team that doesn’t use version control, you can still use it yourself. In this situation, you don’t want to use a hosted service, since you could inadvertently expose proprietary code without the organization’s consent—that can get you fired. Instead, use one of the free systems hosted on your development computer. This will be more work, as you’ll have to sync between the existing system and your version controlled code, but if you can see exactly when a bug was added, or when you need to roll back to the way the code was a week ago, it’ll be worth the effort. Hopefully, you can show the power of a version control system to others, and it will spread to the rest of the team .

An alternative, of course, is to find another job. I honestly can’t think of a good reason to avoid version control. I only have seen this when working with people who lacked basic software development skills and had just hacked a system together.

There are some items that don’t belong in version control, however. Large files, text or binary, belong on a file system or object store like AWS S3. Structured data should be stored in a database. Sensitive information, such as passwords, belongs in a secrets manager. Documents that are going to be edited by nontechnical users should be stored in a document repository.

But everything else, all the source code and build scripts, all the infrastructure setup and developer documentation, all the CSS files and SQL scripts—all this should be kept in a version control system. The code and supporting files that need to be processed to build your application should be stored in version control .

Sincerely,

Dan

Text editors

Dear new developer,

The raw “stuff” of software is usually text files. Well, to be honest, the foundation of software is ideas and insight, but unfortunately, a server can’t yet run on those. So, you must create text files.

One straightforward way to do that is to use a piece of software called a text editor. This program is designed solely to manipulate text. If you have used TextEdit on a Mac or Notepad on a Windows PC, you have used a text editor.

Why a text editor rather than an integrated development environment (also called an IDE)? An IDE combines a text editor with tools that perform other development functions such as testing and debugging. Text editors can be used for any language, whereas IDEs focus on one or a few. Text editors can run almost anywhere, whereas IDEs usually run on your local development computer. Using a text editor will also help you to become more familiar with the command line. In the end, text editors are more flexible than IDEs.

For those reasons, it’s better to start with a text editor than an IDE. There are many options. Two good ones, with long lineages, a cost of zero dollars, and copious functionality, are vi and emacs. But there are plenty of other options. Most text editors are extendable, and you can plug in features such as syntax highlighting, which lets you know when you misspell a language keyword; it’s worth spending time researching and installing such extensions.

What if you learn the wrong text editor? “What if I learn the wrong XYZ?” is a question you’ll face many times as a developer. Since you don’t know the future, you’re always gambling when you invest your time to learn anything. But every time you learn one tool or technology, you will have more context and understanding about that class of tools or technologies. For example, learning vi will make it easier to pick up the next text editor, map its functionality to what you know, and become productive. You also learn the jargon around the technology or tool, which makes it far easier to use a search engine to solve problems.

Text editors are easy to learn, but difficult to master. Opening a file, typing text, and saving the file shouldn’t take long to learn. But to be able to easily navigate between files, move around within a file, or do a mass search and replace, you’re going to have to put in some effort.

There is no more widely available, widely applicable way to convert thoughts into files than a text editor .

Sincerely,

Dan

IDEs

Dear new developer,

Just as you should learn a text editor, you should learn an integrated development environment (IDE) . This is a stand-alone program which helps you write code in one or more languages. They typically range in cost from free to a couple of hundred bucks.

Wait, didn’t I tell you that a text editor was superior to an IDE?

Context is crucial. If you are writing Java code on your laptop, using an IDE will be a superior experience. If you are editing and recompiling Java files to rebuild jar files in order to debug a production issue on the server—an unpleasant experience I have done more than once—a text editor is better. Using an IDE when you need to modify files on a remote server will require syncing files between the server and your development environment.

Using an IDE will give you the following benefits:
  • It will be easier to navigate a project. IDEs usually have a tree view of the entire project. If you are not familiar with the command line, having this view will make it easier for you to see how the project fits together. If the language supports it, an IDE can provide powerful searching capabilities allowing you to see where a function, method, or class is referenced.

  • Often these programs have refactoring support. Refactoring allows you to rename files, variables, functions, and methods. If the language or IDE supports it, all references to the renamed entity can be updated as well. This lets you rename parts of your codebase when their purpose changes and be confident you aren’t breaking anything.

  • IDEs have integrated debugging and code inspection capabilities. You can walk through code running locally and see the values of variables. You can call functions. You can also, if the language supports it, connect to remote servers and examine the state of a program running there.

  • The IDE can provide text manipulation beyond refactoring. For instance, if you want to add a documentation section to every method or generate boilerplate functions, most IDEs let you do this with a couple of keystrokes.

  • An IDE can make it easier to learn a language or framework. If you are not sure of the exact name or syntax of a library call, an IDE can suggest it. This suggestion is usually based on the first few letters you type. The system documentation can be displayed at the same time. For example, if you are using an IDE for Java development, you can usually see documentation for a method by mousing over it.

As you see in the preceding list, an IDE is a powerful way to interact with a codebase. It is also tied to a language’s features. If you are using a dynamically typed language such as PHP or Ruby, your IDE will have different capabilities than if you are using a statically typed language like C# or Java. But in either case, mastering your IDE will make it easier to write and debug code .

Sincerely,

Dan

The standard library

Dear new developer,

If you want to be good at interviews, learn your algorithms . Many companies use algorithm knowledge as a proxy for general problem-solving ability. If you squint, it makes a sort of sense—you have to break down a problem into pieces, turn each into a set of steps, and implement it in code. You can brush up on algorithms at places like HackerRank. Like any proxy, algorithm knowledge can be gamed, which is why tech interviewing feels like a fundamentally broken process. But I digress.

If you want to be good at your job, learn your standard library. This is the omnipresent set of functions or classes that your code can use to accomplish tasks while executing. You can use it for simple things, like a list to store variables, or for complex tasks such as generating a random number or encrypting data.

Every modern language has a definition (this includes syntax and keywords) and a set of associated, standardized classes or functions. These classes or functions allow developers to “stand on the shoulders of giants” and should be used whenever possible.

Why? These libraries evolve over time as the language improves. They have the following benefits:
  • Using the standard library lets you accelerate development. You don’t have to roll your own hash or binary tree, just use the one that ships with your library. You can be assured it’ll be available when your program executes.

  • Standard libraries have a lot of eyes on them looking for issues. This means that edge cases and security bugs are discovered without effort on your part. If the concerns are serious, they will be fixed quickly.

  • Any developer who joins your company is going to be more familiar with the standard library than they will be with any internal libraries. Using the standard library means new team members are more effective faster.

  • A standard library has many developers improving it. While it’s difficult to get exact numbers for such contributions, according to GitHub Golang has had over 1500 contributors to the project1 and PHP has had over 700.2 This leads to security and performance gains over time. And you’ll often get the benefits of these changes with a simple library upgrade.

In general, many more engineers work on and with standard libraries than work on the code in your company.

To get these benefits, you must know and use the standard library. However, unlike the syntax of a language, you don’t need to know it to get things done. While you can’t roll up your sleeves and start coding until you know the syntax of a language like Ruby, Haskell, or JavaScript, you can ship a lot of code without knowing the ins and outs of the standard library. You must make a conscious choice to utilize the standard library in your code to get the benefits.

Standard libraries can be large: Java has thousands of classes in its standard library. Even a language with a relatively small standard library such as JavaScript has approximately 70 objects, many with tens of properties or methods. These libraries take time to learn. Plus, new developer, it can feel like you’re not doing much when you are reading docs. Certainly, reading isn’t as fun as banging out code.

There are also large community-supported codebases augmenting standard libraries for many languages. Sometimes they are centralized, like CPAN (the Comprehensive Perl Archive Network) for Perl and CRAN (the Comprehensive R Archive Network) for R. Code from these sources share many aspects of the language’s standard library. It’s a good idea to evaluate these packages when you are building software. But be aware that there are wildly varying levels of support for community packages, ranging from very active to unmaintained. Make sure you understand the license granting you the use of packages and what that means if you use them.

If you read the standard library documentation and start using it in your code, there will be two benefits for your software:
  • You will save time in developing and your code will be better; see the reasons mentioned above. You’ll permanently raise your abilities in that language for the rest of your career.

  • You will write idiomatic code. Other developers who are familiar with the standard library will know the characteristics and behavior of the software you write.

and a large benefit for you and your career:
  • You will gain a transferable skill set. Learning how to use the custom Ruby libraries that your company created is not as valuable to other companies as your knowledge of the standard Ruby library.

How can you learn the standard library? I’d recommend taking a high-level overflight. Search for “<language> standard library overview” and get reading. I’d also recommend scanning the documentation and seeing what piques your interest—data structures, high-level flow control, or specialty functions. This overview is partly about you being aware of available options and partly about you learning the terms used so that you’ll be a better searcher.

After you have that overview, the best way to learn the standard library is to use it. When you confront a problem, check the standard library docs to see if it has already been solved. Make that a regular part of your development process; make a habit of asking yourself “Is there a standard library function for that?” Your code will improve. You’ll also learn when to venture beyond the library.

If you have time and inclination, you can also search for “<language> koans.” A programming koan is a small exercise problem in a certain language. These are great ways to practice and explore the standard library in a low-risk environment.

When “there is more than one way to do it” using a standard library, which happens more in some languages (like PHP) than in others (like Golang), evaluate options and then be consistent within your codebase.

Learn the standard library. Make the time.

Sincerely,

Dan

Automated testing

Dear new developer,

If you want to build great software systems, learn automated testing . Depending on your platform of choice, you may have built-in options, or you may need to investigate and select a testing framework. A test suite protects your code the same way Styrofoam peanuts protect the delicate contents of a shipped package. Sure, your code can still break, but it’s less likely to do so.

Automated tests are code and that means there is a maintenance cost. Both the infrastructure to execute the tests and the developer time spent keeping the test code up to date are expenses. I once worked on a project that had so many tests that any change to the code consisted mostly of updating the tests. However, test code doesn’t need to be the same quality as production code. Practices that are red flags in production code, like code duplication and unhandled exceptions, are more acceptable in test code; it is supporting infrastructure.

However, paying this cost has benefits. On that project with the abundance of tests, we knew when code changes broke the system. We regularly changed complicated logic knowing that if behavior changed, even of unlikely edge cases, the tests would flag it and let us know.

On a different project, I wrote many tests around a payment processing subsystem. Every time there was a bug, I wrote a test for it. Then I knew I’d never release that bug to my users again. That’s one of the biggest wins for testing: automated tests prevent regressions. It is not very much fun for anyone, user or developer, to have a bug fixed but then have it pop up six months down the line. Writing a test for every bug fix prevents this.

When you run them regularly, tests are living documentation. Set up continuous integration to do so. Such tests help new developers get up to speed on a project. The new developer can tweak a program and get instant feedback, rather than having to find the precise set of steps to take in an application to exercise that bit of code.

It takes a while to understand the right way to test. There are plenty of books to read. My experience is less theoretical and mostly “on the ground.” In my experience:
  • Unit test any logic that is complicated or subject to regular change.

  • Integration testing is great at making sure components work together.

  • Know what your language or framework provides and prefer that.

  • Use a continuous integration tool to run tests on every branch.

However, every codebase has different constraints. The most important thing is to start—don’t let the perfect be the enemy of the good.

I remember the moment I realized the value of automated testing. I was managing a team that, among other responsibilities, operated an ingest engine for real estate data. Releasing this software was a three-day process which included manually evaluating data in the staging and production databases to ensure no regressions occurred. We added testing into the process and were able to release in minutes with high confidence. It was a game changer.

Don’t try to test all user interfaces using automated testing. Instead, focus on the important ones. Automated testing of user interfaces is slow and often leads to breaking tests as the interface changes.

If you are beginning to implement automated testing, start with pure stateless business logic. Functions that do simple and stateless things like split strings are a great place to start, because you can easily write a unit test and make sure your code handles edge cases. For example, a string splitting function must handle null strings, empty strings, or strings with the delimiter missing. However, before you write any particular function, check your standard library to see if it’s already been implemented for you.

To repeat, just start. If you have a project with no testing, make the initial investment and write the first test, even if it is trivial: “Can I instantiate this object?” With that infrastructure in place, writing any other test is now easier. Force yourself to write tests even when you’re slinging a lot of code. It will help the future you, I promise .

Sincerely,

Dan

Network engineering

Allan Wintersieck is the CTO and cofounder of Devetry, a software consultancy in Denver that provides strategic partnership for software architecture and engineering.

Dear new developer,

I realize that just trying to learn basic programming principles can feel daunting enough, but if I may, I’d recommend adding one more task to your list: learn a little bit about network engineering.

Networking underpins everything web and app developers do, since almost every web app communicates from the front end to the back end regularly. Most developers understand the basics of making API calls and how data flows over the Internet, but taking a small dive deeper will help you debug issues for years to come.

The goal is to build your underlying knowledge so that when you encounter related issues in the future, you understand enough about how it all works to intelligently tackle the problem. For example, the reason everyone complains about CORS (Cross-Origin Resource Sharing) being confusing is because it doesn’t make sense without first understanding the basic principles of networking and security.

Here is a quick list to get you started:
  • Read up on the basics of routing. No need to dive into how the protocols work but understand why it’s set up this way and how Internet traffic gets to where it needs to go.

  • Read the basics of DNS and understand how a DNS request is resolved.

  • Read a brief rundown of the OSI model. Focus on understanding one or two examples of things you’ve dealt with in the past that exist at each layer.

  • Review the difference between TCP/IP and HTTP and why they exist at different layers in the model.

  • Read up on the basics of what a “proxy” is.

An overall analogy that I find helpful: Networking is like sending mail via the postal service .
  • Routing is the process of putting mail in your mailbox, having a postal worker pick it up, and it eventually reaching its destination.

  • DNS is the process of looking up someone’s mailing address so you can send them mail.

  • The OSI model is a fancy name for making it clear that there’s a lot of details the postal service takes care of for us. Most people understand how addresses and mailboxes work (let’s call that the equivalent to the Application layer), but don’t really understand all the internal details of how the postal service gets your mail to its destination. All those details are the first six layers of the model.

With that background knowledge in place, tackle some of these additional questions to lead you to more learning:
  • How do CDNs (Content Delivery Networks) work?

  • What’s the difference between “regular” HTTP and WebSockets?

  • How does SSL (HTTPS vs. HTTP) work, at a high level?

  • What can nginx be used for?

And as a last exercise, sketch out a complete picture of a work app or side project: what DNS calls get made, what servers are involved, are there any proxies, what protocols are in use, what OSI layer those protocols exist on, and so on.

I promise that spending the first few years of my career as a network engineer only slightly biases me toward learning this stuff .

Sincerely,

Allan Wintersieck

SQL

Dear new developer,

It’s a good idea to learn SQL, which stands for “Structured Query Language .” SQL lets you interact with relational databases. Relational databases are very good at storing a wide variety of types of data. These database systems are mature, well documented, and performant. They are easy to scale and operate. Sure, at the far edges of speed, scale, and functionality, there are other data store options, but in general you should reach for such solutions when a relational database falls short, not before.

You use SQL to retrieve or modify data by writing queries. These queries will pull or update specific rows of data, rows that match a certain set of parameters, or perhaps aggregate data across a query. For example, if you have table of orders, you could write a query to pull order #1, orders to be shipped today, or to find the sum of the value of all orders this month.

As a new developer, you don’t need to be a SQL expert. It is a mind-expanding way to interact with data. Instead of being procedural, object oriented, or functional like most programming languages, SQL is set based. I confess I’ve been using it for decades and still haven’t mastered it.

There are often frameworks that sit between you and the relational database your application uses for data storage, such as ActiveRecord for Rails, Hibernate for Java, or SQLAlchemy for Python. These frameworks make simple operations simpler. If you want to look a record up via an id or run a simple query, these tools make it a snap. But if you need to join across multiple tables or leverage database-specific functions, the abstraction often breaks down. This is where knowing SQL is useful.

There are also queries for which a framework is too slow. For example, if you wanted to sum a set of orders in a day to get a daily total, a naive framework would load all the data for the orders and then sum up the order value in memory, possibly using too much. A more sophisticated framework would generate SQL summing up the values. Unfortunately, it’s hard to know whether the framework you are using is naive or sophisticated without examining the SQL it generates. Dropping into SQL always works. However, you shouldn’t optimize for performance until you have found this to be a bottleneck.

Some systems or frameworks seem mysterious, but at the end of the day, the magic is built on code and data storage. By looking at the underlying data storage, you can understand what these frameworks take care of. For a long time, Rails migrations seemed magical to me. When I looked at the database, it became clear that Rails migrations were built on storing the date/time portion of the migration name in the schema_migrations table. Now, when Rails migrations are in a weird state, which happens sometimes when I run migrations, switch version control branches, and then rerun migrations, I can fix the issue by tweaking the underlying table. It’s good to be able to peel back the abstraction. SQL helps you do that.

To learn SQL, you can install a SQL database on your computer and play around with it. SQLite is the easiest system to install, but MySQL or PostgreSQL are more likely to be used in your day-to-day work. It’s also worth reading the reference documentation for your database of choice.

Some people have strong opinions on the type of SQL database they use, whether a commercial offering like SQL Server or Oracle or an open source solution like MySQL or PostgreSQL. As a new developer, you want to learn whatever your company is using. The difference between them when you are running basic queries isn’t much. The databases have larger differences in advanced SQL functions and performance and administration concerns. That’ll matter later in your career.

Sincerely,

Dan

Debuggers

Dear new developer,

When you are fixing a bug in a program , you must understand its state. A bug is any undesired or unexpected behavior in a program—the term comes from a moth which caused an issue in an early computer.3 This state includes user input, values from a persistent data store, and nondeterministic state like the current time. But the most important state is the in-memory representation of the code. What function or procedure is executing when the bug appears and what did all the variables look like at that moment?

Reproducing a problem with a test or replication sequence is the first step to solving the issue. Ensure that your debugging environment is as similar as possible to the environment in which the problem appears. I remember one program I was debugging which worked fine in development but failed miserably in production. The application used Google Web Toolkit, which compiled Java to JavaScript. When I compiled the application in development, the obfuscated variable names were different. That ended up being the root issue—there was a variable name collision between the compiled JavaScript and an incorrectly namespaced JavaScript variable. I tore my hair out and was reduced to putting in console.log statements on production to debug the issue.

That’s how a lot of debugging happens—printing out log statements to a file. You can solve many problems that way, it’s extremely portable and customizable, and it gives you at least some insight into program state.

However, a far better solution is to use a debugger. They’ve been around since the 1980s and give you more flexible insight into a program’s in-memory state than logging. You can see the value of any variable. You can run commands interactively. You can stop the flow of a program and restart it. If you pair an interactive debugger with an automated test, you have a tight feedback loop to help you zero in on the bug.

Most languages have interactive debuggers . In fact, that’s a way to decide which languages to avoid; a programming language without a debugger is likely to have other issues, such as a substandard dependency management system. Some languages have standard protocols which you can use to connect to remote servers. You run the debugger on your own system, but can examine the state from the remote server. If you ever need to debug a production issue, having this available is wonderful.

Debuggers are often integrated with an IDE, but some are run on the command line. Whatever your language, search for “<language> debugger” and find out more about this valuable tool .

Sincerely,

Dan

Benchmarking

Dear new developer,

Don’t worry about creating fast code until you need it. If you write code expressly to run quickly, you will write code that is hard to maintain. Err on the side of writing code that is easy to understand.

But there are times when performance really matters. When this is the case, reach for a benchmarking tool first, before you optimize anything. This will let you examine the performance characteristics of your code in a replicable way.

For instance, if you wanted to know whether it was faster to execute a function or a lambda in Ruby, you could use the code in Listing 4-4.
require 'benchmark'
def test_function(a,b)
  return a+b
end
my_lambda = lambda {|a,b| return a+b }
puts "testing function performance"
puts Benchmark.measure {
  50_000_000.times do
my_function(rand, rand)
  end
}
puts "testing lambda performance"
puts Benchmark.measure {
  50_000_000.times do
my_lambda.call(rand, rand)
  end
}
Listing 4-4

Benchmarking Ruby code

It doesn’t really matter what a lambda is in this case. What’s important is that this code runs two different, logically equivalent, code paths 50 million times. It then prints the execution duration. You can benchmark function executions, website page response time, database queries, or microservice calls.

Benchmarking provides concrete numbers reflecting how changes to your code affect run duration. This is crucial to making progress on performance issues. Whenever someone says “this is too slow,” reach for your benchmarking tools to quantify what “too slow” means. Then run them when you make changes to ensure you’re not making a bad problem worse.

Sincerely,

Dan

Search engines

Dear new developer,

Web search engines are important tools for building modern software. On the other hand, search engines are less useful for building foundational software knowledge, simply because you don’t know what to search for. Books, video classes, or side projects are better, depending on how you learn. Searching is tough if you don’t know what terms to use. Once you know a bit of software jargon, searching the Web lets you leverage the freely shared knowledge of others.

When searching, search for the exact error message (almost). When you get an error message like nginx_1 | 2019/01/06 20:42:22 [crit] 11#11: *1 connect() to unix:/var/run/php5-fpm.sock failed (13: Permission denied), don’t just cut and paste it into the search box. Examine the error message and see what in the error message is unique and what is common to all errors of this type. For the preceding error message, text like the nginx instance name, nginx_1, and the date and time are unique. Searching on them won’t be very useful. But the message text starting with connect() seems less unique. Searching on that string has a higher chance of yielding good results.

Read the results carefully, whether a blog post, Stack Overflow answer, or project documentation. I’ve been bitten by this more times than I care to remember. It’s easy when you find a result that seems to solve the issue to cut and paste the top answer and return to what you were doing before you were blocked. A better choice is to read the entire page or even multiple pages of results to make sure what you found solves your problem. Pick the best solution; this may not be the first one, especially if the first result is old. While newer releases often resolve existing problems, upgrading has its own risks. Read the release notes and make an informed choice.

Reviewing more than just the first result also builds your knowledge base. Doing a search should help you beyond simply answering your immediate question. You want to learn about the issue and solution in a broader context. This will help you incorporate what you’ve learned into your mental model. This means that next time you will know better what to search and may not need to search at all. You’re building foundational knowledge at the same time as you solve your immediate problem. Trying to understand various solutions and what they are doing is a way to do just-in-time learning. Mindlessly copying the solution isn’t.

Add links to what you find in your commits and code comments, especially if the solution is esoteric. Write a commit message that explains your intent, with the link providing additional context.

Think about the terms you use in the search query. Choosing the terms is where foundational knowledge of your problem space is critical. For example, if you know that ActiveRecord is an object-relational mapping tool, or that Ruby is a dynamic language where every class can change another, a procedure called “monkey patching,” then you know how to search for these concepts and related knowledge. If you want to change a specific ActiveRecord behavior, you might search for “how to monkeypatch active record” which will get you far more useful results than “how do I change the rails database access system.” This process is iterative. Pay attention to the terms used in helpful content and use them in new queries.

Finally, search engines work well because there’s information produced by people like you and me. You can take part in producing that content, either by asking or answering questions on Stack Overflow, writing a blog post, or responding to a forum post. If you encounter an issue no one has ever seen before, write up your solution. Participation in the wider Internet is crucial for its continuing usefulness. So, take part and give back .

Sincerely,

Dan

The keyboard

Dear new developer,

Software engineering is so much more than typing on a keyboard . Other things that matter include:
  • Knowing who to talk to

  • Determining what to build

  • Abstract ideas

  • Concrete details

  • Testing and documentation

  • Communicating progress

  • Course correcting when a project goes awry

These are all skills you need to be a great developer. However, knowing how to type quickly will make you a better developer too.

Touch typing is one way to do this; it is the ability to type without looking at the keyboard with all ten of your fingers. If you don’t have use of all your fingers or you use fewer, you can still type quickly, as a study from Aalto University found in 2016.4

Typing quickly is important because many forms of developer communication are text based, such as chat, email, or ticketing systems. Being a fast typer will allow you to write code more quickly as well. For the same reasons, you should learn keyboard shortcuts for your commonly used programs.

You can Google “practice touch typing” and find many places to improve your speed. There are also competitions like typeracer. I was lucky enough to learn to touch type in school, so I haven’t had to use any of these.

However!

If I had to choose between being a fast typer who didn’t understand a problem space or a slow typer who did, I’d pick the latter every time. Often, the best code is no code. Focus on understanding a problem first and then solving it.

That is to say, make sure your fast typing solves the correct problem .

Sincerely,

Dan

In conclusion

Part of your job as a software developer is keeping track of tools and the increased leverage they provide. You must balance between evaluating new tools to solve problems faster and chasing endlessly after newly released shiny languages, frameworks, or libraries.

However, software developers are lucky. Unlike many other professionals, our tools cost nothing to copy. This means that many tools are distributed at zero cost and require nothing more than an investment of time. Once you make the investment to learn a tool well, you’ll reap the benefits of increased productivity for the rest of your career.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.128.105