
Ask HN: Do senior engineers have a mental model before coding? - unhired
I failed an onsite interview for a senior position because I didn’t have a mental model of the subtask before coding each function during a 90 minute pair programming test. I only used javascript in a text editor. I ran node in console after small changes and additions to print, test, debug.<p>The feedback was you can’t do this when compiling time is long and development will be slow. I’ve heard of developers that don’t use debuggers because they have a mental model in their head.<p>Do most senior software engineers take time to build a mental model before coding and testing?<p>I prefer to create a draft quickly to build a mental model. Is my way of logging to console frequently and coding before building a mental model a junior habit that I should work on?<p>Am I unlikely to pass a FAANG interview like this?<p>Edit: It wasn’t a LeetCode problem. I had to implement an API where each call would change the state of the application on certain conditions. I heard the problem and clarified it on the whiteboard. I coded each function while talking and ask for clarifications.
======
jrockway
Yes, I pretty much have a mental model of what I want to build before I build
it. I am not sure that I build the mental model in 30 minutes, though; rather
I get an idea, think about it over the course of many days, talk with people
about it, write down some design details, etc. Only after all of that does any
programming begin, and the actual coding is then the easy part. You know what
data structures you need. You know what the external API will look like. You
know how to deal with the tricky parts; be it integration or some sort of
unusually complex algorithm.

Doing the design work is what separates senior and non-senior engineers. The
more details you get worked out before they are solidified by having 10 other
systems depending on them, the better.

If you just do stuff with a rough idea of the direction you want to go in,
it's very easy to get sidetracked by something that doesn't matter. It's also
very easy to build something nobody wants. By having people agree on some sort
of semi-detailed design that describes assumptions, corner cases, the API,
etc... you dramatically increase your chances of building the computer program
that people want.

I am not sure how you test for this in an interview... but it is important. If
you don't design things before building them, that is something you should
start working on.

~~~
karmakaze
It's easy to test for in an interview. Just have them describe the solution to
you.. at a high level. If it can only be described at the code level, or as a
procedural description then there is no abstract model, only implementation.

Usually, I'll think about a problem, some of the inherent characteristics, or
desired behaviours then choose some applicable techniques/technologies,
languages, algorithms, libraries. Then think about how to compose the program
from parts to be developed. This all happens naturally without conscious
sequencing.

That's what's great about being current here, I find out about things I don't
need to use yet but could be useful at a later time. Or discover something
that would have made a past project better if I'd known of it.

------
paladin314159
FAANG interviews aside, I find the idea of having a mental model before you
write code extremely helpful. It's a lot easier to understand the purpose of
individual functions and how things should interface with each other if you
do. It won't be perfect at first, but the more you can get right in the first
stab the better.

Your ability to build that mental model depends on both your experience/skill
and the complexity of the problem. For simple problems, a more senior engineer
might be able to come up with a mental model instantly because it's similar to
lots of things they've done before. For really complex problems, it probably
takes everyone a long time to build the correct mental model and you'd want to
balance that with what you can figure out by diving into the implementation.

My guess would be that the interviewers' line of thinking is that if you
couldn't build a mental model for a problem quickly, that means you're not
proficient with problems like that. Which is probably true, but opens up the
question of whether the interview is testing the right type of problem, of
course.

~~~
bb88
> ...it probably takes everyone a long time to build the correct mental model

To be fair, 90% of most business logic is simple and straightforward, and
should be written that way.

The real test of a senior engineer is to quickly see the hard 10% that isn't
straightforward, and to design the rest of the system to minimize the effects
of the complexities introduced by the hard 10%.

------
squirrelicus
14 years in the industry, and I often describe typing the code as the easy
part of software engineering. Once I'm typing the code, I already know in
large part what code needs to be typed. The hard part was understanding the
problem model enough to know what code to type.

That being said, executing the code while typing it is critical. You cannot
build a mental model of all edge cases. At best, your personal discipline will
allow you have habits around preventing and catching edge cases. But you won't
find enough edge cases just by thinking about the code to type. You do have to
discover them by running the code, and the sooner you discover them, the
faster you will be at producing high quality code.

As far as how much time I spend building a mental model vs coding... It's at
least half mental model time. If I happen to predict enough edge cases, then
it might be 90% of the time. But the critical part is that I'm not done until
I've exhausted the edge cases I can imagine. If I discover sufficiently big
edge cases that brick my code, it's time to step away from the computer and
fix my broken mental model.

