What computer science concepts should devs without a CS background prioritize learning?

ben profile image Ben Halpern Feb 07, 2017

markdown cheatsheet

My favorite non-CS computer science algorithms book is: Grokking Algorithms: An illustrated guide for programmers and other curious people.
It stays at a pretty high level, touches the major algorithms, and explains big O very well!
Grokking Algorithms

Most self taught colleagues I've worked with, and others as well, are missing skills in writing good clean code. If you write good code everything else will be much easier to fix later e.g. performance issues, bugs.

So I'd suggest reading "Clean Code" by Robert Bob Martin, he's not only fun to read and watch holding talks, but is good at explaining things so that they make sense.

the most important one - how to use Google effectively to find whatever you need for CS learning.

Some developers come from a Computer Science background. Others, like me, never studied Computer Science in an academic environment.

In my opinion, the three main things for developers without a Computer Science background to study are Data Structures, Algorithms, and Lambda Calculus. Why these three?

  1. Data Structures. These are the building blocks of data inside of a program. There are many different types of data structures, both simple and complex, and all of them have advantages and disadvantages (in terms of reading, writing, and space complexities). When a dev has to model a problem domain, he or she will first reach for the a data structure. It's good to know the pros and cons of different types of data structures and what they can offer in order to make the best choice for the problem domain. Understanding data structures will help a developer to solve problems quickly and efficiently using the right tools; in some cases, it will also give a better understanding of how data is mapped to computer memory.

  2. Algorithms. Computers are fast - very fast - but solving problems still takes time. Devs should understand algorithmic complexity, know the advantages and disadvantages of specific approaches, and cultivate the foresight to make algorithmic choices based on input and time. More importantly, devs should be able to identify problems which can be solved (trivially or non-trivially) versus problems that cannot be solved at all within a reasonable time period. Algorithms, in conjunction with Data Structures, are the meat and potatoes of our programs.

  3. Lambda Calculus. Modern languages have many design patterns - OOP, functional, declarative, and so on - but Lambda Calculus is a basic, simple model of computing that lends itself very well to any developer who wants to improve the way that they read, write, and understand code. Gaining an understanding of Lambda Calculus can allow a developer to think in terms of inputs and outputs, which lead to further inputs and further outputs. Understanding the compositional, functional style of Lambda Calc can make many problems much more accessible. With Data Structures and Algorithms, Lambda Calculus can elevate a developer to the next level.

Non-CS-major here. Got any suggested readings on algorithms or lambda calc?

Big O notation, an understanding of what algorithms are "expensive," and an understanding of what happens with "expensive" algorithms at large scales.

I second Big O notation and this whole idea. I didn't do an entire computer science degree, but I did some, and these concepts are what have stuck with me as considerations that come up a lot.

Time to write my Big O practical applications essay. Still need to fully understand it though. I read a great book about CS concepts written by someone who didn't have a CS degree. Not an ad but a good book.

bigmachine.io/products/the-imposte...

For some reason at my CS degree we hardly touched on Big O. Does anyone have some great resources for gaining a better understanding?

I know it is expensive and massive but I really think every developer should have a copy of CLRS. It is well organized, well written, and extremely thorough. In fact I was just paging through it today to review a few graph algorithms.

Besides data structures and algorithms, there is some math stuff that is surprising helpful. Calculus is fundamental to model a lot of real problems and to think in terms of velocity and aggregation. Linear algebra is pure computing: once you get to think in terms of matrices, a lot of very, very complex stuff becomes way simpler. Number Theory is fundamental for a lot of disciplines. But the most important math subject IMHO is Probability and Statistics: it permeates everything.

Besides that, the basic of networking and cryptography are very useful as well.

How to structure systems to support concurrency.
We are entering a major shift in industry where concurrency is going to become mandatory. Programming with shared data and interwoven state is going to cause massive loss of time and energy in the future.
The sooner we begin the shift toward a more stateless asynchronous programming methodology the better we will all be.

I'll toss a do-not in here: Sorting.

Sorting can be fun, and can produce some interesting visualizations, but the best for most situations is already built into your language, probably, and it likely goes by the name sort().

If you are a web developer: Databases. I took an intro to databases course in college and even at that pretty beginner level, I still use what I learned in that class every day. Technology stacks may change, but data isn't going anywhere.

