Saturday, March 12, 2022

A Short List of Computer Science Textbooks

The Computer Science curriculum tends to be focused on teaching the theoretical basics. For many people who are new to the subject, it can be unclear how to get started, either as a student, transitioning into the tech field for a new career, or just for self-study.

For the career path, there can be specific bootcamps as well as very practical books on the subject. For the university path, those mostly consist of textbooks. This post provides a "short" list of the well-known textbooks on each subject as well as one free textbook for those who don't want to commit to buying an expensive textbook.

Following the list of free CS classes at OSSU, the books are presented with the free option first followed by the well-known textbooks roughly in order of difficulty.

Discrete Mathematics

Linear Algebra

Computer Architecture

Operating Systems

Networking

Analysis of Algorithms

Databases

Artificial Intelligence/Machine Learning

Computer Graphics

Complexity Theory

Compilers

Programming Languages

Computer Security

Special: Distributed Systems

While this subject isn't commonly taught at the undergraduate level, it's become common enough in industry that it gets a section here.

Special: Data Science and Machine Learning

Data Science and Machine Learning are relatively new fields. They have both become quite popular, so some free textbooks are listed here.

Friday, June 28, 2019

Getting Into the Proper Mindset for Technical Interviews

Most books that talk about the technical interview process have a lot of suggestions for how to properly prepare for the technical questions (aka Leetcoding) or the behavior questions (a la Amazon).  However, if you haven't had a lot of recent practice at interviewing or are relatively new to the interview process (e.g. new grads), then there's a lot of room for misunderstanding about how best to prepare mentally and emotionally for interview.

Listed below are a bunch of ways to look at the interview process.  None of these are guaranteed to work 100% for everyone, but try reading through them and pick out what you think works best for you.

The Interviewer POV

I have done interviewing at every company I've worked at and here is my process:
  • Read the resume for at least 15 minutes.  Look for interesting things to talk about, patterns in employment, potential strengths and weaknesses based on experience.  Make some notes about what to ask the candidate.
  • Get to the interview room on time.
  • Go in, introduce myself, and evaluate candidate's condition.  Always ask about water/food/bathroom.  If they seem nervous or tired, maybe start with casual conversation.  If not, start with the "hard" question (technical or system design) early so that we don't run out of time.
  • Always leave time at the end to answer questions.
  • Do the "hard sell" for immediately promising candidates (usually the top 5% or so).
  • Take continuous notes on my laptop.  I'm looking for some of the following traits:
    • Technical competence
    • Ability to recognize and solve problems
    • Clear communication ability
    • Enthusiasm for any specific technical subjects
Also, here's how my day can look: meeting, meeting, meeting, interview slot, meeting, meeting, short break to do some programming, meeting, code review, meeting.  As you can imagine, many engineers could have the same schedule.

So, what's the point of telling you all this?  Here's why:
  • Most interviewers will be understanding and conscientious--some will not be. For the latter group, realize they are not annoyed at you, they are just a bit harried from their entire day of running around.
  • For the conscientious ones, you can ask them questions about the company and likely get more honest answers.  You may still need to read between the lines, but you can get more insight about what working at that company might be like.
  • You're there to evaluate the company.  If you see nothing but nice and empathetic people, then it's likely the company has more of those people.  If you get nothing but rude interviewers, I'd consider it a red flag about the company.

Find the Right Mindset

There are lots of ways to approach the interview process. Here are some of the ones I've used for myself:

No One Wants You to Fail

Everyone doing the interview wants to find a good candidate.  Some people and places are going to be very picky--most will not be.

Make Your Explanations About Your Thought Process

Most interviewers do care about you getting the problem right.  However, what they really want is to find their next coworker--a peer.  If you just go to a whiteboard or laptop and just bang out a bunch of code, there's no interaction for them to judge.  If you explain your thought processes the entire way ("I'm choosing an array here because I can get it done faster", "I'm using a tree here so that searching will be faster", etc.) then it's much easier to understand where your strengths/weaknesses will be.

If they follow up with an enhancement to the problem, that's good. It may not be possible for you to solve.  If so, ask questions or explain what you do know  Good interviewers will give you a hint that may let you solve the problem.  This is not about you knowing everything--this is a back and forth interaction that gives the interviewer something to work with.

Treat Every Interviewer Like Your Peer

This is one of my favorite approaches.  If I plan on working at that company, everyone who interviews me will become my coworker.  In doing so, I try to treat everyone like a coworker I want to help out.  Sometimes, a coworker won't know about a particular part of the system or why the code is designed in a particular way and I have to explain it to them.  With that mindset, it's trivial for me to stay pleasant and explain what's going on with any technical problem.

Have Some Faith in the Interview Process

It's easy to go into an interview an think "if I don't do well here, it's all over".  Instead of taking such a nihilistic mindset, try to understand that most companies are looking for a few positive traits and being a bit conservative on any red flags.  Also, company cultures vary widely.  Sometimes you'll be a fit and sometimes you won't.

Looking at it another way, if a bunch of people who interview you don't think you'll be a good fit and the manager/director/VP overrides them and you join, would you really want to work with all those people who interviewed you?  Probably not.  Instead, going to a place where everyone is enthusiastic about you starting there is likely going to be a much better workplace experience for you.

Rejection is Not Always About You

Having been behind the scenes (phone screen, interviewing, talking to managers) of the interview process, getting rejected is not always about you.  Some scenarios that can happen:
  • Reorgs and budget cuts can radically alter what sort of personnel a company is looking for and can shift the number of types of job openings.
  • Good companies try to make sure that the team has enough bandwidth to onboard anyone new and mentor any new grads.  One senior engineer cannot do this for a dozen new grads.
  • Company politics can play a part.  If a manager liked you, but the director or VP had something else in mind or were having conflicts with the manager, the manager and interviewers can be overruled