Note: tests are a way to do this, but so is white box poking and prodding at
your program in debug mode.

~~~
einpoklum
For me - it's sometimes like that, but sometimes it's the exact opposite: I
understand the problem through starting to code. Depends on the coding task;
also on the language.

~~~
squirrelicus
I'm sure everyone is different, but it's worth saying that I find myself
spending more time in the writing code phase with dynamically typed languages
than statically typed languages.

------
nomel
I don't think it's a good idea to start the implementation firmly planted in
the trees of the forest you're trying to see.

I think it's best to start with something like an outline. This could be
comments, tests, sparse pseudo-code, or some level of documentation that
explains what you're trying to do.

Once you have a rough idea of the pieces that are required and will roughly
fit together, understanding the consequences of the decisions you make while
implementing those pieces will come more naturally, and can help prevent
rework. Most architecture mistakes, and often bugs, are from not understanding
the consequences, which isn't really possible without having the mental model.

------
johnrob
Well, in the real world I find that you don’t understand the problem you want
to solve until you’ve applied a working solution to it. Practically speaking I
tend to deliver quickly to accelerate the process, then refactor once _all_
the requirements have been exposed. As mentioned here, this probably doesn’t
project well in an interview. It’s a case where the most efficient practice is
not the most presentable one. I’ve failed interviews for this reason too.
Lessons learned!

~~~
jconley
Same experience here. Been writing code for over 20 years. There's a reason we
don't do big Waterfall projects any more. No amount of research uncovers all
requirements. In the real world, with the ease of refactoring in powerful
IDE's these days, there is no reason to spend too much time thinking about a
small problem like those presented for whiteboard coding.

In practice, in an interview, this is the wrong approach. I've failed
interviews for this as well.

Most of what differentiates a Senior Engineer is communication, mentorship,
ability to compromise on product requirements, set realistic expectations,
design solutions to big problems, think in the large and hold the whole system
in their head, design API's, things like that.

I no longer do interviews that require me to write code. They're just
ridiculous for the type of skills I'd hope a company would value in a Senior
Engineer.

------
ohyes
I do not know about success in FAANG interviews.

This is just something that happens while I'm "thinking about how to approach
the problem." I have an idea of what a computer can do and (hopefully) what
the steps might be to solve the problem I'm trying to solve. I'll test out
some things in my head and then start typing.

I think different people are different, using a console that doesn't tell me
that you _didn 't_ have a mental model of how the program would work, it just
tells me that you like to test as you go. That's a good, careful, practice and
not a red flag to me at all.

read-eval-print loops are a time honored tradition in a number of communities.
I've written entire programs by typing into a REPL and dribbling the results
as I go. Languages with long compile times are genuinely unfun to work in.

So i guess my question for you, if you didn't have a mental model, how did you
know what to type into the console?

Also, if developers didn't need debuggers because of their mental model, why
are there bugs in the code that they are working on?

Mental models are necessarily imperfect.

Personally, I prefer your approach to writing a big huge chunk of code,
assuming it is perfect, and testing it at the very end only to find all of the
bugs.

------
Pfhreak
I usually sketch out what I'm going to write with comments and/or function
names. It gives me the sort of 'blocks' of how data is going to flow, where
responsibility is divided, etc. Then I go back in and fill the details of the
block. Five or six comments becomes five or six chunks of code.

I don't usually try to maintain an entire state in my head, but I do try to
make sure each of those blocks is something that I can reason about and hold
the entire state of. If I'm finding it hard to figure out what each block does
with data, I subdivide and write two comments.

For example, I might write something like:

// Iterate over every transform and do the matrix math

and realize that there's too much for me to hold mentally, so I'll do this:

// Iterate over every transform

// Invert each matrix

// Get the position vector

// Multiply by the character's scalar

... etc.

After that all scans, then I'll start writing the actual code.

~~~
ToFab123
I do exactly the same and it gives you a the added benefits, that you get a
bit of documentation of the code for free.

------
antiuniverse
_> I’ve heard of developers that don’t use debuggers because they have a
mental model in their head._

Having heard these claims myself, I firmly believe that developers who eschew
debuggers are either severely handicapping themselves out of misguided
bravado, or at best are too lazy to invest minimal learning time to establish
basic proficiency for huge reward. There's no reason not to avail yourself of
extremely powerful tools like that.

