In a previous article, I introduced Merklix trees as a way to cryptographically describe an unordered set or map. It is possible to produce proof that an element is contained or absent of the datastructure in o(ln(n)), and use these proof to mutate the structure, even without knowing its full content.
Merkle tree are awesome. They allow to hash an ordered set of elements and provide a way, known as a Merkle proof, to prove that a given element is at some position in the set without having to provide the whole set. While this is a very useful tool, the fact that it is ordered can be somewhat troublesome. Inserting or removing an element in the middle of the set will require significant work and, more generally, 2 sets containing the same elements, but in a different order will yield 2 radically different trees.
Today, I’d like to introduce a new tool to the software engineer toolbox, which, as far as I know – and that probably tells more about my searching-foo than anything else, hasn’t been proposed before. The goal is to hash an unordered set in such a way that:
- The end result is the same, no matter in what way the tree is created
- Insertion and deletion are ln(n)
- It is possible to produce a proof that an element is contained in the set without producing the set
Code review has become a standard programming practice, for open source projects, but also for many companies that practice it in house. While this practice has proven to be very valuable, many developers struggle with it. So here are some tips and tricks that will help you work more efficiently when code review is involved.
There are (at least) 2 persons involved in code review. Someone that I’ll call a contributor, who want a piece of code to be merged, and a reviewer, who try to confirm that this piece of code meets quality standards and won’t introduce too much complexity compared to the value it provides. Making the whole exercise efficient requires each party to understand and empathize with the other and act accordingly.
This post is obviously a reference to the notorious Why Can’t Programmers.. Program?. I was earlier today reading an article about unreasonable assignment for junior programmer interview. In that article the author describe how some of one of his junior friend had to program a linked list in java that is compliant with the List
The whole assignment needed to be done in 30 minutes, and required to implement at least 2 classes and 37 public methods. It seems pretty unrealistic indeed to expect this from any programmer, especially from a junior programmer.
But that isn’t what is the most surprising about this article. The author then goes to mention he tried to do the assignment pair programming with another senior developer and they couldn’t get it nailed down in 6 hours. In fact, they didn’t even started the iterator part of the problem. Damn, 2 senior developers can’t do it that much time ? What can be so hard about it ?
And so I tried
I had to see by myself what was so hard about this, so I setup myself to do the assignment and see how it goes. It was understood that I had tight time constraint, so I had to blast through the spec getting all the methods do what they are supposed to with less than a minute each to get it by the time limit.
Hopefully, most methods are actually quite trivial, and, without constraint on the complexity, I could do heavy code reuse. For instance, the addAll method will repeatedly call the add method, which is O((N + M) * M) while doing something in O(N + M) wouldn’t have been too hard. The documentation is also nice enough to provide you with all you need, even sometime sample code for complex condition.
Needless to say, I couldn’t get it done in 30 minutes. I needed 35. I would not recommend to use the result of these 35 minutes of intense coding in production. The complexity is high, allocations too frequent but overall, it works™. If I were to use that code, which would be stupid to boot, because Java already provide a linked list implementation in its standard library, but if I were, I would surely improve the test suite, fix the algorithms that exhibit high complexity and make the code more readable.
To my shame, I skipped retainAll, by choosing to throw an UnsupportedOperationException, which is valid per spec.
What to do during the next 5 hours and 25 minutes ?
As I expected, the assignment was way too complex for the time given, but I’m fairly confident that I can achieve some quality implementation in less than 6h by now. To boot, improving complexity, then, getting the gava test suite make sure all of it passes.
Which lead to the question: How come two senior developers can’t get it done in 6 hours ? The industry I work for is full of mysteries, and this is one of them. While I agree with the author sentiment on whiteboard interview to some extent, I may have some insight on the reasons why he never passes them. Sorry buddy.
Truth be told, pair programming, test driven development, denigrating recruiting practices and ruby on rail sounds very good on a blog, but all of it is no more than playing buzzword bingo if one can’t get shit done.
A good interview question ?
Asking to implement a List
Ideally you want to have a question with an relatively easy answer, but on which one can improve. For instance, a problem with a relatively easy solution of high complexity. Various heuristics can be added and/or discussed to make it perform better.
The interviewer can get signal pretty quickly because there is an easy answer and discussion can follow on how to improve. The problem is open ended, which allow good candidates to really show how far they can go. It also allow for discussion between the interviewer and interviewee, the kind of which help to asses how one works.
Don’t do that. Unless you want your candidate to suffer.
Especially for a ruby on rail position…
I love Gnome Shell, but was bothered by the amount of pixel wasted in its interface. The title bar of window is quite large, and the activity bar is always present. A maximized window still is unable to use a significant amount of pixels in the top of the screen.
This is a major pain on small screen, but even on bigger screen, MOAR pixels for my app is better. After all, the role of my desktop is to allow me to manage my apps in a convenient way. It has to be as discrete as possible.
Using a set of extensions, I was able to achieve the merging of the activity bar and the title bar for maximized window, but recently one of these extensions stopped working and the configuration of the whole stuff was quite complex and unappealing. So I created Pixel Saver, an extension that save brave pixels !
The goal is simple : merge the title bar and the activity bar when a window is maximized, in the most natural possible way.
To do so, Pixel Saver do not require any configuration, it fetches the configuration of your title bar and adapt itself accordingly. It is easier for the user, and produce a nice result. Activate the extension and it works !
|The title bar is completely gone and integrated to the activity bar.|
The extension integrate title bar’s buttons in the activity bar, and change the title of the application menu to reflect the title of the maximized window. Really, nothing more need to be said.
That is Awesome ! I want to install it !
Follow the guide :
git clone https://github.com/deadalnix/pixel-saver.git
# copy to extensions directory
cp -r email@example.com ~/.local/share/gnome-shell/extensions
gnome-shell-extension-tool -e firstname.lastname@example.org
Easy ! I hope to get it soon into gnome extension’s website.
A bug report ? A pull request ? Go on the Pixel Saver github’s page !
Happy Pixel Saving !
A tagged union
Sometime you have some data that can be of type A or B. Very common use cases include decoding various file format or network protocols, communicate with memory mapped devices, some processing that can return an A or a B depending on its result, and many more.
To resolve that issue, it is common to use a union. A union is a aggregate where all members share the same memory. It is very handy, but use it wrongly and you end up badly messing up your memory. I’ll demonstrate in this article how to make this safe in D.
Developers want code that runs fast and users do too. However, it is easy to fall into the trap of early optimization; this story shows that even in non-trivial cases, modern compilers can do wonders. On the other hand, the myth of the “sufficiently smart compiler” is still very relevant. The best way is to look at what is actually generated for an example and that is what I’ll do in this article. Enter the SentinelInputRange.
OOP is known (or should be known) as a behavioral abstraction. It nicely solves a vast variety of problems, but enforces on the programmer an abstraction that doesn’t fit every problem. The fact is, you sometime need objects as data abstractions and not behavioral abstractions.
This is commonly the case for tools that manipulate code. A parser typically returns an AST that will be processed. The processing can be compilation, code formating, code analysis, and basically any other use related to source code manipulation.
Following regular OOP principles, manipulations have to be implemented by the AST node classes. This is a problem, because it prevents any 3rd party developer tool to reuse an existing parser and AST. The known solution is to use the Visitor pattern, which allows to dispatch in our code according to the AST node’s type.
The Visitor pattern has many known problems, to the point that many consider it an antipattern. A better solution using D has to be proposed.
Linux (as other UNIXes) allow you to register handlers for signals. Here we are interested in SIGSEGV. This signal is sent to your program when you try to use a memory location you shouldn’t. Typically, when deferencing null.
Language like Java send a NullPointerException, that can be caught and you can recover from it. However, in a system language, you usually get a cryptic « segmentation fault », you cannot recover from it and cannot have any information about it outside a debugger. Let’s see how we can fix this.
As C++ and D are system languages that support exceptions, we will use this mechanism to handle SIGSEGV. I’ll do it in D in this post, but the same is doable in C++. If you understand why it work, it shouldn’t be a problem.
Duplication is probably the #1 enemy of clean code. Its presence make the code harder to maintain, harder to evolve, more bug prone, harder to test and probably eat babies every morning. If almost any developer will agree on that fact, me can also notice that almost every codebase is crippled with repetitions in the code. How could we explain that ?