Remember, You're there to Evaluate the Company

This does not mean you should be asking about work-life balance or being able to take vacation right away.  You should be evaluating for whatever cultural fit that might be there for you.  You should also be asking questions about productivity, the tech stack, and the actual job.  Sometimes, it's good to ask just to make sure that you're actually interviewing for the position you think you are.  Bad companies will sometimes pull a bait-and-switch job on you (e.g. giving you a manual QA job instead of a QA automation job).

LPT: Watch out for Behavioral Traps

Sometimes companies won't ask behavioral questions, but will instead test you directly.  If your interviewer randomly starts behaving belligerently, recognize that trap.  Do not get defensive and do not take the bait.  Here are some ways to avoid escalating:
  • Take this as a challenge to the design of your system or code.  Start off by saying something like "Let me see if there's another/better way of doing this" or "I think it can be done this way--give me a few minutes to think about it".  Then, do your best to explain why it's a solid design or about potential design pitfalls and why they won't happen in this scenario.  Say anything to keep the discussion about the technical topic at hand.
  • If they challenge more directly, analyze their proposal instead.  Calmly analyze the strengths and weaknesses of their approach and end with asking, "So that's what I can think of?  Did you still prefer approach A or approach B?"
If you see them immediate change behavior, it was a test.  If not, then maybe something you said is a pet peeve of the interviewer and you solved the problem anyway.



Thursday, June 27, 2019

Getting Started with Distributed Systems

In today's high-tech world, almost all software is online and can have billions of users.  Given today's state, it is important to understand the hows and whys of such systems.  Most people will use the term "distributed systems" or "system design".

Unlike most CS courses, there is no "one answer" to understanding distributed systems.  Such systems are always designed with a particular purpose in mind and the purpose often decides the design and tradeoffs.

What does this mean for learning distributed systems?
  • Teaching or understanding the subject much more complicated.  There is no one system to use as "the example" or as "the place to start learning".
  • Textbooks are often incomplete.  The system or purpose specific books only cover relevant topics and general books can end up too abstract or too theoretical.
  • Since there are no clear beginning and ending to learning, it can be difficult to tell when to start reading material covering the next level of difficulty.
Learning a technical subject is difficult enough.  With the above constraints, figuring out what to read or watch can be confusing.  I've curated some of the material that I think best covers this subject for a particular technical level.

For the Novice

Video: Distributed Systems in One Lesson by Tim Berglund
  • Big Data has become one of the big drivers of systems design. This book does a good job covering systems design from that approach.
  • Disclaimer: I have not read this book yet.
Articles: Base DS
  • Some good article providing an alternative perspective on the design patterns of distributed systems.

What Next?

So, maybe you've just gotten started or read up on distributed systems. Where do you go next?  There is no one right answer, but there are many resources available.  Try one or all of them and see what works best for you:
  • Read/watch something from the "Advanced" section below
  • Study a specific system.  You can find lots of information on the more popular distributed systems, like Hadoop.
  • Start contributing to an Open Source project

Intermediate to Advanced Resources

Hopefully, you know the best way you learn or know the restrictions you have on time to learn and the list of resources below can help you get further on your path to learning.

Textbooks

I haven't found a comprehensive textbook yet.  These are the best non-specialized textbooks I've found:
  • Synchronization Algorithms and Concurrent Programming, Gadi Taubenfield
  • Designing Distributed Systems, Brendan Burns
  • Distributed Systems: Principles and Paradigms, Andrew Tanenbaum & Maarten Van Steen
  • Principles of Distributed Database Systems, Third Edition, Tamer Ozsu, Patrick Valduriez
  • Guide to Reliable Distributed Systems, Kenneth Birman
  • Network Distributed Computing: Fitscapes and Fallacies by Max K. Goff

Conference Videos

Videos are nice.  They are usually around an hour and cover a specific subject of interest.  There are also times where a verbal explanation is much more clear than several pages of text.  Below is my list of conferences and the like that I think have a decent amount of videos covering distributed systems:

@Scale (Videos from 2016 and later) (YouTube videos from 2015 and earlier)
  • This is currently my favorite set of conferences.  There are several tracks of talks and you can almost always find something of interest.
  • USENIX hosts a lot of conferences.  For issues related to distributed systems, FAST, LISA, NSDI, and SRECon have the most relevant videos, 
Kafka Summit (2016-present)
GOTO Conferences 

General Articles

Cloud Design Patterns from Microsoft Azure docs
  • The "Challenges in Cloud Development" section is a good summary of real production distributed systems challenges and the patterns they list are a very nice alternative view of distributed systems.

The "Classics"

Once you have some good experience with distributed systems, you'll start to see common patterns in both the design and in the mistakes.  Some of the classic articles on the subject cover these succinctly, but hide many years of wisdom behind the truths.

Eight Fallacies of Distributed Computing
  • This is the first of the classics.  There are many good follow up articles that try to explain (1, 2) and disprove (1) these fallacies in better detail.


A List of Corporate Engineering Blogs About Scalability

If you're reading this post, then I'm assuming that you already have some interest, background, or experience with distributed systems.

In my opinion, by the time you've passed some threshold for understanding such systems, either direct coding experience (jobs or Open Source) or reading good corporate engineering blogs are the only things that will build on that knowledge.

Here are the corporate engineering blogs which I've found to contain the most interesting projects:

Discord: https://blog.discordapp.com/tagged/engineering

A Short List of Computer Science Textbooks

The Computer Science curriculum tends to be focused on teaching the theoretical basics. For many people who are new to the subject, it can b...