I had an interview at google years ago where I basically I was asked to come up with this on my own. In my opinion, a terrible interview Q (per Kernighan's blog, linked in original post, it took pike an hour or two alone in his office), and I bombed it. It was either my just before or just after lunch interview and it stuck with me for the rest of the day and I couldn't give my entire focus to the rest of the sessions.
anyways, after it was done, I found kernighan's blog post and decided I should try to implement this in java as it will allow me to even get some practice with things like junit and more experience with object oriented programming as I had been living in the C world at that time). so I did, but I then found this regular expression page ( https://www.regular-expressions.info/) and learned many more things about "regular expressions" that i hadn't learned in school (because they aren't regular) and wondered if I could extend pike's simplicity to them in a relatively simple manner. So I did.
Not meant to be "performant" but meant to be educational to me and perhaps others.
Then when I was learning go, I rewrote it in Go. I did things that are not "normal" go patterns (i.e. using panic and recover to make error handling cleaner (in my opinion, if an error path is simply if (err) { return err } all the way up, I personally think panics/recover at the top can be cleaner, but it seems most disagree), but it was educational on how to rewrite my java code to an object oriented style in Go and to explore the limitations of interfaces and how one might get around them (also perhaps in ways that go against what might be considered proper go programming)
though now that I look at that repo, wondering if all the work was done elsewhere and then I just pushed a single commit there, might need to go back and look at it
> I personally think panics/recover at the top can be cleaner, but it seems most disagree
Count me among those. At best, panic/recover would be an uglier version of throw/catch with even worse performance.
That said, I hope someday Go adds the "?" return-operator that kotlin and Rust use. Won't really change anything besides adding syntactic sugar for an already recommended pattern. But development ergonomics would improve a lot.
The authors of the encoding/json library thought the same. As a way to exit from deep down in a parse stack it works well especially if you only have limited entry points.
https://cs.opensource.google/go/go/+/refs/tags/go1.19:src/en...
uses well typed panics.
The stdlib is not always the best example of idiomatic Go; encoding/json is particularly infamous for having poor performance and awkward APIs. I'm fairly confident that it it was re-written today, it wouldn't use panic/recover.
which was why I used it. I basically had a single entry point (if i remember correctly) something like "match(regex, text)" and hence it made it easier for me to write by just panic at the error location and recover within the match() call than putting if err != null everywhere. Or at least that's what I thought then in terms of cleanliness.
in all the production code I've written in go since then, I haven't used panic/recover because its not considered proper. But I'm still a bit skeptical as do think it can make code a bit cleaner when writing a library (I'd 100% agree though that the panic should never escape the library though and only a plain error returned to the caller, i.e. need strong library boundaries for this).
I agree it's way too hard as a one-hour interview question! When I interviewed at Google a few years' ago I was asked to write a simple glob matcher that handled ? and * (like the one I've shown here: https://benhoyt.com/writings/rob-pike-regex/#bonus-glob-matc...). I think that question was border-line okay for an interview, though when I conduct interviews I prefer to give less algorithm-y problems. It was a tough question for me to do in 30-40 minutes, though I think with a little bit of help I got a working solution in Python (I probably didn't handle edge cases properly).
I’ve implemented glob matchers by regex-replacing the glob pattern, turning it into a regex, and then using that regex. I wonder how that would have gone in an interview. :)
Honestly even that is way too hard. The people who originally came up with DFA and NFA engines and all that didn't do it under pressure in 40 minutes. You're basically selecting for people who have done it before.
But Dijkstra's shortest-paths algorithm is, of course, a perfect interview question, having infamously been derived in half an hour over a coffee date with his fiancée.
This is completely unfair comparison. Deriving is not comparable to reciting/applying something... Dijkstra's is pretty intuitive once you know it and about 10 or 12 line of python code? Quantum mechanics took years and multiple geniuses to figure out yet somehow undergrads and graduate students are able to learn it in one or two semesters.
I'm not sure I follow - interview questions are supposed to be about deriving things, not reciting/applying them. In any case I'm pretty sure he was being sarcastic. You aren't hiring Dijkstra.
we probably got asked the same Q, but I believe pike's solution is close to the optimum solution to the google interview Q (in terms of being able to code out on a board in a short period of time).
If I remember correctly I was asked to be able to do a regex that handled . ? and *
The problem I have with this question is that if you spend 10-15 minutes going down a very wrong path, it's very very difficult to correct yourself in a pressurized environment.
I've tried to take the question and reformat it.
i.e.
I ask, what language do you want to program in (presuming I'm comfortable with the languages they want to use, otherwise I wouldn't be in the room, as wouldn't be a fair evaluation).
I give them the basic "strcmp" from pike's implementation (i.e. move character by character matching). i.e. something like
Second Q. how could we modify it work to match a substring (my explanation would be to just iterate over text like pike, but as with everything need to be open to where the interview takes you, but sometimes might need to say "that works for this, but for the future Qs, might want to think of it in this way", and give them some code, as again, I dont want them to code themselves into a corner that they don't have time to get out of).
Third Q. how could we add anchor support (ala regex, with a bit of explanation if they don't know what they are) (ala pike, determines where we are in the text, ala for ^ no iterating, and for $ we should be at a '\0' in the text
Fourth Q. how could we add "." support (just a || change to the primary matching condition, with being smart to check for '\0' which shouldn't match, but in a pressurized environment they might not get that without prodding right away)
Fifth Q. how could we add "?" support (now we have to look ahead a bit ala what pike does with )
Sixth Q (and the hardest), how could we add support.
I want to see if they can take some existing code, digest it and then see how they think to expand it. As there are many deliverables along the way, I'd hope I'd get a decent amount of "signal" even if they can't get to "?" or "*"
I also give them the link to kernighan's discussion on pike's code at the end.
if people have critiques of this approach to the Q (or further ways to improve it, I'm open)
Absolutely insane as an interview question. I know lots of top engineers who've built the fundamentals and driven companies to billions of dollars multiple times who would have failed to have completed this objective within an hour.
I refuse to believe anyone could imagine it's possible. Either that or there's a whole bunch of hidden talent wasting away at Google - which sounds unlikely.
The Google interview is more interested in how you approach the problem, explain it, and analyze it etc than in a working solution. You can pass the interview without having fully working code.
(I did interview training at Google twice)
I still think it's a terrible interview format, though.
I had an interview at google years ago where I basically I was asked to come up with this on my own. In my opinion, a terrible interview Q (per Kernighan's blog, linked in original post, it took pike an hour or two alone in his office), and I bombed it. It was either my just before or just after lunch interview and it stuck with me for the rest of the day and I couldn't give my entire focus to the rest of the sessions.
anyways, after it was done, I found kernighan's blog post and decided I should try to implement this in java as it will allow me to even get some practice with things like junit and more experience with object oriented programming as I had been living in the C world at that time). so I did, but I then found this regular expression page ( https://www.regular-expressions.info/) and learned many more things about "regular expressions" that i hadn't learned in school (because they aren't regular) and wondered if I could extend pike's simplicity to them in a relatively simple manner. So I did.
which I created this https://github.com/sjpotter/regex.
Not meant to be "performant" but meant to be educational to me and perhaps others.
Then when I was learning go, I rewrote it in Go. I did things that are not "normal" go patterns (i.e. using panic and recover to make error handling cleaner (in my opinion, if an error path is simply if (err) { return err } all the way up, I personally think panics/recover at the top can be cleaner, but it seems most disagree), but it was educational on how to rewrite my java code to an object oriented style in Go and to explore the limitations of interfaces and how one might get around them (also perhaps in ways that go against what might be considered proper go programming)
https://github.com/sjpotter/regex-go
though now that I look at that repo, wondering if all the work was done elsewhere and then I just pushed a single commit there, might need to go back and look at it