That said, maybe don't start with text-mode debuggers...

~~~
vegannet
I think it very much depends on the work you’re doing. My co-workers depend on
debuggers which are a crutch that allow them to _feel_ like they have control
over our spaghetti code — “it’s fine, I can step through!” — but the code I
produce (without a debugger but through TDD) is much more resilient. There’s
certainly engineering problems that benefit from a debugger but I think for
most modern work they’re not essential — and often a crutch.

~~~
james_s_tayler
While I don't think they are only ever used as a crutch, I'm starting to see
more and more how they definitely are an enabler of spaghetti code.

It's not even just spaghetti but things that are very obtuse too. I often need
a debugger whenever I see things in the code like if(variant.sourceId == null)
and then below is the large unnamed block of code that also doesn't give any
indication of what it implies. Because I have no idea what it implies, I have
no idea how the data got into that state, so it's like... What case triggers
this code?

I often wind up refactoring that stuff after computing an understanding of it.
It usually comes out significanty easier to read and not likely you require a
debugger to understand it.

So I that regard I think debuggers enable unnecessarily difficult to
understand code to hang around.

------
fergyfresh
In my experience its purely random if/when someone will care about that. You
just have to do a lot of interviews and if you're still coming up with near
optimal solutions in the allotted time you should be okay.

I also do not think Senior Engineers have better mental models of these code
trivia questions than Junior Engineers do on average. Seniors spend more time
on architecture and facilitating Juniors to be more productive so I dk.

I have never been in an interview where piecing out the problem solving and
debugging outside of whatever the IDE/editor of choice was frowned upon.

Maybe they just wanted to see you solve the solution in the pair programming
window and thought you were copy/pasting your solutions from someone that was
helping you off screen.

~~~
james_s_tayler
This.

Don't try to get the right answer. Try to get the right interviewer.

------
codingslave
FAANG interview is all about leetcode problems. Where your competition has
already extensively studied the problem sets. If you cant get it the first
time, and spend 15 minutes on bad solutions as you work through it, its a
rejection. FAANG wants you to show up with near optimal solutions.

~~~
bm1362
I went to a FAANG interview today without preparing and was asked 7 leetcoding
problems across 5 interviews. Even the behavioral one included a leetcode
problem.

Most interviewers seemed to give an easy problem followed by a medium/hard. I
think I succeeded, purely based on years of doing leetcode in the past and
having a job at another FAANG-like.

------
dboreham
Hmm. I think you did have a mental model. What they're really complaining
about is that you ran your code before it was complete, or at least before it
was more complete than they would prefer.

I'm going to say that the point about edit compile run cycle is valid, but
only in the context of a programming environment that actually has a long
cycle. They didn't ask you to use one of those. So ultimately they're wrong or
at least so uptight and annoying that you shouldn't go work for them.

