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.
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.
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.
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.
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.
[x for x in my_list if x % 2 == 0] + [x for x in my_list if x % 2 != 0]
It is a great question for talking about performance tuning an algorithm, but just seems bizarre to be pushing for abstraction on this problem.
lambda f: [x for x in my_list if f(x)] + [x for x in my_list if not f(x)]
Nothing worse than an interviewer asking a design/coding question and who already "knows" which answer he/she wants.
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.
Extensibility/maintainability also exist on a spectrum - a less than ideal answer can still be pretty close.
Have you ever heard of Premature Abstraction[0][0a]?
> 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.
That's the whole point of DRY, though[1]. If you abstract with less than three instances of it, you will end up with abstractions that typically misfit the solution, requiring refactoring or outright disposal of the abstraction in the future (Or worse). Also, you waste time developing (what in all likelyhood are bad or leaky) abstractions when you could be devoting time to something more important.
> Any time we need to change things, it breaks something else entirely unrelated.
That's unrelated to abstraction.
There, I said it.
Leaky or badly fitting interfaces are not solved by abstracting more, they're solved by compartmentalizing more (There's a subtle difference here). This can be done with abstraction, but doesn't need to be. Typically refactoring the data structures, shuffling state around, or redesigning the interfaces to better fit the problem, is a better solution.
[0]: http://wiki.c2.com/?PrematureAbstraction
If the question is simply phrased, "Group the values by odds and evens ...; and please create an appropriate abstraction" without any more details, it would explain your results. I wouldn't be able to hold it against the interviewee that they couldn't reach the proper abstraction without more context.
If I wanted to gauge an interviewee's ability with abstraction and code organization, my preference would probably be to engage in a higher level discussion, because it's difficult to construct a code test that tests this well.
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.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.
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.
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 list = getOddsToTheFront(list)
list = sortOdds(list)
list = sortEvens(list)
implementation of helper methods left as an exercise for the reader 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. oddsBeforeEvens = uncurry (++) . Data.List.partition oddEven 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.
That's not really true though. Definition is a quadrilateral w/ 4 right angles. Width and height can be dependent or not
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.)
If you said “here’s an address, how would you parse it?” it would feel like the purpose of the interview is to use this task to see how I could. Saying Google Maps then seems quite facile.
If you said something like “you’re writing a web app and have been asked to add a new feature that would parse the submitted address and do X with it. Delivery of this feature is urgent. How would you parse the address?” then Google Maps seems like a much more natural answer.
I think the difficulty with such tasks is that it can be hard for the candidate to know what the confines of the test environment are - what kind of response is expected etc
There is nothing worse than a developer who doesn’t know the difference between which problems are part of the business domain that they are suppose to be writing code for and problems that other people have already solved.
And for this particular use case, I happen to know about CASS certified software. SmartyPants is $1000/month for unlimited lookups. Why would I waste company resources on writing that myself? The yearly cost is less than a month’s fully allocated salary for a senior developer in a major metropolitan city.
I'm surprised that this rarely seems to be brought up as a solution. It was the first approach I had in mind since you really can't split and format all those potentially mistyped addresses reliably without looking them up in a database/directory of valid addresses.
It feels very obvious, however admittedly in an interview situation I might actually assume that the interviewer doesn't want me to use the third-party look up approach as it feels like cheating, which is somewhat absurd since it's the correct approach.
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.
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.
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.