System Design Interviews
I personally find that system design interviews are a lot easier than coding interviews. Much of the skill sets are the same but the abstraction and level of detail is different. Instead of knowing the intimate details of the code logic, it's more important to know the intimate details of the interfaces you're creating and the trade offs you're making by choosing one tool over another.
I think system design interviews are easier as long as you have the requisite experience and knowledge. In other words, it's hard to know what you don't know, and if you haven't had experience with certain technology, you're at a disadvantage. From my recent interview experience, I've come up with a few tips for system design interviews.
Technical Interviews
I left my job at Smartcar about three months ago. In my time off, I've had the opportunity to interview at a variety of different tech companies, big and small, early stage startup to public company, health tech to financial tech.
I've noticed the interview process is different from when I was a new grad. More specifically, the technical interviews were much less focused on problem solving, efficient solutions, and algorithms and more on writing clean, testable code. I'm not sure if this is because I have enough industry experience where the expectation is that my algorithms and data structures knowledge is rusty, but this was a welcome change.
The medium has also changed. In the eight onsites that I had, I only coded on a whiteboard for one of them and this was because my laptop wifi wasn't behaving (Ubuntu on Mac problems). The rest of my interviews were pair programming on a computer, in an editor and language of my choice.
With the new format, here are a few tips that I've found helpful when interviewing.
Representing Regular Expressions as a Syntax Tree
In developing a chatbot, I recently became curious about generating regular expressions from a set of examples. I thought if I can acquire enough examples of a particular command, I could use regex to determine the intent of the message and any entities within the message and process the command. Creating a system that processes a set of strings and substrings to extract using regex was my first thought.
After a quick search on the internet, I found a few resources, which I'll link below that have more than extensively researched this topic. My goal for the following blog posts is to describe the steps I used to come up with my solution to this problem. I've quite barely scratched the surface in trying to solve this problem, and I'm aware that there may be better solutions, but I stumbled across one that I found particularly intriguing. This research paper describes a process for automatically generating regex from examples using genetic programming. With little more research in hand, I decided it would be a fun project to implement.
Continuous Deploy with GCP
It's amazing how much you take production continuous deploy for granted. I've been working on a side project with a friend and the beginnings of this project were quite hacked together. Our first prototype was a server deployed on GCP using screen
. Obviously, this wouldn't be sustainable as we want to move quickly deploying new features.
I decided it would be necessary to have continuous deploy built in, and what better of a time to learn how GCP works, when your friend works at Google. So, let's get to it!
What I've Learned Working with Continuous Deploy
My Experience
Before we dive in I'll briefly discuss my engineering background. Most of my experience comes from working with a small, ten person engineering team. Each engineer on the team has fewer than 3 years of experience, many fresh out of college. Our team works with two week sprints and everyone is a full stack engineer.
Software Development Life Cycle
I think before discussing any trade offs from using continuous deploy, we need to understand our software development life cycle and the responsibilities of an engineer:
- prioritize the feature or bug
- scope the size of the feature or bug
- plan and design the feature or bug fix
- implement the feature or fix locally and write unit and integration tests
- develop a test plan used by other engineers to manually test the changes
- conduct a code review (or a few) to catch bugs, fix styling, etc
- deploy the change to our staging infrastructure
- run the manual test plan
- make any changes from testing and repeat step 4-8, if necessary
- release the fix to production
- run the test plan on production to verify the behaviour
I think understanding the software life cycle process is fundamental in understanding the overhead imposed on individual engineers by continuous deploy.
iOS Dependency Management
I started developing an iOS app recently. It's come to my attention that there are two primary dependency management systems for iOS and they both have their own quirks. I thought I'd discuss what I've discovered about these different dependency managers and why I ended up using CocoaPods.
Before I started writing my app, I looked into dependency managers. I found that Carthage and CocoaPods are the predominant two. After a quick Google search, I learned that they have different design goals. Both have simplicity in mind, but make different facets of the system simple.
Mobile Ads Rant
I recently started developing iOS apps again, after about a four year break. Swift is fairly easy to learn and a nice change of pace from when I used to program in Objective-C. Also, not having to handle garbage collection seems to make the whole process just a bit easier. I have noticed, that ad integration is more difficult.
Four years ago, when I made my first iOS app, I simply looked at the Apple documentation for integrating iAds and was able to monetize my app. But, as of June 30, 2016, it seems that Apple will no longer be supporting the iAd App Network. This change means that iOS developers looking to monetize their apps need to look to third party advertising frameworks. This is fine, but I think the alternative, third party services, are almost more annoying to integrate than it's worth.