This August, I was extremely fortunate to join Flatiron as a new grad software engineer. The transition to my first full-time software engineering job out of college presented some unique challenges.
In college, I worked almost exclusively on self-contained projects with several partners, where we would all be present and responsible for coding the entire system from start to finish. Similarly, in most internships, I predominantly worked on independent projects. For both, I was typically present when every line of code was written.
In contrast, Flatiron’s code base exists to solve countless complex problems in oncology, with contributions from just under a hundred engineers. There was no way that I could have that same level of full-system knowledge and there was no way that I could wait until I had the entire code base in my head before contributing, unless I wanted to wait 6 months to start pushing code.
I found my lack of system-wide knowledge particularly troubling during the code review process. I was learning so much from peer-review of my code, but I felt limited in my ability to contribute when I was the one doing the reviewing. Sure I could spot syntactic errors or functions missing test coverage, but so could any linter or test coverage tool.
Fortunately, when I brought up this problem with my engineering manager Maayan Roth, I received some helpful advice. She encouraged me to treat code reviews like reading a story. Before, I would start at the top of the alphabetically organized files in the diff and read down throughout the changes. Essentially, that’s like opening a book to any page, and reading it, then flipping to another one at random, and wondering why the whole thing doesn’t make any sense. Her strategy revolved around finding the focal point of the changes in question, often by starting with the test cases, and then following the path into smaller and smaller subcomponents. When I find myself at a part of the story so small that I can only check syntax, I know the story is done. On the other hand, if I either cannot identify the beginning of the story or I cannot follow the story to its end, I already have a jumping off point to make suggestions that truly improve the quality of the code, not just how it’s formatted. Using this technique, my lack of comprehensive system knowledge could at times work to my advantage, as I could highlight ways things could be clearer and simpler for a newcomer. In contrast, developers more experienced in the system may be used to the complexity and it won’t trigger their radar.
Now that I had ideas for possible improvements in clarity and structure, I faced one final hurdle: sharing my opinions with my teammates effectively. The last thing in the world I wanted was to be the new person who comes in and says “change this, this, and this,” especially when I knew a lot of thought went into the code I was reviewing. Fortunately, within my first couple of weeks, I stumbled across Derek Prior’s talk on Implementing a Strong Code Review Culture. All of his advice is well-informed (and many of his suggestions for teams are already in place at Flatiron). Yet what I found particularly helpful was his advice on written communication. Derek notes how simply transitioning from phrasing a comment as a statement (i.e. “You should change x to y”) to phrasing it as a question (i.e. “What would you think about changing x to y?”) can have powerful effects. Strong statements can often make the author feel as if they must defend themselves, while questions start a discussion between the reviewer and reviewee that ultimately help both learn and collaborate on a solution.
Both Maayan and Derek’s advice really helped me in my first few months at Flatiron as a new engineer. I am tremendously grateful for their insights and for the countless other tips and tricks other members of the Flatiron team have shared with me as I make the transition from student to professional software engineer.