Yes I strongly agree. I had worked with new self-taught web developers and database skills was the most glaring thing they needed to learn. Knowing how to design a database to write SQL queries that has good enough read and write performance, knowing ACID concepts, knowing when transactions are needed, knowing the differences between SQL and no-SQL databases and to pick the best one to use rather than the easiest to use. Database is one of the most important things a web developer should know.

Easily the most fundamental skill to have besides algorithms and data structures.

There are a lot of things to learn, But the most important IMHO should be Data Structures and algorithms.

With some basic knowledge about both, Writing code becomes less about "Let's get this to run / work." and more about "how efficient is this? / could i do this is a more efficient way?"

Naturally the search for efficient ways to do stuff will lead to some other important concepts like concurrency, caching etc

The bits and bytes of storage to know which data types are appropriate to use, avoid overflows, utilize resources efficiently, flags.

Recursion - although recursion usually has sub-optimal examples. I think a good exercise would be to emulate a SQL WHERE clause with objects.

Loops - looping backwards. Not getting stuck in a loop.

Basic array knowledge. They'll probably never use (or realize they're using) a stack, heap, linked list but more will use dictionaries, ordered and unordered collections. Don't bother with sorting algorithms. I don't think trees would be a priority.

Inheritance, encapsulation...

Know just enough to be able to decide how secure you need a crypto class to be for a specific use. Random() usually doesn't cut it.

DB Indexing, maybe, if that's what you're in to.

Stand-alone code.

At my current employer, I am one of the few people, if not the only person, with a computer science background. Yet almost everyone is a "coder". Some are writing Stata, some R, some Python, and I've heard rumors of a couple of web and db developers. They know far more math than I do and can Google the rest.

But what what they can't do is write stand-alone, automated code. One of the skills someone with a CS background must learn is how to write code that compiles and runs on someone else's machine. CS students have to submit source code that the professor will compile and run. The "but it works on my machine" refrain doesn't cut it in a CS class. Code has to run and run correctly under someone else's account, on someone else's machine, and maybe with different input data. That is a skill you can only get from a CS class, not Google, and not Coursera.

Things which proved helpful

I finished a Bachelor degree in Applied Computer Science about three years ago and am working as software developer since then. Those are the things which have proved most helpful from my studies:

  • The most important things were the internship period and Bachelor thesis which helped to gather practical experiences and blurred into my current occupation.
  • The practice of holding presentations and giving/receiving feedback. I have to do this regularly now.
  • Broad overview over software engineering topics. This provides some from of intuition for problem solving.
  • First experiences with Linux and network configuration. This is necessary now for getting a grip on the development infrastructure.
  • Exercises like implementing merge sort in C were helpful to strengthen the programming muscles. The same goes with the Operations Research module.
  • Finite-state machines are actually applicable. We are currently refactoring a module towards using this concept with the Spring State Machine.
  • Learning about different program modeling techniques. Sequence, class, nassi-shneiderman, and ER-diagrams proved useful.

Things I still want/need to learn

I think that aspiring developers should get comfortable with version control as early as possible in their careers.

Math and abstract computer science topics are often easiest to learn once you find an application for them. However, you can't experiment confidently with any major change to your code until you know the experiment won't destroy all your progress! I'm a fan of Git, but any modern VCS will allow you to time travel through your project's history and undo any change you later regret.

The ones that most likely will encounter in the near future, or has in the past.

If no order is decided you must follow the CS curriculum order because it has a sense and the concepts are bases on previous ones.

The most common are other data structures than arrays, like linked lists, and other algorithms for search and sort.

Other way to deep dive is to learn the internals of your language, though making better optimized code and learning about lower level CS, like how. Sort is implemented in your language.

Later edit:
Minimal algorithms and data structures
Good math classes at Khan academy: Algebra 1&2, trigonometry, statistics
Khan academy computer science

The Memory Hierarchy.

Too many times have I seen inexperienced programmers not take into account the memory hierarchy when writing their algorithms. Their algorithms end up being extremely slow in real situations with real data because of their inefficiencies. Especially algorithms that work on thousands of database records.

