From The Challenges - Shell
Exploring the software engineering lessons we can learn from the solutions I've seen
Hi this is John with this week’s Coding Challenge.
🙏 Thank you for being one of the 75,419 software developers who have subscribed, I’m honoured to have you as a reader. 🎉
If there is a Coding Challenge you’d like to see, please let me know by replying to this email📧
Welcome To Coding Challenges - From The Challenges!
In this Coding Challenges “from the challenges” newsletter I’m sharing some of the common mistakes I see software engineers make when tackling the Coding Challenges.
I’m sharing both the mistakes people make and some thoughts on how you can you avoid making the same mistakes when taking on the coding challenges or when writing software professionally. Sometimes we have to make mistakes to learn from them, somethings we can learn from other people’s mistakes, then make our own new ones! 😀
Build A Redis Server Clone: Master Systems Programming Through Practice.
I’m running the Coding Challenges Live Redis course again starting February 17th. It is a live, instructor led, course that runs for two working weeks from February the 17th to the 28th. During the course you’ll implement from scratch a clone of the original Redis server and extend it to support the RESP2 protocol and some additional commands.
Coding Challenges Live - Building An Interpreter Course
Would you like to tackle building a programming language interpreter with a cohort of other software engineers - and me?
I’m building a two-week cohort-based course around a coding challenges On the course you’ll learn:
How the application is built - the data structures, algorithms, and architecture behind it.
How to tackle the project in stages - breaking it down into a series of steps and testing as you go.
How to collaborate with other software engineers - reviewing their code and offering feedback on their solutions.
If that sounds interesting, you can register your interest and provide feedback on what you’d like me to cover and the format of the course in the course survey here.
I’ll be offering a discount to everyone who fills out the survey.
Ok let’s get into the mistakes people made when building a shell….
Recapping The Shell Coding Challenge
In the build your own shell coding challenge the goal was to to write your own command line shell.
A shell is a program that exposes the operating system’s services to us, the user of the system. We’re going to focus on the command line versions, like sh, bash, zsh and others.
If You Enjoy Coding Challenges Here Are Three Ways You Can Help Support It
Refer a friend or colleague to the newsletter. 🙏
Sign up for a paid subscription - think of it as buying me a coffee ☕️ twice a month, with the bonus that you also get 20% off any of my courses.
Buy one of my courses that walk you through a Coding Challenge.
Five Common Mistakes Software Engineers Make Solving the Shell Coding Challenge
I’ve pulled together this list of common mistakes from the hundreds of submissions I’ve been sent privately and the many shared in the Coding Challenges Shared Solutions GitHub Repo.
Mistake 1 - Only Covering The Happy Path
Don’t forget to include error handling when you build software. A shell should be reliable, the user might run programs in it that crash, they might kill the program they’ve run, they might mistype the name and try to run a program that doesn’t exist.
Don’t just think about the happy path when building software.
Mistake 2 - Allocating Memory And Not Handling Overflow
I saw several solutions in C, a couple of which allocated buffers to read the command line input from the user and then didn’t handle the cases where the user enters too many characters, i.e.:
char* read_line() { int = 0; int bufsize = 512 char* buffer = malloc(sizeof(char) * bufsize); int c; while (true) { c = getchar(); buffer[position++] = c; if (c == '\\n') { buffer[position] = '\\0'; return buffer; } }
If the user provided more than 512 characters of input this would overflow. It can be handled by resizing the buffer, i.e.:
char* read_line() { int = 0; int bufsize = 512 char* buffer = malloc(sizeof(char) * bufsize); int c; while (true) { c = getchar(); buffer[position] = c; buffer++; if (position >= bufsize) { bufsize *= 2 buffer = realoc(buffer, bufsize) if (!buffer) { exit(EXIT_FAILURE) } } if (c == '\\n') { buffer[position] = '\\0'; return buffer; } }
Mistake 3 - Meaningful Comments
Comments should be meaningful. Don’t just rephrase the code, add value and explain why the code is the way it is. What problem is it solving and why is it solving it this way.
Comments like:
if (char == '\\n') { // Check for newline // Flush buffer flush(buffer)
Are adding no value and in long lived code can easy become stale and incorrect.
Mistake 4 - No README / Binaries In The Repo
This seems to be a mistake that I pick out over and over again.
A README in your repo doesn’t have to be long, but it should contain the basics of what tech stack is used, what the project does and how to use it.
I know a couple of tech stacks well and can work with several more, but some I haven’t touched for over a decade and some I’ve never used. It’s always a good idea to assume that your colleagues are like this, new members of your team might also be new to the tech stack you use.
An interviewer or hiring manager looking at your work / a take home task they’ve sent you might be new to it too.
It really helps if your repo makes it clear either what the tech stack is or how to clone, build (if applicable) and run the repo in clear simple steps. Those steps should not include or reference paths that exist only on your local machine.
Source code repos are for source code. Binaries do not belong in them. It should be possible to re-create the binary from the source code so there is no need for the binary. Equally it’s not obvious from a binary if the current binary is built from the current version of the code or an earlier one.
Mistake 5 - Skipping Parts Of The Coding Challenge
I’ve picked the steps carefully to focus on knowledge and skills that I believe are useful to most software engineers. While you don’t have to do all of the steps, skipping them because they’re hard deprives you of the chance to learn something new and grow your skillset.
Growth doesn’t happen in our comfort zone, it happens when we push ourselves out of it.
If you'd like help tackling this coding challenge I have a course available that guides you through it: Build Your Own Shell is available in Python and Go.
Request for Feedback
I’m writing these coding challenges and this new from the challenges series to help you develop your skills as a software engineer based on how I’ve approached my own personal learning and development.
What works for me, might not be the best way for you - so if you have suggestions for how I can make these challenges more useful to you and others, please get in touch and let me know. All feedback greatly appreciated.
You can reach me on Bluesky, LinkedIn or through SubStack
Thanks and happy coding!
John
P.S. If You Enjoy Coding Challenges Here Are Four Ways You Can Help Support It
Refer a friend or colleague to the newsletter. 🙏
Sign up for a paid subscription - think of it as buying me a coffee ☕️ twice a month, with the bonus that you also get 20% off any of my courses.
Buy one of my courses that walk you through a Coding Challenge.
Subscribe to the Coding Challenges YouTube channel!