8 ms·
Too many software engineers get into a mindset of “just make it work.” For me, making it work is only half the battle. You need to build something that will mak
by baron816 8y ago
Too many software engineers get into a mindset of “just make it work.” For me, making it work is only half the battle. You need to build something that will make it possible for you or someone else to come back to later and be able to reason about and modify or extend.
I interview a lot of job candidates and I give them a very simple problem. Pretty much everyone can solve it, but I’m not just looking for them to solve it. I’m looking for them to find the right abstraction—one that will make it easy to extend the problem and for junior devs to look at the solution function and understand exactly what it’s doing. Almost no one passes.
My coworkers ask “just make it work” problems in interviews, and I believe that has contributed to our codebase being a nightmare to work with.
I think most software engineering is an organization problem, rather than a optimization problem. My advice: learn functional programming and object oriented design. You will learn how to write declarative code that is loosely coupled and not dependent on its context.
- ganashaw 8y agoWould you mind sharing that problem? Always looking to improve my own interview questions.
- baron816 8y agoThe question is to make a function that will group the values of a linked list by odds and then evens. So 1->2->3->4->5->6 becomes 1->3->5->2->4->6. The solution essentially comes down to creating filter and concat methods for the LL, so you get something like: function groupByOddEven(ll) { var odds = ll.filter(isOdd); var evens = ll.filter(isEven); return odds.concat(evens) } If anyone were to ever get this far on their own and implement the LinkedList class correctly, I would have them make it so that they could make a higher order function that would receive any predicate function and then group by those values first, then its complement.
- jtchang 8y agoMy first thought is below. However I'm not sure if this is a good problem to ask unless you want them to iterate on the solution and you mention you want to do in a functional way. def groupByOddThenEvens(someList): odds = [] evens = [] for x in someList: print x if x % 2 == 0: # Even evens.append(x) else: odds.append(x) odds.extend(evens) return odds
- Aeolun 8y agoAh, I just see if people realize that Square is a subclass of Rectangle.
- Zalastax 8y agoBut is it though? If your objects are immutable I agree but if you have setHeight and setWidth I don't.
- jonny_eh 8y agoIt can be mutable if setHeight sets width automatically, and vice-versa.
- Jare 8y agoThis is a terrible idea. A rectangle by definition has width and height independent of each other. A square does not fit that description and thus is not a rectangle. Even if you did something like implementing the square's size as an average of the underlying rectangle's width and height, which would apparently support both classes correctly, you will get in trouble with the semantics or with other, less "fakeable" properties of these objects.
- zild3d 8y ago> A rectangle by definition has width and height independent of each other. That's not really true though. Definition is a quadrilateral w/ 4 right angles. Width and height can be dependent or not
- jonny_eh 8y agoI've never come across this definition. I've always heard that squares are a subset of rectangles, just as rectangles are a subset of parallelograms.
- Aeolun 8y agoIf you have set width and height, then you don’t need the Square class at all.
- enedil 8y agoSo in this case you're sure that this is the right abstraction. Here's one that I find equally well fitted: you basically want a stable sort on the list with key function f(x) = 1 - (x % 2) This is also a standard problem. Do you think this abstraction is worse? If so, why and how?
- jdcarr 8y agoRuby works out pretty nicely in that case! def order_list_by_predicate(l, &blk) l.partition{|i| blk.call(i)}.flatten end part(1..6) do |i| i % 2 == 1 end And you can always sort the incoming list if that's a requirement.
- scarface74 8y agoIs that really representative of the type of problem that your company is trying to solve? If not, why not actually create a simplified version of a real world problem your company solves on a daily basis, with a skeletal non working implementation, and corresponding failing unit tests and tell them to make the unit tests pass? That way you can actually see how proficient they are with the tools they use everyday. I had two job offers one time. One where the interviewer asked me how I solved real world problems and my experience and one where they wanted me to write a merge sort on the board. Guess which job I took? I’m not going to be writing a merge sort in real life and I don’t waste my time learning algorithms and studying leet code. I solve real world problems using existing frameworks from the front end to cloud and on prem infrastructure. Yes I have my geek credentials - started programming almost 35 years ago in 65C02 assembly, did bit twiddling in C for 12 years, etc. but I am way past wanting to reinvent the wheel.
- TableOnTheRug 8y agoCould you give an example of a simplified version of a real world problem?
- scarface74 8y agoThe last time I was responsible for interviewing, the project I was working on dealt with a lot of data transformation - get data from various APIs and databases, transform it and store it somewhere else. This is all .Net and we were storing data in Mongo. So we were always working with lists of strongly typed objects. One simple problem was given a list of users objects, create a list of the target object and generate a userid from the first initial, first four of the last name. Then we had an algorithm for how to handle ID clashes. We had failing unit tests for all of the corner cases. We were hiring contractors and paying them well so we made one of the requirements that you had to know LINQ and EF. Even though we weren’t using EF that often, Linq is Linq and linq queries work the same with in memory lists, EF, and the C# Mongo driver. It was a requirement that they used Linq instead of foreach loops since Linq gets translated to Sql and MongoQuery instead of doing the processing in memory.
- deleted 8y ago
- zeroname 8y ago> If anyone were to ever get this far on their own and implement the LinkedList class correctly, I would have them make it so that they could make a higher order function that would receive any predicate function and then group by those values first, then its complement. What does that have to do with any real world problem any company ever had? Do you actually solve problems at your company, or are you busy rewriting everything from Scala to Haskell?
- dang 8y agoPersonal swipes will get you banned here, so please read https://news.ycombinator.com/newsguidelines.html https://news.ycombinator.com/newsguidelines.html and don't post like this.
- justinpombrio 8y agooddsBeforeEvens = uncurry (++) . Data.List.partition odd
- yread 8y agosomehow everytime i see a question with linked list I'm conditioned to look for in-place solution. Something like list = getOddsToTheFront(list) list = sortOdds(list) list = sortEvens(list) implementation of helper methods left as an exercise for the reader
- Jemaclus 8y agoNot the person you're replying to, but I'll share one of my favorites: Given an address such as "123 Main St, Boston, MA 00215", break it up into its component parts of: street number, street name, city, state, zip. (Note: I usually just ask for pseudocode, but if they want to write real code, they can.) The reason I like The Address Problem (TM) is that it's a real problem I've solved before. I've built address verification systems for some large US companies that you've almost certainly heard of. Most companies in the consumer space deal with some sort of address input, whether it's StitchFix deliveries or Redfin for real estate. Most of those companies outsource it, but still... you store customer addresses in your database, right? :) I also like it because the domain knowledge is already known for anyone who has spent any amount of time in the United States (where I reside). It's intuitively obvious to any American or even recent immigrant which part of the address is the street number, which part is the city, and which part is the zip code. You don't have to know anything special coming into it -- you don't need to know what a binary tree is or what a linked list is or any of the bajillion other CS concepts that I learned in college and see in interview questions and have yet to use in actual real-world use cases. All you need to know is how to read the front of an envelope or an entry on Yelp. Another reason I like it is that there are some really obvious ways to go, and there are some really complex ways to go. Arriving at a solution that _works_ isn't really the point. Any programmer out of boot camp can do that, and there are a billion complexities to addresses that most people don't think about. What's more interesting to me is how you arrive at your solution and is that solution something that you can build upon to handle various edge cases. For example, a lot of candidates will say "I'd use a regular expression," at which point I'll ask them to write one. They usually struggle a bit with it, but even if they do get it, I throw a curveball: "What if some inputs have no commas?" Then they have to modify their regex to handle comma and comma-less addresses. Some candidates will start off looking at the beginning of the string and saying something like "I'll look for a substring of Street/St or Avenue/Ave or similar", to which I can throw the curveball of "123 Main Street E, Boston, MA 00215" or a more fun one, "123 St Francis Ave, Boston, MA 00215" I really like the address question because of the endless curveballs I can throw at it. What happens if the user leaves off the ZIP code? What if they abbreviate the city to "SF" instead of "San Francisco"? What about apartment numbers? How do you handle pre-directions and post-directions? What's the city for "123 Main Street West Palm Beach FL 33409" and how do you know? What reasonable assumptions can you make about an address? For example, there are 50 states + a handful of territories, so states should _theoretically_ be easy to parse out... What other assumptions can we make about addresses? (Gotta be careful with this one -- people often assume that street names end in "Street" or "Avenue" or their abbreviations and forget about post-directions!) Since the domain knowledge is so simple even a 5th grader understands, the real challenge comes down to problem solving. There's no "trick" to it. You just work through the problem until you get stuck or we run out of time. Giving hints is fairly straightforward as well. At the end of this part of the interview, I often allow them to give me some thoughts on how they did. If they could do this whole 30 minutes over again, what would they do differently? Maybe not use regex? :) How do they think the US Postal Service handles addresses? Or Google? Again, there's no right or wrong answer for these. I'm more interested in whether they exhibit self-awareness, whether they can identify what went wrong earlier, and whether they can learn from their mistakes. (In case you were wondering, the _real_ answer I'm hoping for is "I'd ask Google Maps." I've had exactly two people give me this response in the 8+ years I've been giving this challenge. I don't know if it's because they think it's a dumb answer, if they know that I expect a code-related answer, or if it never occurs to them... but I like to think someone who wants to see what Google says isn't the type that constantly wants to reinvent the wheel. Note that NOT giving this answer is not a deal-breaker. I generally give the benefit of the doubt to candidates here.)
- dudul 8y ago> I’m looking for them to find the right abstraction Nothing worse than an interviewer asking a design/coding question and who already "knows" which answer he/she wants.
- jjoonathan 8y agoAlso, I'd give better than even odds that GP's "right" answer is a pet solution of theirs that other people of similar background and skill level would contest. I don't disagree with the practice of giving simple questions with solution spaces well understood by the interviewer. I use it myself. However, I force myself to accept any answer that correctly identifies tradeoffs as correct and I have to intentionally suppress my inclination towards a specific set of weights on those tradeoffs in order to be fair. This doesn't seem to be nearly as common as it ought to be.
- adjkant 8y agoThis 100%. There's a big difference between looking for maintainable and extendable code and the "right" solution. To me, that almost no one passes is a red flag - if you are screening resumes right and framing the question right, the pass rate should be at least 25% IMO. Extensibility/maintainability also exist on a spectrum - a less than ideal answer can still be pretty close.
- Aeolun 8y agoI guess that could be said for any question. Have them be easy enough that at least 40% give something close to the desired answer, and then use 10 of those questions.
- baron816 8y agoI’m fine with less than idea answers. The problem is that most people I see prematurely optimize and don’t try to abstract the problem out at all. Or they only abstract one small part, or a part that makes no sense to abstract. They gravite to one big function that does everything. Our codebase has a lot of big functions that do everything. The only time people try to break things up is to make it DRY. Any time we need to change things, it breaks something else entirely unrelated.
- openIce 8y agoThat sounds like a lot of wasted money. As long as it works there's no reason to redo it. Thank god I dont work at the same company as you. If there's anything new software developers need to learn it is to make money for the company and stop worrying about the code.
- scarface74 8y agoToo many software engineers get into a mindset of “just make it work.” For me, making it work is only half the battle. You need to build something that will make it possible for you or someone else to come back to later and be able to reason about and modify or extend. There are no absolutes. In small companies that are just trying to get that one whale or feature that can keep them in business and prove to thier investors that they have achieved “product market fit”, sometimes just duck taping together makes sense. Other times companies aren’t looking for a long term product, just something good enough so the investors can have an exit strategy. Yes I have worked and been a Dev team lead in both the above environment and one that wanted well tested, well architected software that they wanted for the long term and had the resources to see it through. You have to know what the end game of the business is. Look at Twitter. All indications was that early on that their code base was horrible. They proved their was market, got the money and rearchicted thier system.
- rizzom5000 8y agoI think you make a valuable point here, but I don't think that quality and productivity are mutually exclusive. I often encounter engineers or teams who are putting just as much time and effort, or more, into 'making it work' as it would take a more skilled engineer or team to achieve both.
- scarface74 8y agoMost of the time they aren’t mutually exclusive. It’s just as fast for me to write maintainable code that is well designed and for me to write some scripts to automate deployment and Cloud Formation templates to automate infrastructure deployment. But I’m only one person. If they want something done fast, I can spin up a team of barely competent programmers who know how to create web pages that meet the spec and outsource a bunch of manual QA testers instead of writing automated test and let them test the code that we write during the day when they come to work while we are sleep (outsourced it’s daytime for them). Despite the talk of the 10x developer, sometimes you just need bodies. I can do front end, middle tier, database admin work, AWS net ops, dev ops, and development, talk to CxOs about strategy, mentor developers, lead a team etc. and I have done all of those things. But, I can’t do it all at once.
- holografix 8y agoI’d also like to know that question if you don’t mind. I’m considering a career change to development full time.
- pfarnsworth 8y ago> I’m looking for them to find the right abstraction—one that will make it easy to extend the problem and for junior devs to look at the solution function and understand exactly what it’s doing. Almost no one passes. If no one passes, it means you are instead asking them to recreate what YOU would do, and basically asking them to be a mind reader. A good interviewer would know that there is more than 1 solution to everything, and that there are equal, but completely different solutions to the same problem. Someone could abstract the problem completely different from yours, but still be correct.
- baron816 8y agoI tell them exactly what I’m looking for and am very clear up front. Many of them don’t follow orders, they put everything into one big function and don’t try to abstract at all.
- codingdave 8y agoSo you are expecting them to start with the abstraction, before coming up with a solution?
- enedil 8y agoOh, come on, the solution is trivial.
- emmanuel_1234 8y agoSo trivial that I can't really see what's there to abstract. It's literally a one liner in Python. [x for x in my_list if x % 2 == 0] + [x for x in my_list if x % 2 != 0]
- codingdave 8y agoThat doesn't re-build it into a linked list as his example showed. It also does multiple passes through the data, which should be fun if there are millions of items. It is a great question for talking about performance tuning an algorithm, but just seems bizarre to be pushing for abstraction on this problem.
- graycat 8y agoIMHO, do all you want on (A) "declarative code" and (B) "find the right abstraction—one that will make it easy to extend the problem" and I will applaud. Indeed, as I entered grad school in applied math and had a good career going in software, two profs getting ready to teach a computing course asked what advice I would give. I responded with something like your (B). Also for (A), at times I tried to write code that would have some algebraic properties: E.g., as I was writing various sorting routines, routines to invert a permutation, to apply a permutation to an array, working with the fast Fourier transform, there were, of course for these topics, some cases where could regard calling one of the routines as something like an operator in parts of math/physics, get new operators by composing the other operators, and, then, saying when some of the operators were equal to some of the others,, net, nothing, or invert another one. I got some such before I got back to just get it done. But at this point, IMHO, for all can do on (A), (B), etc., my view is that the crucial part is missing: I urge to do all you can on (A), (B), etc. and then just take the attitude that the code doesn't mean anything at all, is just gibberish, and then get the important meaning by documentation in a natural language, e.g., English. E.g., in a physics text F = ma has with it one or more whole chapters of well written natural language explaining what the heck that equation and its symbols mean. We do not leave the math by itself as self-documenting, self-evident, clear, or any such thing. Then, write the documentation so well that, if had to select and keep just one of the code and the documentation, then definitely leap to keep the documentation: If the documentation is good, then can reconstruct the code fairly easily. Without the documentation, understanding the code well enough to reconstruct the documentation tends to be a really big puzzle problem and likely in principle impossible. Bluntly, knowledge and meaning are communicated in natural language. E.g., well written pure math is in complete sentences.
- yourbandsucks 8y ago>> Pretty much everyone can solve it, but I’m not just looking for them to solve it. ... Almost no one passes. Sounds like a not-great process IMO. You're expecting them to understand a lot of what makes you tick and what you personally consider 'maintainable' based on a 1 minute problem description. My opinions on what makes code maintainable have evolved and fluctuated (based on most irritating current problem) significantly over time.
- mooreds 8y ago> Too many software engineers get into a mindset of “just make it work.” For me, making it work is only half the battle. I had a conversation with a mentor talking about hiring. He said that he typically saw two types of engineers: Those who can start something. And. Those who can finish something. The former can tackle problems that seem to have no solution, start from scratch and build something that just works. They are energized by greenfield development and close consultation with customers/users. The latter can work within larger organizations, know about idiom for the technologies used, think about the right level of abstraction, and provide polish for the codebase. Teams typically need both kinds of engineers. I found out what kind of engineer I am years ago. That's led to roles that make me happy. Agree that fp and oop are good investments.
- __exit__ 8y agoI cannot stress enough how true this is when talking about types of engineers. However, both types are not mutually exclusive. There may exist some overlap between them, but of course, an engineer may feel more comfortable being one type more than the other.
- drakonka 8y agoI like doing both, but I especially like really understanding and improving an existing code base, finding/following/encouraging best practices, contributing back to the engine, etc. Writing something from scratch can be fun too though if I am given the time to do it in a way that I think is "right" vs just banging out a prototype with corners cut as quickly as possible and leaving it as is.
- collyw 8y agoI like doing what you describe as well, improving an existing codebase, but its not something most businesses see as valuable. Instead you end up adding more hacks on top of the existing crappy codebase to get features out on time, making it even worse.
- zeroname 8y ago> I interview a lot of job candidates and I give them a very simple problem. Pretty much everyone can solve it, but I’m not just looking for them to solve it. I’m looking for them to find the right abstraction—one that will make it easy to extend the problem and for junior devs to look at the solution function and understand exactly what it’s doing. Almost no one passes. In other words, you're setting those people up to fail who are providing a straightforward solution to a made-up problem. The "right abstraction" often is no abstraction whatsoever. If "almost nobody passes", the problem is you. You're an "overengineer". These candidates are dodging a bullet with you.