7 ms·
Subverting the software interview (2021)
- gunnr15 4y agoSo good.
- cntainer 4y agoProbably didn't pass the interview. The implementation was rather simplistic and low quality. Here's a better enterprise version: https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris... Though the fact that it was written some years ago might be a weakness. Some interviewers might prefere a more modern, distributed solution.
- jeffrallen 4y agoA multi core one, with lockless data structures.
- classified 4y agoBetter, with CRDTs.
- ARandomerDude 4y agoThis is brilliant and spot on.
- pfoof 4y agoThis github org needs more leetcode examples in that style
- selcuka 4y agoThere is also the Hello World Enterprise Edition [1] [1] https://github.com/Hello-World-EE https://github.com/Hello-World-EE
- MikeDelta 4y agoOr serverless
- smoyer 4y agoWhat about observability?
- BLanen 4y agoI was thinking of making a modern distributed spaghetti version some time. FizzService, BuzzService, FizzBuzzService, CountingService, etc
- deleted 4y ago[deleted]
- andrew_ 4y agogreat read. entertaining and engaging, wonderful creative writing with nerd flair.
- thatjoeoverthr 4y agoI'm smiling as I read from top to bottom.
- thoughtpalette 4y agoGreat writing, hilarious. I feel like we all could know someone who fits these characteristics.
- jeffrallen 4y agoI worked with a guy who implemented map and reduce in C++ as a subtask of some other task. It was, of course, a header-only templated monstrosity. He called it "fun.hpp". "Fun" times, indeed, working with him.
- djmips 4y agoOMG.
- omegaham 4y agoYou'll like the `std::ranges` library that's been somewhat implemented as of C++20 and is getting some more stuff in C++23. It's very Fun! #include <ranges> #include <numeric> #include <vector> #include <iostream> int main() { std::vector<int> vec = {1, 2, 3}; // map, using `std::views::transform`. Implemented in C++20 for(int elem : std::views::transform(vec, [](int x) { return x + 1; })) { std::cout << elem << " "; // 2 3 4 } std::cout << "\n"; // `std::ranges::fold_left` will be available with C++23. // Until then, we're stuck using the <numeric> iterator version, which was // implemented in C++20. std::cout << std::accumulate(vec.begin(), vec.end(), 1, [](int x, int y) { return x * y; }) << "\n"; // 6 return 0; } Building and running with the following: $ g++ --std=c++20 test.cpp $ ./a.out 2 3 4 6
- delta_p_delta_x 4y agoThere's a nicer way still: #include <algorithm> #include <functional> #include <iostream> #include <numeric> #include <ranges> #include <vector> int main() { std::vector<int> vec{1, 2, 3, 4, 5}; auto plus_one{[](const auto x) { return x + 1; }}; std::ranges::for_each(vec | std::views::transform(plus_one), [](const auto x) { std::cout << x << " "; }); std::cout << "\n"; std::cout << std::accumulate(std::begin(vec), std::end(vec), 1, std::multiplies<>()) << "\n"; return 0; } https://godbolt.org/z/84ePjfPhf https://godbolt.org/z/84ePjfPhf
- singron 4y agoEverything makes sense to me until the Dual definitions: newtype Dual a = Dual {getDual :: a} instance Semigroup s => Dual s where (Dual a <> Dual b) = Dual (b <> a) instance Monoid m => Dual m where mempty = Dual (mempty) These are declaring instances of Dual, but they are providing method definitions for Semigroup and Monoid as if they were declaring instances for those types. I plugged this into ghc and I couldn't get this to compile either way. This isn't using an extension or some more obscure language than haskell is it?
- tczMUFlmoNk 4y agoLikely meant to be lifting instances of Semigroup and Monoid through Dual: newtype Dual a = Dual {getDual :: a} instance Semigroup s => Semigroup (Dual s) where (Dual a) <> (Dual b) = Dual (b <> a) instance Monoid m => Monoid (Dual m) where mempty = Dual (mempty)
- billsmithaustin 4y agoAnother in this genre: https://aphyr.com/posts/342-typing-the-technical-interview https://aphyr.com/posts/342-typing-the-technical-interview
- ryukafalz 4y agoThis (along with several others) is linked at the top of the article.
- JonChesterfield 4y agoQuoting from aphyr as it still brings me joy and might encourage others to read through the interview pages there, > “In Lisp,” you offer. “We often write domain-specific languages to solve new problems.” > “C is not a DSL!” > “If you insist.” Keep going anyway.
- yellowapple 4y agoMy favorite: > The Church. The lambda calculus. The gay agenda. It has known a thousand names, a thousand forms.
- trenchgun 4y agoWhy gay agenda though? What is the connection?
- yellowapple 4y agoIt's a reference to the Church-Turing Thesis, the latter namesake having been persecuted for "homosexual acts" and forced to undergo chemical castration.
- tra3 4y agoGorgeous. I'm not versed well enough in the theory to validate his code, but I know enough to see where he's going with this. As an aside, there's a lot of rightful complaining about the interview process. I've been on both sides and it sucks either way. As a hiring manager for a small company, we never had the 'process' that bigger companies have, so it was always a seat of the pants decision. Not my favourite thing to do. As an interviewee, I've struggled with people's favourite questions, you know the ones that you ask so much that it starts sounding like an easy question in your head?... I'm productive, I ship software but interviewing is so incredibly stressful and always makes me feel like I don't know much. Anyhow, if I was interviewing the OP for a typical web app CRUD position or monolith to micro services refactor or some other common role, I'd think twice. Clearly he's very smart. Is he able to "deliver value" vs optimizing code? I know the post was tongue in cheek, but in the real interview setting you gotta demonstrate how you're a smart team player and allude to your capabilities. It's kinda like dating I guess. You can't show how much of a real person you're on the first date.
- johnbcoughlin 4y ago> validate his code > by Naomi Liu
- guntherhermann 4y agoA name does not imply sex. Even if it did, the parent wrote multiple paragraphs and you get hung up on something as inconsequential as this. Take a day off.
- Zacharias030 4y ago[dead]
- PostOnce 4y agohttps://en.wikipedia.org/wiki/Naomi_Uemura https://en.wikipedia.org/wiki/Naomi_Uemura
- congoe 4y ago
- imperialdrive 4y agoI'm crying from laughter - this is simply fantastic! Mucho thanks to author and OP for making my morning!!!
- guntherhermann 4y agoBeautifully written, great read.
- WalterBright 4y ago> You have a tendency to overengineer things. Overengineering is an actual problem. For a tiny example, I'll see things like: enum MAGIC = 67; // explanation ... foo(MAGIC); The use of MAGIC is the only one, and is far removed. A better solution is: foo(67); // explanation because it improves locality. I also see things like an object fleshed out with all kinds of member functions that are never used.
- maxbond 4y agoI think I can see what you're getting at that you view this as a premature abstraction, but I don't think I'd call it over engineering. I'd call it a stylistic difference. If `MAGIC` was sufficient to understand what the significance of the number was and `// explanation` was the citation or derivation, then I'd be fine with this, especially if there were a bunch of other constants with explanations with similar derivations or citations (eg a bunch of trig or constants from the same standard); then it'd be preserving a different sort of locality. If `MAGIC` wasn't sufficient to capture the purpose of the constant & such a name wasn't readily available, so that you're always going to want to read `// explanation` (rather than only in the case you think the value is wrong), then I'd agree with you. Concrete(ish) examples: if 67 terminated the Foo section of the Bar binary file format, even if we only used it once, I'd prefer to see END_OF_FOO rather than read a comment. Reading comments is context switching, at least for me. Names help me stay in the headspace of the programming language. If 67 was the result of an ad-hoc calculation which only made sense in the context of this particular program (how many angels can dance on the head of an Acme brand pin executing our trademarked choreography) while, and so there wasn't a great name for that calculation, or at least not a name that would make sense unless you've already read the derivation, then I'd agree in that case. That being said, I have absolutely seen overengineering or misengineering cause real problems.
- sokoloff 4y agoIn a code review, I’d given a junior programmer advice to avoid magic constants and use defines instead (c, not c++). Resubmission came back with: #define SEVENTEEN 17 Last I spoke with him, he was a Java instructor.
- lazyant 4y ago> how their work ethics share the same ability to resist deformation as their play habits "We work hard, we play hard" in case anyone missed it :-)
- preciousoo 4y agoLol I sure did miss it
- deleted 4y ago[deleted]
- deleted 4y ago[deleted]
- danbmil99 4y agoCould this be accelerated and parallelized by writing a custom GPU shader?
- vincent-manis 4y agoI was kind of hoping for a specialized FizzBuzz CPU built on an FPGA.
- anonymousiam 4y agoFunny! The premise that modulo (%) is "slow" here doesn't quite justify the jump into Haskell, but it's still hilarious.
- Y_Y 4y agolist, mist func, gunc church, dhurch This is clearly the One True Naming Scheme and now that I have seen it I can't imagine ever using anything else.
- ptspts 4y agoThere is “no way” to subvert this FizzBuzz interview when writing code in Python 3 only. def inf_range(a): while True: yield a a += 1 def take(n, it): return [a for a, b in zip(it, range(n))] def fizzbuzz(): return (a + b or str(c) for a, b, c in zip( (a for _ in inf_range(1) for a in (("", "", "Fizz"))), (a for _ in inf_range(1) for a in (("", "", "", "", "Buzz"))), inf_range(1))) print(take(30, fizzbuzz())) For bonus points: which alphanumeric characters can be changed in the code above?
- Kamq 4y agoI always liked the version with no branching statements. In python it would be roughly: def fizz_str(n): return "FIZZ" def buzz_str(n): return "BUZZ" def fizz_buzz_str(n): return "FIZZBUZZ" def to_str(n): return str(n) indexes = [3, 0, 0, 1, 0, 2, 1, 0, 0, 1, 2, 0, 1, 0, 0] def fizz_buzz(n): funcs = [ to_str, fizz_str, buzz_str, fizz_buzz_str ] return funcs[indexes[n % 15]](n) for i in range(1, 101): print(fizz_buzz(i))
- raluk 4y agoHere is another version of similar idea as oneliner. Additional feature - no loops and no conditions. fb = lambda n : n == 0 or not fb(n-1) or not print(['{}',"fizz","buzz","fizzbuzz"][((n%3)==0)|(((n%5)==0)*2)].format(n)) fb(100)
- rahimnathwani 4y agoNice use of bitwise OR
- sjadoinqwoeihad 4y ago> 0, 0, 1, 0, 2, 1, 0, 0, 1, 2, 0, 1, 0, 0 I never noticed this symmetry in fizzbuzz before.
- eesmith 4y ago
- mizzao 4y agoReminds me of this oldie but goodie: https://joelgrus.com/2016/05/23/fizz-buzz-in-tensorflow/ https://joelgrus.com/2016/05/23/fizz-buzz-in-tensorflow/
- d1l 4y agoKyle did it better
- hashkitten 4y agoThe cycle method is really elegant in Perl, of all languages: use feature say; say <{Fizz,}> . <{Buzz,,,}> || $_ for 0..100;
- callalex 4y agoIt’s certainly concise, but I wouldn’t consider that to be elegant.
- dr_kiszonka 4y agoBesides the article, I greatly appreciated the EGA-like color scheme!
- 29athrowaway 4y agoWhat you need is Fizzbuzz, Enterprise Edition https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris...
- adityaathalye 4y agoIn Clojure, general for any set of fizzbuzz-like prime factors: (defn any-buzz [num & words] (or (not-empty (reduce str words)) num)) (map any-buzz (range 1 16) (cycle [nil nil "Fizz"]) (cycle [nil nil nil nil "Buzz"])) Source: from a bunch of fizzbuzz code riffs I wrote to illustrate real-world programming and problem solving with Clojure: https://www.evalapply.org/posts/n-ways-to-fizzbuzz-in-clojure/index.html#main https://www.evalapply.org/posts/n-ways-to-fizzbuzz-in-clojur... edit: formatting, detail
- mgaunard 4y agoI'm somewhat well-versed in lambda calculus, and still I have no idea how it was related at all to this exercise. In the end the only "subversion" is that it was written as zipped infinite ranges rather than an explicit for-loop.
- cbreezyyall 4y agoA personal favorite ruby -e 'puts (0..99).map {|i| srand(46308667) if (i%15).zero?; ["FizzBuzz", "Buzz", i+1, "Fizz"][rand(4)]}'
- Lio 4y agoThis is great and was a lot of fun to figure out. It also has the side effect of making me feel better for never attempting to write my own encryption algorithms! :D