I'll start with the thought I had which sparked this question:
I find junior devs often need guidance to help them understand that the abstraction they are comfortable with is, in fact, "just" an abstraction and is often shallower than they realize.
For example, in Ruby I usually pull in the HTTParty gem because the language's default support for HTTP request is kind of ugly and painful. However I find that more junior devs will come into a project with HTTParty and effectively think this is the only way to make an HTTP request unless guided otherwise.
I think this applies pretty generally: The library you got comfortable with becomes your idea of how things just are done in general and this is how to do it. This might afflict self-taught/bootcamp devs more than people with CS backgrounds.
This is just an observation of mine, what are some other ideas?
I'm a professional Explainer-Of-Things-To-Other-Developers (Dev Advocate/Support) and I can't agree more.
I remember a Ruby talk at RailsConf several years ago where an audience member asked "Will this work in Rails, as well as in Ruby?".
The speaker was completely confused until it dawned on them that the person asking didn't realize that Rails is "just" Ruby. The questioner's abstraction went Rails-deep. That person might have been excellent at Rails! It just hadn't occurred to them to peel back the layers and see what's underneath.
The best way I've found around this is to encourage Juniors to read the libraries they're using, add debug messages, and draw diagrams of what they've discovered.
Not sure if it's common but the following is something I'm guilty of when I was junior: that every commit needs to be pushed to the repo 🙈
Now, I would commit BREAKING changes to the repo because I thought I had to commit and push my work at the end of the day regardless had I finished or not. It wasn't until the team decided to set some rules for commits, merges and deploys that I started to understand when/how to actually push my code (yes, they were created because of me 😂).
It really helped me understand the importance of a good established workflow in development ⭐
Just fyi, you should definitely commit and push changes even if they are breaking, you dont wanna be in that situation where you accidentally delete your local changes (trust me, it's gonna happen).
Just don't merge them, and once you can get to it, you can uncommit the last commit with breaking changes or ammend it once it's done.
It's just that we weren't using feature branches, we all worked and pushed to the same dev branch 🙈 A couple of years later, a new tech lead showed up and implemented a better branch workflow with MRs and git, we were using I think TFS.
I should've explained that a bit better in my initial comments, sorry!!
Ah well, I forgot to explain it in my initial comment but in this team we weren't using your conventional git flow/system/that. We all worked and pushed to the same branch, so one of the rules was that I had to create atomic commits, aka, all my 1000000 changes in one single descriptive commit that had to be something like "backlogid/bugid - description of change - my name", and this was all created to curve my chaos askldjlaksjd
It was really hard afterwards to adopt the small commits paradigms (every change is a commit), I still have a hard time to be honest, I tend to commit only when I feel like I've done something big enough for a commit. Commiting barebone code (something I've seen advised) just feels weird to me ;w;
So, what I would advise is to use a more conventional git flow(?) and descriptive commits (regardless of size). If you're in a team that doesn't have it, try to identify bottlenecks/issues/etc and then you might need to do a bit of research to propose a good flow that can handle these issues. In my current team we implemented the conventional git flow (feature branches, dev branch, main branch and release branches), but since most of the users making the changes have little software experience and they need the changes NOW or else the sky will fall (and it will!), I sorta realized a trunk based approach with MRs would've been so much better than git flow, it actually evolved to just that 😂
tldr; Every team and project is different and you'll probably need to talk to your teammates and come up with guidelines together! :3
Hope this helps if not please let me know and I'll try to explain myself better because I'm not the best ✨
Universally, junior devs I've met need a lot of help with two things: 1) Where to find the right article, SO question, documentation, etc that addresses the problem at hand and 2) how to look for the problem in the first place - where in the code is the error coming from? What impact could you observe depending on different logical branches?
I sum both of these under "how to look for stuff". Observation, exploration, search.
I find often it's things like "If this part of the code works, there will be an entry in the database. Do you know that it even gets this far, or does it break somewhere else? You'll find the problem much more easily if you can whittle down which side effects do and don't happen." Or "have you tried debugging the save call to go back the stack trace for where the erroneous save is triggered?". Or "Have you pasted the error message into Google? What are the common causes? Do any of them apply to our case?"
French software engineer with 15 year experience on 3D data visualisation and processing. Lots of C++, and switch to Unity recently.
I like when it run fast 😉
Getting s**t done and don't drown into the endless improvement you can do to your code.
Perfect code doesn't exist, and you can spend your whole life refactoring again and again your code. The point is, you should not stop when the code is clean, you should stop when the code is good enough. Refactoring always leads to a Brownian motion, where you just go around in circles without moving forward. As long as you go forward, you can refactor, but it requires a minimum experience to feel when you just turn around without improving anything. And too much refactoring often leads to over design and more complicated code.
Web Dev full-stack [LAMP] since 2005, but much heavier on the JS stuff these days.
Jack of all Stacks, Master of some.
Always looking to learn new things. Always glad to help out, just ask.
Location
Atlanta, GA
Education
B.S. in Biochemistry 2004, M.S. in Computer Information Systems 2007
"abstraction" - holy hell it's hard those first few weeks coding to grasp that "something" can be separated into many "somethings" that combine to make the original "something". Until you grasp this, understanding objects and arrays is hard though i found arrays much easier than objects for a long time. I don't even know how i learned this stuff, but one day it just clicked finally, i think i had been coding like 2 years by then.
"recursion" - again, this is so confusing when you first encounter it because you have to be able to run the code in your mind, seeing it as it progresses through itself and "calls" itself again. While(true) and infinite for loops are hard to grasp and we all break things with them at some point.
"ask a dev" - so many newbies just dont' ask enough questions. They think they bother others by doing so, but in reality when a newbie asks you a question they help you retrain yourself on that information so the more newbie questions you answer the better a dev you can be. No one should work on a problem for more than 30 mins without asking someone more senior about it. A senior dev will spot the problem in 5 minutes or else in another 30 you add another seniorer dev and repeat. No problem goes unsolved for more than 2 hours this way.
"tabs over spaces" - it hurts my heart to see so many who just never learn to understand that one key stroke and 1 byte beats 2|4 key strokes and 2|4 bytes ANY DAY.
That the work is 80-90% reading and probably less than 10% actually writing code. I find they don't read logs, error messages or stack traces. I've found this to be true of a lot of mid-level developers I've worked with as well.
I think more than anything, these are the things I put most effort into when developing less experienced programmers:
Reading a stack trace effectively.
Monitoring logs effectively.
Using common command line tools (git/grep/tail/et. al) effectively.
I'm not sure about concepts. People pick up on paradigms pretty quickly if you explain them within their perspective.
I think it's mostly the sheer number of new things at once when they start a job. In schools, university and courses, concepts are usually taught one by one. In a real job, it all works together simultaneously. You have to know your languages, your team's best practices, tests, git, etc. That's a lot.
The guidance aspect is to stay patient and encourage them to move forward.
Hello~ I am a software developer currently interested in game and web development, I like being organized and my code does not reflect that, but I do try!
Currently anxious about github committing/merging and working on projects with a team, the only experience I have is working on my own repos with a sprinkle of contributions to other ones. I'm not sure about other juniors, whether people generally expect them to have this be second-nature already.
I'm a coder who has worn a lot of hats, from individual contributor to lead engineer to "CTO" (yes, in quotes, make of that what you will!). I've a lot to learn and hopefully some to share as well.
Infinite recursion. At some point every newbie accidentally writes function a which calls a function b which then (insert arbitrary amount of other functions in the middle) calls function a again.
This is very confusing for newbies who don't know what they're looking at. I remember because I was stuck trying to debug this kind of problem for a whole day once, and eventually gave up and asked my mentor for help. He attached a debugger and instantly saw the infinite recursion by looking at the call stack.
Top comments (28)
I'll start with the thought I had which sparked this question:
I find junior devs often need guidance to help them understand that the abstraction they are comfortable with is, in fact, "just" an abstraction and is often shallower than they realize.
For example, in Ruby I usually pull in the
HTTParty
gem because the language's default support for HTTP request is kind of ugly and painful. However I find that more junior devs will come into a project with HTTParty and effectively think this is the only way to make an HTTP request unless guided otherwise.I think this applies pretty generally: The library you got comfortable with becomes your idea of how things just are done in general and this is how to do it. This might afflict self-taught/bootcamp devs more than people with CS backgrounds.
This is just an observation of mine, what are some other ideas?
I'm a professional Explainer-Of-Things-To-Other-Developers (Dev Advocate/Support) and I can't agree more.
I remember a Ruby talk at RailsConf several years ago where an audience member asked "Will this work in Rails, as well as in Ruby?".
The speaker was completely confused until it dawned on them that the person asking didn't realize that Rails is "just" Ruby. The questioner's abstraction went Rails-deep. That person might have been excellent at Rails! It just hadn't occurred to them to peel back the layers and see what's underneath.
The best way I've found around this is to encourage Juniors to read the libraries they're using, add debug messages, and draw diagrams of what they've discovered.
Not sure if it's common but the following is something I'm guilty of when I was junior: that every commit needs to be pushed to the repo 🙈
Now, I would commit BREAKING changes to the repo because I thought I had to commit and push my work at the end of the day regardless had I finished or not. It wasn't until the team decided to set some rules for commits, merges and deploys that I started to understand when/how to actually push my code (yes, they were created because of me 😂).
It really helped me understand the importance of a good established workflow in development ⭐
Just fyi, you should definitely commit and push changes even if they are breaking, you dont wanna be in that situation where you accidentally delete your local changes (trust me, it's gonna happen).
Just don't merge them, and once you can get to it, you can uncommit the last commit with breaking changes or ammend it once it's done.
ah no totally!
It's just that we weren't using feature branches, we all worked and pushed to the same dev branch 🙈 A couple of years later, a new tech lead showed up and implemented a better branch workflow with MRs and git, we were using I think TFS.
I should've explained that a bit better in my initial comments, sorry!!
Can you give those guidelines here for better commit and development workflow which your company adopted. Just want to know what points to consider
Ah well, I forgot to explain it in my initial comment but in this team we weren't using your conventional git flow/system/that. We all worked and pushed to the same branch, so one of the rules was that I had to create atomic commits, aka, all my 1000000 changes in one single descriptive commit that had to be something like "backlogid/bugid - description of change - my name", and this was all created to curve my chaos askldjlaksjd
It was really hard afterwards to adopt the small commits paradigms (every change is a commit), I still have a hard time to be honest, I tend to commit only when I feel like I've done something big enough for a commit. Commiting barebone code (something I've seen advised) just feels weird to me ;w;
So, what I would advise is to use a more conventional git flow(?) and descriptive commits (regardless of size). If you're in a team that doesn't have it, try to identify bottlenecks/issues/etc and then you might need to do a bit of research to propose a good flow that can handle these issues. In my current team we implemented the conventional git flow (feature branches, dev branch, main branch and release branches), but since most of the users making the changes have little software experience and they need the changes NOW or else the sky will fall (and it will!), I sorta realized a trunk based approach with MRs would've been so much better than git flow, it actually evolved to just that 😂
tldr; Every team and project is different and you'll probably need to talk to your teammates and come up with guidelines together! :3
Hope this helps if not please let me know and I'll try to explain myself better because I'm not the best ✨
How to look for stuff.
Universally, junior devs I've met need a lot of help with two things: 1) Where to find the right article, SO question, documentation, etc that addresses the problem at hand and 2) how to look for the problem in the first place - where in the code is the error coming from? What impact could you observe depending on different logical branches?
I sum both of these under "how to look for stuff". Observation, exploration, search.
The number of times I've found an answer by searching GitHub or
.node_modules
specifically...I find often it's things like "If this part of the code works, there will be an entry in the database. Do you know that it even gets this far, or does it break somewhere else? You'll find the problem much more easily if you can whittle down which side effects do and don't happen." Or "have you tried debugging the save call to go back the stack trace for where the erroneous save is triggered?". Or "Have you pasted the error message into Google? What are the common causes? Do any of them apply to our case?"
Getting s**t done and don't drown into the endless improvement you can do to your code.
Perfect code doesn't exist, and you can spend your whole life refactoring again and again your code. The point is, you should not stop when the code is clean, you should stop when the code is good enough. Refactoring always leads to a Brownian motion, where you just go around in circles without moving forward. As long as you go forward, you can refactor, but it requires a minimum experience to feel when you just turn around without improving anything. And too much refactoring often leads to over design and more complicated code.
this
"abstraction" - holy hell it's hard those first few weeks coding to grasp that "something" can be separated into many "somethings" that combine to make the original "something". Until you grasp this, understanding objects and arrays is hard though i found arrays much easier than objects for a long time. I don't even know how i learned this stuff, but one day it just clicked finally, i think i had been coding like 2 years by then.
"recursion" - again, this is so confusing when you first encounter it because you have to be able to run the code in your mind, seeing it as it progresses through itself and "calls" itself again. While(true) and infinite for loops are hard to grasp and we all break things with them at some point.
"ask a dev" - so many newbies just dont' ask enough questions. They think they bother others by doing so, but in reality when a newbie asks you a question they help you retrain yourself on that information so the more newbie questions you answer the better a dev you can be. No one should work on a problem for more than 30 mins without asking someone more senior about it. A senior dev will spot the problem in 5 minutes or else in another 30 you add another seniorer dev and repeat. No problem goes unsolved for more than 2 hours this way.
"tabs over spaces" - it hurts my heart to see so many who just never learn to understand that one key stroke and 1 byte beats 2|4 key strokes and 2|4 bytes ANY DAY.
That the work is 80-90% reading and probably less than 10% actually writing code. I find they don't read logs, error messages or stack traces. I've found this to be true of a lot of mid-level developers I've worked with as well.
I think more than anything, these are the things I put most effort into when developing less experienced programmers:
I'm not sure about concepts. People pick up on paradigms pretty quickly if you explain them within their perspective.
I think it's mostly the sheer number of new things at once when they start a job. In schools, university and courses, concepts are usually taught one by one. In a real job, it all works together simultaneously. You have to know your languages, your team's best practices, tests, git, etc. That's a lot.
The guidance aspect is to stay patient and encourage them to move forward.
Currently anxious about github committing/merging and working on projects with a team, the only experience I have is working on my own repos with a sprinkle of contributions to other ones. I'm not sure about other juniors, whether people generally expect them to have this be second-nature already.
Infinite recursion. At some point every newbie accidentally writes function
a
which calls a functionb
which then (insert arbitrary amount of other functions in the middle) calls functiona
again.This is very confusing for newbies who don't know what they're looking at. I remember because I was stuck trying to debug this kind of problem for a whole day once, and eventually gave up and asked my mentor for help. He attached a debugger and instantly saw the infinite recursion by looking at the call stack.