Ask HN: What did I do so wrong in this coding interview
The day after the HR sent me an coding test that involved creating a simple memory game in JS with a tiny back end to store high scores. So I banged out this code as fast as possible, while trying to emphasis on maintainability and testability. I sent back the result as github repo:
https://github.com/m4nuC/memGame
Didn't hear back for a few days but eventually arrived a mail stating that "this code felt far short from a senior developer standards" and obviously didn't get the job. I know I cut a few corners, no unit testing, a couple of minor bug and obviously not a production ready app but I thought that would be enough to show that I knew how to build a web app without spending 2 days on it.
I couldn't manage to get any more info from them on what they meant by "falling far short of senior developer standards" So what in your opinion went so wrong about the code?
97 comments
[ 3.4 ms ] story [ 134 ms ] threadA lot of things come into play here. Often it is unclear expections. I have done coding tests where the requirement was to pull data from a dataset and cache it in memory. This requirement can be met in many ways. I chose the simplest one but the feedback I got was similar to what you got. It totally depends on where the reader of your code is in the evolutionary stage https://medium.com/@webseanhickey/the-evolution-of-a-softwar...
Reading code is harder than writing.
Is it possible that you misunderstood and they (a) wanted you to use a different language than PHP (perhaps because they're a Rails shop or something), or (b) wanted you to do this in pure JS, with e.g. localStorage?
Also, the block indentation/braces look deeply messed up on github, any idea what happened?
https://github.com/m4nuC/memGame/blob/master/app/controllers...
Combination of using spaces and tabs for indentation. Looks like it'd look fine with tab size set to 4, but it should of course only use one method of indentation.
The problem looks like it's on the frontend, mainly. It doesn't look like you're leveraging a framework (instead manually munging the DOM), which suggests unfamiliarity with modern framework-based frontend development flow (this may or may not be true).
Regarding the backend, it looks like mainly PHP framework copy-paste. I suspect if someone has a vendetta against PHP (I don't, but some do), that might be a black mark.
If I were to summarize this code, it looks like it was written by someone who can competently hack together a web app on their own, but doesn't have much experience with working on a modern dev team.
I have no idea if I'm right. Just offering an employer's perspective.
Certainly opening up write access to everyone isn't going to win you any points.
I've taken a look at your code and you do not appear to be senior-level material. You managed to turn a relatively small game into 40+ files and 15+ directories of mostly useless framework fluff just to make what appears to be a mostly-javascript game.
- Trying to review your code, I have to navigate a nested tree of framework php and nodejs includes to actually discover what the heck is going on. - Why do you need nodejs for development? That just introduces yet another framework to install and deal with packaging and deployment. Why not just stick to backbone or some other minimal framework tool in javascript? You're not even importing that much useful stuff to warrant using npm. - You're doing a lot of manual dom manipulation which looks sloppy - You've committed a minified css file
Maybe some of the code you wrote might be okay, but your choice of setup and prep for a project seems pretty junior. Get some experience working with veteran developers on more complex projects (i.e. not simple web dev).
In the future if you get something similar, you may want to ask what they're looking for (gathering requirements, you might say), and optimize accordingly. Ultimately, it may be completely unrelated, but I've had both kinds of coding tests, ones where I had an hour and had to cut corners as such, and ones where I had an entire weekend and was explicitly told to make it production quality, whatever I felt that entailed.
For a quick project I think you did a great job, BTW, though there should never be any need for sudo. That was the only decent feedback honestfeedback provided. The rest is BS.
tl;dr: I agree with the assessment that this doesn't look like the kind of code I'd expect of a senior developer.
The biggest issue from my POV is that you pull in a _lot_ of heavy-weight frameworks and implicit dependencies for what could be a really simple app. To actually examine the application logic of your submission, I have to flip through dozens of auto-generated PHP files, Javascript module wrappers, and empty directories.
Sometimes, calling yourself a "senior" engineer means doing less, not more. The layers of indirection, framework code, and build toolchain applied here make it harder to follow what your code is actually doing. Coupled with a lack of unit tests, it seems impossible to verify in any short amount of time that it actually works as promised.
Even with all that MVC goodness, the separation of concerns on the client isn't great. There's a mix of display logic and app state visible in lots of places. (IMHO game.js is the worst offender here, as the entire game state and DOM rendering are mixed pretty indiscriminately.)
Finally, asking a reviewer to run a bunch of code from an untrusted repo via 'sudo' is pretty much a giant red flag for me. A simple JS+PHP webapp shouldn't require me to do anything as root on my machine. (I'm also not familiar with Composer, but my brief skimming of the homepage, it seems like the whole point is to not require system-wide installation of dependencies, so the sudo bit is especially weird.)
It looks functional, and if you were interviewing specifically at a shop that used these frameworks and tools, it might not be so bad. If asked to review this without that context, though, I would give similar feedback to what you received.
Making things too abstract, too early, is usually a bad sign. In most cases, the most most specific and straight forward solution to a problem is the best one.
There's definitely cases where you're simplifying things by making them more abstract and reusable (but making something reusable before you need to reuse it is a waste of time) -- another good case is where you're using the principle of separation of concerns.
I think when I started developing I made everything very abstract, b/c all the books you read would also tell you that was a good thing.
It's not. Until you need to, at least.
Abstraction can be a great tool, but it comes with the cost of added indirection.
You want to aim for the sweet spot in the middle somewhere.
Remember, when you're looking for a job, you're not looking to create some build and forget application. You're going to be working as part of a team. Other people need to be able to maintain your code. For a problem that should be able to fit onto a single page, you don't want to have to browse through a 7 megabyte git repo with nearly 10,000 files in it.
An analogy might be if someone's trying to hire you as a carpenter. They ask you to build a cabinet to demonstrate your skill. You go and find a prefab house frame, an entire prefab plumbing system, and so on, and build the skeleton of a house. Within that, you build a reasonably functional cabinet, though it's kind of hard to judge the cabinet among the entire rest of the incomplete house. How do you think that's going to compare to someone who just went and build a cabinet, and spent the time getting it built really nicely, paid attention to the detail work, made sure the door hung true and opened and closed without squeaks?
Here are a few things that I note at a cursory glance; and notice that I haven't even gotten to the logic of the code, because all of these things are red flags that come up before I am even able to read it:
1. Checking in dependencies to Git. That's not how it you do it; dependencies should be handled by a separate package manager, in which you depend on the appropriate versions of packages. You should never check anything other than your own source code into Git.
2. Your commit messages. Commit messages in Git should follow the format of an email describing a patch. The first line should summarize what the commit does; the rest of the commit should contain a description of why you are doing it. See the following for an explanation of what good commit messages should look like. First from the Git source itself:
http://git.kernel.org/cgit/git/git.git/tree/Documentation/Su...
And then a much more in depth guide:
https://wiki.openstack.org/wiki/GitCommitMessages#Informatio...
3. Inappropriate use of frameworks. You included a lot of dependencies that are unnecessary for the problem at hand. Dependencies have real costs; every extra dependency is something that could break, could have a security bug, could be a pain to upgrade in the future. Now, that doesn't mean to never add dependencies; but do so with a certain amount of care.
4. Simple spelling and style errors. Tabs vs. spaces. Inconsistent spacing: "var _createCell = function( color, id ) {" and "if ( el.className.indexOf('turned-over') > -1)" (note: decide whether there are spaces between parens and their contents, and stick to that choice). You spelled "RESTful" as "restFul". Things like this are seen by developers as canaries in the coal mine; if you are sloppy about the very basic stuff like tabs vs. spaces, are you really going to be mindful of other important things? Consistency of style is important for keeping code readable, if you can't even keep consistent in a simple code interview problem, why should anyone think that you'll be able to do it on a day to day basis when under real deadline pressure?
Here's my exercise for you. If you want to get better, and be able to pass future job interviews, condense this down into as small a codebase as you can, with as few dependencies as possible. I think that you should be able to do this in less than 100 lines of your own code, and only the most basic...
@OP: You didn't commit the composer.lock. That means that your code might run locally but breaks on another machine because there might be a new version of laravel 4.2
What is the "right" amount of time/effort to put into a "job-application" project like this?
If you want to respond, respond to those items, not excuses <- denotes junior-level mentality.
Why the dummy account ?
I think the best way to get feedback on a rejected code sample is to give your code to an objective third party and ask their opinion, like OP did here.
These are not the speakers exact words but nearly..
... unless the role and the job post clearly state a particular framework as pre-requisite,
resorting to frameworks in an attempt to impress interviewers when applying to a senior role
is the worse thing you could do.
i.e. just because you know your way around Photoshop that doesn't make you a designer,
it makes you a Photoshop operator.
The same logic applies to coders who are too focus around frameworks.
They are not necessarily good programmers.
- The choice of using a Laravel back end was an informed decision to emulate as close as possible what would be my workflow on a real life app. Beside as opposed to front-end framework it has almost no cost attached and makes the back-end more maintainable and agile - Laravel is an amazingly clean framework. Finally the assessment of the basic PHP knowledge such as using PDO to connect MYSQL had already be made on paper test so there was no point repeating this there.
- The JS is certainly not perfect, game.js could use some refactoring, but my intent was not to make a production ready app but to show that I know how to write proper and maintainable vanilla JS. Given more time I would have addressed those details (which BTW are not the real issue in that code). Also you'll notice that I chose NOT to use a framework there as it was not needed. Again this was an informed decision.
- Sudo: I was worried that whom ever would try to install the app bumped into permission issues so I tried to make easier to install. I should have made a note of that. So point taken here. As for composer, I wouldn't want to work with any company that use PHP everyday and don't know what composer is.
You're right about your criticism of course, his memory game implementation is crap in many, many ways. But in the grand scheme of things, it's details. Most developers in the real world wouldn't be able at all to put it together in javascript in only two days (i've worked with people who wouldn't have been able to do it in two months). Hell, a large minority of developers can't solve the FizzBuzz test so disqualifying this guy for using to many dependencies and requiring sudo is silly.
I don't know exactly what they were expecting from you if anything in terms of efficiency or scale but there is a chance this looks like a massive, bloated chunk of unnecessary dependencies and code, which suggests you might not know how to manage a project efficiently. Just requiring Node.js to do javascript development in a PHP environment, itself, is kind of smelly to me.
I'm not saying it's fair, just that it's the impression i'm left with.
I can't say I'd pass the interview but my idea of how this would work would be:
- simple instal.php script that would use PHP's PDO to create a DB and a table with necessary info - simple api.php script that would take API calls in order to save scores and that's it. You could easily do this in Node as well thus keeping everything javascript - javascript front-end with no PHP involved there. An actual index.html file with everything in it, referencing one (non-minimized) JS file and whatever images and CSS.
This is hindsight 20/20 obviously especially since we all want to show EVERYTHING we know during an interview and I'm guilty of doing things like this as well. I'm guilty of doing the opposite too, keeping things too "prototype-y" and messy.
Some thoughts for the future:
1) PHP was a bad choice; some people have a burning, irrational hatred for it, and it leads them to judge your work in the harshest light instead of an evaluative one.
2) Speaking of burning irrational hatreds: PLEASE DO NOT MIX TABS AND SPACES. Drives me nuts--I would have dinged you for that. Not enough to make me say it is "falling far short of senior developer standards," but it makes me question your habits of development.
Tests are always nice, too: they're like the anti-PHP, and give a great deal of bang for buck in terms of coloring people's impressions of you.
These things are highly subjective.
Yes.
leads them to judge your work in the harshest light instead of an evaluative one
Should any professionals have to present apologetics for others in his procession doing such a thing? We are all human beings, but shouldn't we be trying not to be this quickly and arbitrarily judgemental?
Speaking of burning irrational hatreds:
Somehow the social expectations of the programming profession are that we can get away with acting these out.
PLEASE DO NOT MIX TABS AND SPACES. Drives me nuts--I would have dinged you for that.
Yes. This can be problematic. The fact that it is still problematic after all these decades is a good indicator of how backwards we are as a profession.
If you look at the various analyses answering the op as detection of signalling -- well, it's all about signalling. I'm not so sure this is too much more substantive than an interview where you need to have the right school name on the right degree and a properly pressed suit.
> Should any professionals have to present apologetics for others in his procession doing such a thing? We are all human beings, but shouldn't we be trying not to be this quickly and arbitrarily judgemental
Well sure. But this is php we're talking about here.
I'm not sure this is any more substantive than an interview where you're supposed to have the right names on everything and show up in a pressed suit.
I'm not a web developer, but this seems like a day or two of work? That seems unreasonable to me, and I probably wouldn't have agreed to that level of commitment, especially if they were still interested in me after an interview.
Side note: in the webdev world, is it normal to have third party code mixed with stuff you wrote yourself? In C++ land most of the third party stuff would have gone in a contrib directory or something before being built into a library of some sort.
Drawing the grid with Javascript wasn't necessary at all: that could have been pure HTML/CSS.
No use of jQuery is probably a red flag - not that it's inherently bad to avoid jQuery if you don't need it, but using it would have made your code substantially cleaner/easier to maintain. If a quick and dirty project like this is your assignment, I'd be a little concerned if you didn't install a tool that would help you complete it as quickly as possible - especially one that's (for better or worse) pretty much a given on any project that involves Javascript.
Finally, while I understand that you may not be a UI designer, there's a pretty severe lack of polish on this interface. Part of being a full-stack developer is being a front-end developer; part of being a front-end developer is some sense of design; and part of being a "senior" full-stack developer is being able to set a strong example across the entire stack (including the front-end). The arrow keys for navigation was a nice touch on the interaction side, but visually it was amateur hour.
I'm not a strong PHP developer so I won't speak to your back-end skills, but hopefully this has given you some perspective on why they made the decision they did. For what it's worth, I agree with their feedback. I know that's hard to hear, but just pick yourself back up and keep getting better.
In the mean-time, I suggest applying for lower-level positions. Find somewhere that will provide a good learning environment, alongside some strong senior developers that can mentor you without expecting you to perform at a senior level. Then, in a few years (or months if you're a quick study), get back on the horse and apply for some more senior positions. You'll get there someday.
The output of this project should have been a starting point for further discussion. Instead what you describe tells me the company you interviewed with is probably a "one-pass" (it's expected to be perfect the first time) shop and likely have loads of technical debt. Competent software shops understand the long term nature of development and the tradeoffs involved. They missed an important opportunity to learn about your true depth and ability to work with others by not having you do a paired refactoring of some aspect they didn't like.
Just as people are often bad at being the interviewees people can be equally as bad (or worse) interviewers. There are loads of jobs out there for you. Don't let things like this discourage you.
2. Why is the spacing convention all over the place in some files? https://github.com/m4nuC/memGame/blob/master/app/controllers... https://github.com/m4nuC/memGame/blob/master/app/database/mi...
3. Why are there so many folders that only have .gitignore's inside them? In fact, why are there so many folders at all?
4. In my glances at some of your files I didn't find a single function with a lot of "meat" inside it, so it doesn't show much about your ability to write something that actually does something.
I hate this meme. There's nothing wrong with too much commentary. You are not on a comment budget. Please stop spreading this around, like the "rewriting is always a bad idea" meme that's embedded itself in young developers like dogma even though Spolsky's point is up for debate. Atwood is wrong about this one, too, and I hate that Spolsky and Atwood have so many "rules" of programming that people pass around.
I've seen this meme borne out via comment ratio rules in style guides. That's ridiculous. We all work in editors that make comments a different color. I use light gray. My eyes can look right past them, but if I want the paragraph or two explaining the algorithm I'm looking at, it's there. The underlying flaw in Atwood's claim is that it is possible to write code in a way that is self-evident to every reader. You do not know every reader.
Well-written commentary -- bordering on literate programming -- makes development much better. Even better if the code is the documentation. I don't know where this notion that we must conserve comments like water came from, but I'd be happy if it just stopped.
Note here that I'm addressing quantity, not quality. I feel that is important to clarify.
What's not OK is commenting ALL of your code, especially not to such an extent where the comments are actually longer than the code size on average. (!) Some stuff just has to be self-explanatory, period -- that's a fact, not a meme. If you can't make the simplest code self-explanatory, then I'm sorry but you simply can't code as well as someone who can. And if you're going to comment everything, then you're also wasting valuable time that someone who didn't need to do so would've spent writing actual code and getting more done.
And absolutely I think commenting all your code is okay. I honestly wish literate programming had caught on.
That's exactly what I'm refuting, so I'm not sure why you keep talking past me. I am speaking to the crazy notion that there is a par for the comment golf course, and we all have to be Goldilocks as we write software. I don't know where that started, but I'd love it if people stopped judging software based upon the non-executable portions.
A line before every line? Maybe. Are they comments of quality? I've put a comment on every line of assembly before as a postfix. There is no hard and fast rule on this, and I wish people would stop trying to make one.
Again, literate programming. I feel like you're missing how serious I am about this by overlooking my repeated love for it.
Please do me the respect of researching literate programming before attempting to extend this thread, because I can tell you're unfamiliar, just based on how many ways you're trying to slice and dice a chink in my opinion on this.
The debate has been about why the OP's code was considered poor by the employer, and I think putting too many comments might have been such a reason. Whether or not you think putting too many comments is good or bad is orthogonal to whether or not it might have been a reason for rejecting the OP as a candidate. I think it's a reason for avoiding hiring the OP (see my previous discussion about productivity and wasting time writing comments), and whether you feel it's actually justified by some "good" coding methodology is orthogonal to whether or not the employer might have used the same rationale as me, and that's all I'm trying to address here. If you feel the employer's rationale was unjustified or crazy, then so be it; that doesn't mean the employer couldn't have had this thought process anyway.
We're not on the same page here, clearly.
Literate programming is a horrible idea; comments in code encourage verbosity and showing off, lack any guarantee of correctness and should always be a last resort.
Sorry for the bad experience, hope it turns out better.
My guess is that they were expecting a much simpler application for a simple problem. Also for a JS game with a tiny backend, the Github project code is heavily weighted toward PHP (73% PHP vs 20% JS). Perhaps in their internal discussions, a word like "over-engineered" was brought up.
I'm not saying that it's bad code. It looks fine to me.
Other point is that the technical interview is a time to ask questions for the interviewee (when they allow). What is their development process? Do they iterate and prototype a lot, or is their process closer to waterfall? Assuming their stack is primarily PHP, do they use a framework? Do they follow MVC? Do they use a JS framework? Etc... Having known the answers to these questions would have helped you create an application that looked closer to their comfort zone. (Even if you don't know a coding test is coming, you still should want to know the answers to these questions so that you can know if you are getting into a situation where you might have to maintain old applications written in PHP 4, for instance.)
I hope the OP finds a job someplace where his skills will be appreciated, a place that doesn't ask for free work. Sounds to me that they were really too lazy to look at the whole application or didn't have the technical know-how to understand an application written in frameworks they were not familiar with.
- Overall project structure seems a bit unorganized IMO (no centralized build process, gulpfile inside subfolder). Overall this makes it fairly hard to dive right into the project. It might be my lack of experience in PHP project structure.
- I think pulling in a server & a db might be an overkill. Local storage will do the job perfectly.
- Mix of tabs & spaces is also very messy.
- Styling is pretty sloppy too I believe. No clear organization/reusability in the stylesheets.
- Vendor scripts/generated scripts should not be committed to the repo IMO. There're already bower & CDNjs & a bunch of other services.
- Your JS is also very module/singleton-based although some of them are clearly object-oriented. Also seems to be a mix of jQuery usage & DOM directly, why not 1?
I think what they're looking for is a couple of simple JS that's easily tested, maintained & expanded which IMO is more important for senior candidates. Less senior ones can always bang this out quickly but senior ones care way more about other attributes of a project than just getting it done asap.
This was what I noticed the most - and I can easily see this as a big part in the discussion, since seniors should lead and bootstrap projects.
I'd have expected something like ./server and ./client and a README toplevel, client eventually having a public folder which can be served as-is (i.e. doesn't contain any build/dependency management files), potentially with a second public-minified around. Instead I end up with a src-folder hidden like 3 folders deep and another one toplevel for asymmetry.
Beyond that, the folders in the php app follow the package-by-kind antipattern. There is no value in grouping all controllers in one place. There's value in grouping all the highscore handling in one place, though.
Doing it like this makes me wonder if their real motive is something else. What are they really trying to determine with this sort of test at this time? They do it at a time where there isn't much opportunity to discuss the result, so what's the real goal? Whether, without prompting, you used their favorite language/framework/database and happen to have the same coding style as them? Seems pretty silly to me.
Did you get any possible feeling that maybe they have some hidden or political reason for not wanting to hire you, and threw this test at you as a way to create an excuse for why they won't hire you? That would explain why they gave it after the interviews and don't seem to be interested in discussing why it doesn't meet their standards.
I can teach you my project's programming language... I don't have time to teach you problem solving basics.
You know laravel. You know about libraries and can use them. It's less clear that the code you wrote was good. It's sort of buried in a fair bit of noise.
You won no favors by requiring an install of the nature you have and fumbling that a bit as well (chmod 777).
The other thing is... you can't trust a potential employer's reason for saying, "No." They said it, but you don't know if the message is garbled by the HR rep or even a flat out lie because the short answer is, "No." and they don't want to spend time explaining themselves.
They decided and moved on. They are not invested in your future. Coming here for feedback is a good practice. We care about you and have few reasons to just let you know, "No."
Soooo many dev job fish in the sea. Get your line back in. Your bait is fine.
In the demo I can use arrow keys. But only left click can flip a card. [enter] does nothing (using Chrome Version 35.0.1916.153 m on Windows 7).
If they tried it and it failed (and if they had a big pile of submissions to get through) this would've definitely counted against your submission.
--
More generally, having looked at what this game actually does vs number of lines of code I would use one word to describe it - overkill.
--
Let me add. It was very helpful of you to post this question. Informative (I hope) for you, but also for everyone else, as we contemplate what coding mastery is really about.
At the end some companies appreciated it and some just plainly gave a very discouraging feedback.
If you can't appreciate a person who can deliver your requirements with 100% features covered and well tested to the point without wasting any time on clarifications, under crippling timelines- Then clearly you are looking for men from an another planet.
You must just wish those companies all the best and move on. They are ultimately going to hire some career cup scraper any way.