Dean, do you know some intermediate/advanced resources on this topic with real life examples?

  • Finite State Machines
  • Rewrite Systems and Reduction Systems
  • Lambda Calculus and the basics of Computability theory

and then basic data structures and algorithms

Glad you mentioned finite state machines. It's something that can make most applications we write (if not all of them) much more robust. Most developers unknowingly write half-baked versions of finite state machines (in the form of if/else if and switch statement spaghetti sprinkled all over the codebase) that are hard to understand cohesively.

I hear a lot of people shouting big O notation and I understand is relevance, however you can also explain the price you pay for certain algorithms and it's "expensive" without referring to big O, or log n, and etc. for example you could say this algorithm is efficient but if the length of a array Is n is a costly matter meaning this takes O(n) or in lamen terms a long process because of the length of the array and how long the process might take

Learn a bit of logic and work through some simple proofs (really do this with a pencil and paper). Type systems are strongly related to logics. Relational databases are cut-down logical inference engines with persistent storage thrown in for free. Almost every aspect of programming has been clarified since I learned logic.

Apart from the already cited topics, I would add system engineering ;-)
It might appear obsolete in this cloud/container area but it struck so often that software developer have no idea on the hardware powering their applications and thus on the many possible issues that could be fixed easily by taking it into account.

So system design to avoid looking only at the current code at hands and have thoughts on the system level.

However I do believe learning algorithms is a great tool to have a a developer or a software engineer in many cases. Because you would need to solve a problem in a very efficient amount of time or not in a coastly time. It's also henaces you probelm solving abilities and how you approach problems in a very efficient way. What I mean by efficient is how you determine weather the algorithm or process is not efficient or is the the fast way of doing it.

I guess that very much depends on what you are working on.

For example when I first started working with LINQ in C# I loved it. How on earth did they make that work?? So I watched some channel 9 videos (eg. Bart de Smet on 'Ana, Bind and Cata'). I did a course on functional programming @ edX. It no longer seems like magic to me. Not sure if that makes me a better developer, guess I just don't like to rely on magic :o)

If you write many sql queries (either directly or via an ORM), learn about b-trees and indexing. It will help you understand how to make efficient use of your database.

So to wrap it up, prioritize what's relevant to your part of the puzzle so you can reap the benefits.

Follow this link . This will be a good learning path for non-CS programmers
(I am also non-CS coder!!!)

Google's Technical Development Guide

From all the stuff I had to learn for my degree in computer science, in the real world the most valuable two topics turned out to be the courses about parallel programming and correctness of computer programs. The latter is pure theoretical knowledge, but the skills I have aquired there are an invaluable asset when it comes down to analysing buggy software. The first is really helpful when you have to live in an asynchronous, multi-process world. And who has not to nowadays.

Necessary, but clearly not sufficient.

Data Structures and Algorithms.

Data Structures for a basis of how individual parts of data can be modeled and managed in groups.

Algorithms, without doing into a 401 course, would help get into the mindset of seeing problems as a set of repeatable actions to accomplish a goal.

I'd recommend reading "Introduction to Algorithms" aka "the Cormen", twice at least.
Also, ACID as a concept, not only for "real" databases, but for storing all kinds of data, even in flat files, is important.

It's not a specific course, but taking CS courses help you learn abstract thinking and how to debug.

Agree with all comments about Algorithms and Data structures.
Would then add O/S Internals and Compiler fundamentals.
Then OOP, the UML and Patterns.
Then Agile .. Business Change .. Human Centred Design.

.. then takeover the world ! :)

Computer Science is a religion whose adherents worship many false gods.

Data Structure and algorithms + Design and analysis of algorithms

Start using any Linux desktop, if you r not going to be Windows/Microsoft developer, and you will learn everything else including CS concepts on your own..

I would say strong cohesion and low coupling, because if you have these two points your code will always look good and will be easy to re-use later and to maintain. Each class does a specific thing and does not need any other important class of the program for its definition.

layering and that what belongs to where. "how" i.e. algorithms, usually come next.

Cryptography, abstract data types, combinatorics.

I think Theory of Computation would be great to learn, so it would help a lot to understand the foundations of regular languages, automatas and so on. Even though they might not be directly applicable to a solution, will help to understand and think in another approaches to solve a problem.