Posts

Checked exceptions break composition

A.K.A. Always Throw Runtime Exceptions or their subclasses A typical Java or C++ function can potentially come with an exception specification: for example, a method can declare that it throws exceptions of a particular type (eg. IOException, std::bad_alloc etc.) and clients need to handle that exception being thrown with a try-catch block. This seems good at the outset till we spend time thinking through what this does to the type of the function. A typical function in a happy-go-lucky world either succeeds or fails with an exception because of something beyond its control. If it succeeds, it returns with a value of the provided return type (let's call it SuccessValueType). If it fails with an exception (eg. a file read error or a mem allocation error), it throws the exception and the error handling parts of the code run. In type terms, the return type of the function is Either<SuccessValueType, RuntimeExceptionType> (where the RuntimeExceptionType is an implicit return ty...

IO numbers that everyone should know

In the Numbers Every Programmer Should Know , one set of numbers that I've always found missing were IO numbers (HDD vs SSD - random reads / writes). I found a really good source on StackExchange  for these numbers and for the sake of posterity, I'm documenting this here (for me and for you): SSD | HDD Sequential Read/Write : 700 MB/s+ | 115 MB/s (6x diff)  SSD | HDD Random Read 512KB : 160 MB/s | 39 MB/s (4x diff) SSD | HDD Random Write 512KB : 830 MB/s | 57 MB/s (14x diff) SSD | HDD Random Read  4KB :  27 MB/s  | 0.5 - 1.5 MB/s (17x diff) SSD | HDD Random Write  4KB :  135 - 177 MB/s  | 0.7 MB/s (192x+ diff!) The bottom line is that unless you're thrashing the HDD with lots of 4KB random writes, the HDD should not be tapped out till about 30+ MB/s (and an SSD should be just fine till about 150 - 300 MB/s ). If you're seeing an HDD tapped out at 3 MB/s, then you're either not writing sequentially or your block size of writes is too small. If you're seeing an...

Modern Programming: never use Inheritance; use Composition instead

Inheritance vs Composition is an age old debate. The world has evolved enough that it's time to put this discussion to rest. There is no good reason to ever use inheritance in new code. Composition is functionally identical to Inheritance, produces superior outcomes, flatter class hierarchies and more flexible code than inheritance. Composition also does not violate encapsulation and avoids classes of issues produced by unexpected polymorphic dispatch to implementations. We get better class design for free as well.  In short, never use inheritance - always express the same code re-use through composition and be happy. Let's go through each of the points one by one: 1. Composition is functionally identical to inheritance. This one is easy to work with. When inheriting implementations, all subclass methods have an implicit parameter (an instance of the superclass). Composition just makes this parameter explicit as a constructor argument and takes away the superclass. Code reuse t...

Managing Humans with Math

I was in a funky corner of the internet, reading about reinforcement learning when I chanced upon this article that compares a number of reinforcement learning algorithms. Since we as humans are glorified neural networks amenable to reinforcement learning and companies are nothing but hierarchical relationships between humans, it was very interesting to go through that article with a business point of view. Long story short, the article figures out various conditions in which the algorithms are able to break down a task recursively, the optimality convergence conditions and the "knowledge" required of the lowest level agents to learn successfully. From my reading of the article, I'm most drawn to the "Options" style of management: work with high quality people, give them maximum freedom to act and step in only at decision points. This is the style of management that I'd grown used to at Google (and that I've seen work really well there) and is quite in ...

Hermetic MySQL in the modern world

So you're looking to run a MySQL docker instance without any environmental dependencies? Here's how to do that: $ docker run --name mysql-test -e MYSQL_ALLOW_EMPTY_PASSWORD=true -e MYSQL_DATABASE=testingdb -e MYSQL_USER=scott -e MYSQL_PASSWORD=tiger -p 3306:3306  mysql/mysql-server:latest Documentation on the various environment variables are located here: https://hub.docker.com/_/mysql   To connect to your MySQL instance without depending on my.cnf: $ mysql --no-defaults --host 127.0.0.1 --port 3306 --user scott --password --protocol tcp testingdb That's it. You have a running instance of mysql from a docker image and you're connecting to it with a generic mysql command line client. Have fun.

Alerts should be actionable a.k.a.: Do not email on success!

Following the Unix philosophy: Do one thing, do it well and be quiet about it. In software engineering, if you're writing a system that's useful and suddenly, one day, you think it's nice to notify users via email that their useful thing is being done, you're making a mistake.  Emails from software systems should be actionable: if a system is sending an email to a user, it should be helpful, provide enough context about who it is, where it's running, who owns / runs it and what the problem is that requires human attention. Ideally, the alert email should clearly specify the next steps and the dashboards that can be used to ensure that the problem is fixed. The worst offense of the system is to send out success emails. This fails on 2 counts: 1. Success emails are not actionable - if I read a success email, I am informed and I promptly create a Gmail filter to never see another success email from the system again. The system made me do active work to ignore it. 2. Su...

How to debug a crashing docker container

If want to run your docker process with some tweaks because it's crashing in your docker container and causing the container itself to stop (without giving you a way to inspect the files on the image), here's the magic command to start it with just bash. (I found this after quite a bit of hunting on the internet, the magic flag is --entrypoint and don't forget the -s at the end) Here's a sample command: docker run -it --entrypoint /bin/bash  $IMAGE -s Sourced from: https://vsupalov.com/debug-docker-container/