------
mntmoss
I think your practices are fine - coding even a limited prototype reveals a
lot of unanswered questions in a mental model. Once you _have_ the model, you
can apply it in a theoretical sense, but in my experience it takes longer to
build one by not coding than it does by doing some coding, then some thinking.
The only limitation on prototyping is that it's difficult to communicate what
is being accomplished in the middle of the process, because you'll make
something that looks negligent or incomplete - it isn't trying to answer all
the concerns yet(that's what you do in production code).

------
iamwil
Depends. If I'm just sketching something in code, or I don't know what I'm
actually building, I'll write it out in code first.

However, if I'm designing a known thing, where I understand what it's suppose
to do; I usually devise a mental model of the thing I'm trying to build before
I start committing to code.

Also, having a mental model for the system that you're designing makes it
apparent whether someone else can pick up and understand your system.

I also don't really use a debugger. Not sure why though.

~~~
meowface
I've also never used a debugger. Python libraries like icecream
([https://github.com/gruns/icecream](https://github.com/gruns/icecream)) make
print debugging pretty nice. I wonder if I'm missing out, though. I use VS
Code a lot, and have been intending to see if I can fit its debugger into my
workflow.

~~~
morenoh149
I think you are missing out. Debuggers allow you to know the state of
variables at every line, not just the ones where you print debug. Debuggers
also allow you to set watch expressions and occasionally you step through
library code which begins helping you understand the source of your
dependencies.

~~~
iamwil
Usually debuggers take extra steps to set up, and I find it only helps for
code that's really hard to reason about. But the most time consuming thing is
just stepping through the code, and if it happen to go too far, I have to
start over from the top again.

I do like time-traveling debuggers though. Those give me something print
statements don't give, and it's really great to examine the state as the
application is progressing.

~~~
agustif
Just got this on a newsletter [https://github.com/oslabs-
beta/reactime](https://github.com/oslabs-beta/reactime)

------
codingdave
I tend to build out a mental model of the bigger blocks of a feature, but will
iterate on details as I code, just like you described. And I rarely run my
code through a debugger because with that mental model and some judicious
logging, I get the job done. But there are people who think coding in that way
is asinine, and shows I'm not experienced. Different folks work in different
ways.

But because of those differences, it may have been the right call to not move
forward with you. That is not a judgment against you. It is an acknowledgement
that you don't work the way they like to work, and may have had a hard time
melding into the existing team. Or it may have worked, but hiring managers try
to avoid risk where possible.

That is fine. Getting turned down for a job that you were perfectly capable of
doing is a reality in this industry. Find another place, try again.

------
peterhi
The problem with mental models is that they are domain specific. My domain is
sports data, solving problems is easy because I have 10 years of experience
and a cookbook of models (can we say patterns) to apply to any given problem

Good mental models == Lots of experience

I suspect that the senior that interviewed you would be out of his depth if he
moved into another domain. I definitely would. But then again having lots of
experience helps you identify the patterns - sorry models - quicker and
recognise the problems that you will need to guard against

"Building mental models" sounds like a deliberate cognitive act. To be honest
it is more like recognising which part of an existing system would best fit
the problem and what changes are need to be made to get a better fit

Which kinda makes it sound a lot less glamorous :)

Anyhow let me repeat:

Good mental models == Lots of experience

~~~
bradleyankrom
Just curious: which sport/industry are you working in?

~~~
peterhi
Data aggregation. Scores, stats and tv listings from multiple suppliers
covering almost all sports worldwide. As B2B for people who don't want the
hassle of doing it themselves

------
ebj73
Yes, it's important to develop a habit to plan ahead before coding. For
anything bigger than small scripts or utilities, you need to do this.

On the other hand, there's the eternal conflict between the waterfall model
and the iterative development model. The waterfall model dictates planning
(almost) everything ahead, while the iterative model says plan sufficiently
far ahead, then start coding, then take a break and re-evaluate, do some more
planning, do some more coding, rinse, repeat. I certainly prefer an iterative
model, and building prototypes, as you do. But even then, I'd say professional
development work is 90% planning ahead, and only 10% actual coding. Probably
even less.

------
nurettin
Yesterday I decided to write a simple log file watcher because customers
especially requested for a simple script with no dependencies on the target
machine. It had to detect any new logs that match the given pattern, too.

My plan was to detect new files and file modifications using two async tasks.
Whenever a new file arrives, open a stream and read. Whenever a file is
modified, find the previously opened stream and read. Every time I read, I
push it onto an async Queue which will be consumed by another async task. That
would emulate something similar to go channels. Multiple IO tasks, that sounds
like a job for async/await. This was my mental model before I coded a single
line.

After a few dozen minutes and a single confusing error (I forgot to pass the
asyncio loop into the queue and the sleep functions) it was done. I even made
it so that it would output the newly appended logs to the stdin of another
process or another file. That way I could decouple my log watcher from the
program that uses it.

I also opted for detecting file changes by using an async timed loop instead
of inotify which would both simplify coding and buffer the new data to reduce
read/write operations.

4-5 years ago, I would have experimented with code and tested different ways
of accomplishing the same thing. Rather than favoring code experimentation, I
had a product idea and implemented a minimal but complete example by reading
docs .

------
usgroup
If you’re saying you write code without knowing what you’re writing then yes
you should have a mental model.

It’s a lot easier to build in your head than to write code. You might go
through a dozen ways of doing something in your mind which would take an age
to do in code.

Further, writing code to produce a mental model is limiting because every line
you write naively commits you to fewer possibilities. You can be a lot more
revolutionary in your head at no added cost and without throwing away hours of
work.

------
zmj
Yes - it's essential for debugging.

Your mental model tells you that if the system is in a given state, and
receives a given input, what "should" happen. You can then look for evidence
whether those things happened and narrow down a bug.

It also works the other way. If, given this input, that happened, your mental
model tells you what the system state must have been. That can help you work
backwards to identify a bug that put the system into a bad state.

------
blihp
Building at least a minimal mental model takes me far less time than trying to
jump in and code something without one. When writing a trivial
method/function, it often takes only a fraction of a second[1], but having it
tells me if I'm on track to accomplish what I set out to. The mental model
helps you plan and course correct... without it, you're likely either
learning/exploring/doodling (which should help you build a mental model) or
flailing about. You can get by on smaller scale/solo projects without one but
it becomes an issue if you are expected to work in/with one more teams and or
larger scope/scale projects.

[1] It takes effort in the early years, but like anything else you work at it
does become second nature. I often don't consciously decide to build a mental
model for simple tasks... it just happens reflexively with minimal time and
virtually no effort. Now the model may be crap/wrong... but that's the value
if it: as soon as what you're doing/observing doesn't match the model, you
know you have a problem and need to course correct.

------
s_m_t
I think you probably should build a mental model. The way I see it the
code/compile/debug loop style of programming is a bit like a gradient descent.
You are probably going to fall into whatever solution pops up rather than
really thinking about what makes sense.

With that being said no one is smart enough to not use a debugger.

------
rraghur
For largish problems, a general idea of the key structures and abstractions..
what's desirable, what's not... It becomes hard to think of how certain parts
of the system mesh together... At that point, to avoid analysis paralysis, I
write the scaffolding and some tests to see how the API feels... Most often,
doing this clarifies stone assumptions that I was perhaps inadvertently making
and leaves me with a path forward (after moving things around a bit)

So definitely iterative..

Whenever I've tried to design completely, it's rarely worked well. What has
happened as I've grown older is that most parts of the system are orthogonal
to others and it's usually not very complicated to compose parts together. So
that leaves me with focusing on the core problem more up front and then
layering in the other needed (but known) parts

------
ilaksh
I think everyone has to have _some_ kind of "mental model" otherwise you
wouldn't be able to code anything except random keystrokes.

But next time just write some comments outlining what the function is supposed
to do.

Also take whatever rationalization people give for what they do with a grain
of salt. There are lots of reasons they might have picked someone else --
maybe there was a cheaper hire, or a prettier one, or you had bad breathe that
day.

But comments with an outline before you start typing real code should satisfy
most people's idea of having a mental model.

If you want to pass a FAANG interview with algorithmic/puzzle questions then
that's totally different than pair programming and you will probably want to
get a book specifically related to that or something. Like a book titled
"Cracking the Code Interview" or something.

------
ozzmotik
I'm not a senior engineer by any means, despite all the time I've devoted to
learning about CS and development in general; my main problem is that I just
don't code anymore. That being said, I always have found that it is better to
approach a problem with a model/plan in your head for how to implement your
solution.

It's fully possible to go in blind and just develop a solution iteratively,
and that methodology can be useful sometimes, especially when working with
something completely foreign. But if you can take the time to develop a model
in your mind of how it works, then all that's left is translating the details
of that model into code.

------
ChrisMarshallNY
I try to keep as much in my head as possible.

Stuff in my head is always easy to change, and I find I need to change
CONSTANTLY.

I create what I term a "napkin sketch," and try not to write down too much,
afterwards.

Documentation is a HEAVY "concrete galosh."

That said, it's often imperative to write stuff down; especially in a team.
It's just that every single thing you write down becomes tech debt.

I talk about that here: [https://medium.com/@ChrisMarshallNY/concrete-
galoshes-a5798a...](https://medium.com/@ChrisMarshallNY/concrete-
galoshes-a5798a55af2a)

------
TheOtherHobbes
Mental models are good. You should have them.

Don't expect them to be complete. You will _not_ be able to solve any non-
trivial problem without discovering edge cases, unexpected complications, and
misunderstandings that will only be revealed when you start to code.

I don't understand why anyone would believe that a mental model makes a
debugger unnecessary. An accurate mental model won't protect you from certain
kinds of implementation bugs, or from sneaky hard-to-spot typos that compile
but do the wrong thing - etc.

------
grumpy8
As an interviewer, I like when candidates explain how they're going to solve
the problem first. Either on the whiteboard, with comments or pseudo code.
It's easier for me to help and guide them when I know where they're going.
Some people prefer to start coding right away and, while I won't penalize them
for doing so, if they go in the wrong direction without explaining their
reasoning there's not much I can do to bring them back.

------
dbcfd
I'm lucky enough to have a memory/mind's eye where I can see the problem in my
head almost always. I also tend to take time to flush that out in my head
before I start coding, attempting to work through issues.

I'd like to think without having that, I'd take the time to put it in a day
book.

In interviews, I've typically tried to draw/write out the problem (especially
in terms of requirements) to help work through what I'm thinking.

------
paulddraper
A. It's pretty dumb to fail an live coding interview assignment for that
reason.

B. Yes, mental models are absolutely critical.

\---

A better interview assignment to test mental models would be to architect a
data model or system. No code, just concepts and relationships.

On meaningfully sized non-FizzBuzz problems, starting by banging out code is
like starting a vacation by getting in the car and driving. A better use of
time is upfront thinking about possible plans, pros, and cons.

------
ryan_w
I'm not even a senior engineer, but I always like to do planning and get an
idea of how I should go about a project before doing it.

It might take a while for me to come up with a design I like and it could bug
me for days, but once I come up with something, even if it isn't "proper", the
project moves along fast.

I always like to write on a whiteboard and draw out visual representations of
each component I would need

------
forze
I had the same problem when I began. To be fast you definitely shouldn't
compile during a testable part. It also messes with your working memory. Type
all the code of the task, then after it's 'complete', check everything to see
if you didn't miss something. THEN you compile. If the compiler gives some
errors that is the moment where you fix them one by one.

------
nitely
Well, I'm amazed they allowed you to run the code at all. In an interview you
are expected to test the code by going through it and write the state of the
program as you go (i.e comments about the state of some variables in each
iteration of some loop and stuff like that). The rest of the feedback is just
how they justify themselves.

------
kissgyorgy
I'm not sure how could you write anything if you don't think about the problem
before? I didn't like my last whiteboard interview because I just stare at the
screen for a long time before writing anything, and sometimes even the best
design decisions happen outside when I'm walking or under the shower.

------
arenaninja
Over the past year I've been relying on mental/written models especially when
writing something new. It's useful for communicating - in a team setting I can
communicate APIs to other team members before it's written and in interview
settings you can use to explain your trail of thought

------
pythonbase
While I don't consider myself as a senior engineer, I do try to create mental
models before coding. Also, in the code, I create the flow using comment
statements which can later be replaced with actual code.

I developed the habit of dry running my code when I started to learn code
using GW-BASIC, way back in time.

------
silverlake
Lisp and Smalltalk programmers worked this same way. You develop bits of code
incrementally to build up to a larger program. It’s a benefit of a REPL, which
is what you’re doing with print stmts. keep in mind interviews are mostly
random, most interviewers are terrible. Don’t let it get you down.

------
southphillyman
Maybe I misunderstand what you're talking about, but wouldn't this manifest
when you ask questions and talk about your approach?

Comunication while coding seems to be a big deal during interviews now so if
you just started coded after hearing the problem I could see that being a
negative.

~~~
unhired
It wasn’t a LeetCode problem. I had to implement an API where each call would
change the state of the application on certain conditions. I heard the problem
and clarified it on the whiteboard. I coded each function while talking and
ask for clarifications.

~~~
ju-st
The problem sounds like they wanted you to implement a state machine, and to
draw a state diagram before that.

------
jerzyt
I have to have a mental model before I touch the keyboard. It's probably wrong
on the first iteration, but without a mental model how would I know if the
code is doing what it's supposed to?

------
scelerat
The most useful coding tools I have are a pen and a pad of paper

------
codeprimate
I don't see how it's possible to code without a mental model. It's like
drawing something without "seeing" it.

That sounds really really hard.

~~~
unhired
In drawing, you see something and sketch before inking and coloring.

------
hydandata
Plans are worthless, but planning is essential.

------
tobinfricke
> Do most senior software engineers take time to build a mental model before
> coding and testing?

What's the alternative?

------
gHosts
I regard engineering as a daemon that will magically give me anything, from a
nice cuppa tea to a nuclear holocaust.

The daemon has a strong preference for nuclear holocaust.

The trick is to give it explicitly, concisely and precisely supply all the
information it needs, out of the infinity of possibilities, to make a nice
cuppa tea (preferably without creating a toxic waste problem).

I tend to construct my code.

I have the signatures of the functions at the boundary of the code visible,
and then I create the data structures to hold the information required.

Then I wired the boundaries to the data model and uncover... holes. Gaps.

So I assume then my daemon will magically grant me all I need to plug that
gap, so long as I tell it precisely what the gap is... and then test that what
I have so far is "tea-like" and not emitting gamma rays.

And then turn myself into the daemon to create those parts I needed to plug
the gaps.

So what is my mental model? A daemon with a preference for nuclear holocaust.

------
purple_ducks
Sometimes yes.

Sometimes no. That's when I do TDD.

~~~
kissgyorgy
You can only solve a problem with TDD well if you know EXACTLY what do you
want to implement before even starting with exact input-output.

~~~
purple_ducks
That's blatantly not true.

I use TDD to pick apart the problem bit by bit implementing the next (then
unknown) step in a very piece meal fashion.

edit: also, what kind of gatekeeping is

"You can only solve a problem with TDD well if you know EXACTLY what do you
want to implement".

The end result is the same: a set of covering tests & working code.

~~~
kissgyorgy
Kent Beck, Martin Fowler and David Heinemeier Hansson disagrees with you:
[https://martinfowler.com/articles/is-tdd-
dead/](https://martinfowler.com/articles/is-tdd-dead/)

~~~
purple_ducks
Wow slam dunk.

You really defeated my actual experience and proved your point on this one /s

------
fsloth
"Do most senior software engineers take time to build a mental model before
coding and testing?"

I don't know. It probably depends on the problem.

If I've written anything remotely similar before, I probably come in with a
history with the problem at hand and can at least guess what sort of solution
might work.

If I've never written anything remotely similar I just need to sketch a lot to
a paper, and try out things in code before I implement anything.

I don't know what the interview was actually like. But no one has been able to
verbalize exactly the specific behaviour of a good programmer. The best gauge
of good programmer is that they identify each other.

Now, this key factor also has a hidden catch. People are different! Nobody has
identified that there is only one true way of being a top performer.

So, when you are interviewing, the interviewer has a specific model in her
head ... of what a top performer is like to her.

But as far as I know, no one has done any research how many "top performer
archetypes" there are.

So, I would say it's intellectually faulty to say there is only one way of
being a senior contributor. Senior contributors output is gauged in
production.

On the other hand, the only way to find top performers is to ask for other top
performers to find them. And they are not necessarily expert psychologists,
they just know how they work, and maybe have some notion of what the
organization supports.

The interviewer might have had some archetype in their head that you did not
fit with, but could not exactly verbalize, so they tried to generate anything
resembling a reasonable rationalization for their intuition. So the actual
problem might not have been your "lack of mental model", but some other
unspecified lack of affinity with the specific way of working the interviewer
expected (reasonably or not).

So there might be ways to be awesome that are unfamiliar to the interviewer,
that they just don't understand.

On the other hand, they've likely seen what works in their organization and
what does not, and that feeds into their intuition as well.

So the best way to ace an interview at an organization, is to psychologically
match with the other top performers in the organization.

And the best way to suck at an interview is to be technically incompetent for
the seat they are hiring - in this case no psychological affinity is going to
help in the short term. But how to _think_ , or how exactly to solve
problems... that's a stretch to say there is only one way to do it. It sounds
to me at worst it will lead to groupthink and lack of innovation opportunities
due to cognitive monoculture.

Sorry, I don't actually know how to pass a FAANG interview or what you need
for it.

------
t-writescode
TL;DR: different people have different programming styles and you might not be
programming the way they expect you to; but that might not be the problem. The
problem might be that you're focusing on the part of the interview that the
interviewer doesn't care about and that makes it so that the interviewer gets
frustrated and doesn't see your skill.

\--

When I was younger, I got a chance to work on a game with a friend of mine. My
friend was an incredibly skilled programmer, probably one of the best
programmers who built things people used or could use, that I knew at the
time.

I was a competition programmer.

We were both learning HTML5 at the time, and we both took on the task in very
different ways. I believe we were writing Nibbles (Snake) or something like
it, as a learning exercise, each.

I learned the basics: arrays, function creation, etc, and then went really
fast at building the whole program without testing it, connecting all the
pieces together in ways that I assumed would work. In the programming
competitions I took part in, 3 people shared one computer, all doing different
problems at the same time, so most of us wrote our code on paper before we put
it in to the computer.

After my whole code for snake was written or at least as much as I wanted to
have for a prototype (it's been many years since we did this, so I don't
remember a lot), I started trying to run it. It didn't work, of course, or did
messy things, and so I spent a bunch of time going through and fixing the bugs
that were in my code.

My friend went a completely different approach. Of course I don't remember
specifics, but it was something like this:

* he got a pixel drawing in a canvas

* he got a pixel moving on the canvas

* he got apples appearing on a canvas

* he got a chain of pieces of the snake following

* he got collision working

Of course, this is probably not what actually happened; but, this is basically
what I remember about how he coded. He was very slow, methodical, and had a
step-by-step process of how the whole code would work.

In the end, I think he had his program working before I did and much better;
but, if you looked at just the start, you might assume he's not skilled.

\--

Let's fast forward to today and a different person.

I was talking directly to a senior engineer at my company the other day. Very
skilled, very, very skilled. We were talking about how we do things. It came
out that I design systems and draw pictures to get flow and layout down. I
like to work on weird, pie-in-the-sky, robust systems that tend to take a
drawing to figure out later, because they're powerful and do powerful things;
and, the goal of those systems tend to be to pre-emptively be ready for v-next
and handle all of the requirements as cleanly as possible, and future
requirements as cleanly as possible.

He greatly prefers to start hacking on a solution quickly and get something
building and then work in the nuance and ugly later, refactoring whole
sections over time to get a better and better solution.

When I remark on a dangerous test case or scenario area that I'm worried about
when it comes to the upcoming solution, he's always thought of that problem
area ahead of time, too; but, from what he tells me about how he works, he
starts hacking basically right away; and, I don't think he does the crazy
designs as his first version, either.

\--

I'm not sure where I'm going with this; but, I think I want to say that this:

> I ran node in console after small changes and additions to print, test,
> debug.

is not a sufficient reason to think you're not senior; but, this:

> I didn’t have a mental model of the subtask

might be. Please notice that I reduced what I said down to a very, very narrow
statement. If you eventually have a mental model, then I think you're fine
here.

\--

I'm going to add some more. This might be an interviewing problem, and I think
it may be important to get a feel for what sort of interview it is, even
asking them. If you're adding a bit, printing, testing, adding a bit,
printing, testing, you might be adding a bit to things that your testing
partner doesn't think matters. Did the interviewer expect the code to compile
and run proper tests? Or were they just trying to understand your thinking
process? If the interview only cares about your thinking process, then they
probably don't care if you don't write the code to get the substring you need
exactly right, or they might not care if you get rounding wrong, or output
formatting wrong, because that's not the part of the problem you're being
asked to solve.

You get better at this by interviewing more and practicing asking questions.

\--

You mention this:

> The feedback was you can’t do this when compiling time is long and
> development will be slow

While this is true, for most of the work I do, I could write a small program
on the side that tests the design I'm going for that compiles quickly and then
inject that code into the larger code base and test the rigging. Maybe that's
not how it is for the job you're looking at.

I've said a lot, I hope this helps.

~~~
meco
>the goal of those systems tend to be to pre-emptively be ready for v-next and
handle all of the requirements as cleanly as possible, and future requirements
as cleanly as possible.

>He greatly prefers to start hacking on a solution quickly and get something
building and then work in the nuance and ugly later, refactoring whole
sections over time to get a better and better solution.

I think you've articulated a dimension of programming that I've increasingly
been observing and discussing with other engineers.

Do you happen to know a name for (or any language to describe) this kind of
spectrum of problem solving where one end tends to pre-emptively encompass as
many edge cases and future versions as possible, while the other focuses
solely on the most obvious use case initially, adding in each edge case in
successive versions of a "working" product (where working is used very loosely
(i.e. single pixel on a screen is a "working" initial version))?

I definitely fall into the latter category, and find it very frustrating to
work with engineers who want to chat edge cases that are days, weeks, or even
months away from being relevant in my eyes. I would like to understand their
thinking and this space of meta-problem solving better, but I'm not really
sure what to call what we're talking about.

------
crimsonalucard
>I prefer to create a draft quickly to build a mental model. Is my way of
logging to console frequently and coding before building a mental model a
junior habit that I should work on?

There is absolutely nothing wrong with this. There is zero research that says
developing a mental model before a prototype is better (in fact research says
the opposite is true). If compile times are like an hour, probably don't want
to do this, but there are many languages where code to executable time is
seconds.

A lot of senior engineers may disagree well, that's unfortunate, because those
are the people interviewing you. They think they know better but there's
literally no evidence.

