Skip Navigation

How proficient do you rate yourself in your most coded language?

Hi,

My question certainly stems from the imposter syndrome that I am living right now for no good reason, but when looking to resolve some issues for embedded C problems, I come across a lot of post from people that have a deep understanding of the language and how a mcu works at machine code level.

When I read these posts, I do understand what the author is saying, but it really makes me feel like I should know more about what's happening under the hood.

So my question is this : how do you rate yourself in your most used language? Do you understand the subtilities and the nuance of your language?

I know this doesn't necessarily makes me a bad firmware dev, but damn does it makes me feel like it when I read these posts.

I get that this is a subjective question without any good responses, but I'd be interested in hearing about different experiences in the hope of reducing my imposter syndrome.

Thanks

83 comments
  • I should know more about what's happening under the hood.

    You've just identified the most important skill of any software developer, IMO.

    The three most valuable topics I learned in college were OS design basics, assembly language, and algorithms. They're universal, and once you have a grasp on those, a lot off programming language specifics become fairly transparent.

    An area where those don't help are paradigm specifics: there's theory behind functional programming and OO programming which, if you don't understand, won't impeded you from writing in that language, but will almost certainly result in really bad code. And, depending on your focus, it can be necessary to have domain knowledge: financial, networking, graphics.

    But for what you're taking about, those three topics cover most of what you need to intuit how languages do what they do - and, especially C, because it's only slightly higher level than assembly.

    Assembly informs CPU architecture and operations. If you understand that, you mostly understand how CPUs work, as much as you need to to be a programmer.

    OS design informs how various hardware components interact, again, enough to understand what higher level languages are doing.

    Algorithms... well, you can derive algorithms from assembly, but a lot of smart people have already done a ton of work in the field, and it's silly to try to redo that work. And, units you're very special, you probably won't do as good a job as they've done.

    Once you have those, all languages are just syntactic sugar. Sure, the JVM has peculiarities in how its garbage collection works; you tend to learn that sort of stuff from experience. But a hash table is a hash table in any language, and they all have to deal with the same fundamental issues of hash tables: hashing, conflict resolution, and space allocation. There are no short cuts.

    • Any good resources you can share for/on each topic?

      • College.

        I'm one of those folks who believes not everyone needs a degree, and we need to do more to normalize and encourage people who have no interest in STEM fields to go to trade schools. However, I do firmly believe computer programming is a STEM field and is best served by getting a degree.

        There are certainly computer programming savants, but most people are not, and the next best thing is a good, solid higher education.

    • Thanks for the input, it will make me think about how to approach how to get the skills I need.

      I'd say I am decent with FreeRTOS which is pretty much just a scheduler with a few bells and whistles.

      I haven't used assembly in a long while, so I know where to look to understand all the instructions, but I can't tell right off the bat what a chunk of assembly code does.

      Algorithms, I am terrible at these because I rarely use them. I haven't worked in a big enough project where an algorithm is needed. I tend to work in finite state machine which is close to algorithms, but it's not quite it. And a big part of my job is interfacing peripheral chips for other to use.

      • Thanks for the input

        You're welcome!

        I haven't used assembly in a long while, so I know where to look to understand all the instructions, but I can't tell right off the bat what a chunk of assembly code does.

        Oh, me neither. And that's not what I think is necessary; what's important is that you can generally imagine the sorts of operations which are going on under the hood for any given line of code. That there's no magic "generate a hash for a string" CPU operation, and that, ultimately, something is going to be iterating over a series of memory locations and performing several math operations on each to produce a numeric output. I think this awareness is enormously valuable in developers, and helps them think about the code they're writing in a certain way, and usually in a way that improves their code.

        Algorithms, I am terrible at these because I rarely use them.

        You use them all the time! Anything longer than a single operation is an algorithm.

        Nobody is going to ask you to write a search function; however, being aware of Big-O notation, and being able to reason about time and space complexity, is important. On the backbend, it's critical. It's important if you're a front end developer - I blame the whole NodeJS library fiasco on not enough awareness of dependency complexity by a majority of JS developers.

        I tend to work in finite state machine which is close to algorithms, but it's not quite it.

        I'd absolutely call FSM work "algorithms", and it sounds as if the projects you're working on is where these fundamentals are most important. Interfaces between hardware components? It's the most fraught topic in CIS! So. Many. Pitfalls. Shit, you probably have to worry about clock speeds and communication sheer; there's absolutely a huge corpus of material about algorithms for handling stuff you're working with, like vector clocks. That's a fabulous, interesting field. It's also super tedious, and requires huge attention to detail which I lack, so in a way I envy you, but an also glad I'm not you.

  • I am very proficient in my primary language, C#.

    Writing more context out feels like boasting, so I think I will skip that and go to a summation/conclusion directly.

    Knowledge and expertise comes from more than the language. Which you hinted at. The language is only our interface. How is the language represented, how will it transform the code, how will it be run. There's a lot of depth in there - much more than there is in the language itself.

    I learned a lot, through my own studies and reading, studying, projects, and experience. I'm a strong systematic thinker. It all helps me in interpreting and thinking about wide- and depth- context and concerns. I also think my strengths come at the cost of other things, at least in my particular case.

    You're not alone. Most developers do not have the depth or wide knowledge. And most [consequently] struggle to or are oblivious to many concerns and opportunities, and to intuitively or quickly understand and follow such information.

    Which does not necessarily mean they're not productive or useful.

  • I would give myself a solid 4.2/5 on python.

    • I have in deepth knowledge of more than a few popular libraries including flask, django, marshmallow, typer, sqlalchemy, pandas, numpy, and many more.
    • I have authored a few libraries.
    • I have been keeping up with PEPs, and sometimes offered my feedback.
    • I have knowledge of the internals of development tooling, including mypy, pylint, black, and a pycharm plugin I have created.

    I wouldn't give myself a 5/5 since I would consider that an attainable level of expertise, with maybe a few expections around the globe. IMO the fun part of being really good at something is that you understand there still is to learn ❤️

  • I don’t think your question relates to the language as much as to the platform. The language of choice is somewhat irrelevant and what you care about is what actually happens under the hood.

    For the likes of java and go you want to have some understanding of what runtime does for the memory allocations and how their GCs work. For python you sometimes end up in the spots where you need to understand what limitations the GIL imposes (even more important now that they are trying to get rid of it). When you run C (or C++ or Rust) on the embedded hardware it really helps to understand what exactly bit flipping does in specific registers and what DMA means for how you write your code.

    You don’t really have to know it all. You can absolutely write code without caring about anything of that and I know plenty software engineers that do. Some people write amazing functional things in java without ever questioning what it does to the machines and what resources you need to run it.

    If you start questioning it, that will only expand your understanding. It's not a lateral move from e.g. C to Rust where you need to learn a lot to write your code in a memory-safe way, it's a movement deeper into the stack and what you learn there will be applicable to any language you use for this stack.

    Answering your question: I always feel bad about not understanding some low-level concept. I have stacks of MCU reference docs lying around, printed, highlighted; I have archives with sample code, and hand-annotated CMSIS reversing notes. Embedded world is hard because you can’t just know C and be done with it. You have to know the hardware, too.

    Here's my advice for you. Make notes of things that you learn from people smarter than you. Create a web of those notes and see where your gaps are. Then, work on learning something in those gaps in particular and see if you can make a blog post or something of your own. When you share what you learn you become one of those people with deep understanding that others look up to. There's always someone struggling with something that you either know or know how to figure it out.

  • I have no fear of implementing anything I'm asked to in typescript go rust java c# f# or nix... They're all the same tool just kinda different in some places.

  • Being proficient isn't about getting something right the first time, it's about how easily you recognize something as wrong and knowing how to get the knowledge to fix it. Under that definition I rate myself 5/5 if I'm not trying to be humble or sorry about tiny details.

83 comments