Every time I upgrade Postgres major versions, I need to google for these steps. This usually happens after I’ve run brew upgrade and my database stops working. Here are the steps for future reference.
I was working on a personal project and feeling guilty about not writing enough tests. The two are different enough that no one should feel guilty for skimping on tests for their personal project.
Once a service is running in production, it never gets turned off. Decommissioning a service always ends with realizing some unknown party was using it and still needs it for their job. The standards for testing should be higher.
You’re not the only person working on your project. There’s no better way to communicate to your teammates how you expect code to behave than good tests. Having a unit test for a ticket makes it harder to reintroduce the bug.
If you’re starting a new service from scratch, testing should be a part of your project from the beginning. Pick frameworks that are easy to test. At work, we don’t use any Go router frameworks. They’re a huge pain to setup before each test.
In your personal projects, you’re the only person working on it. If you stop, it’s more likely to be abandoned than passed to another developer. It’s hard to justify tests if the project might not last a year.
Unless you’re a pro at project management and have strict requirements, your side projects are going to have higher code churn than at work. How can you justify writing acceptance tests for a web page whose layout is constantly being tweaked?
Test as much as you can, but don’t beat yourself up over it.
My dream for the internet of things is a bunch of different devices coordinating with each other. My air conditioner, humidifier, and dehumidifier should all work together to keep my apartment climate controlled and prevent me from ever having dry, cracked hands ever again. Having connected devices work together feels so far away. As we baby step towards my dream, here are some rules all internet of things devices should follow.
Washing machines and refrigerators can last ten to twenty years. Your 1985 Nintendo probably still works. Electrical components don’t degrade like mechanical components do, so the internet of things devices need to last at least as long as their mechanical counterpart.
All devices need manual controls. If the internet is out or if a storm is making the internet unreliable, the smart device should still be useable. Your Juicero doesn’t need to connect to the internet to squeeze a packet of juice.
If the wifi on my refrigerator breaks, I can’t take it into an Apple store without renting a truck. Even worse, I probably bought an LG fridge, and LG doesn’t have stores at the local mall. The smart parts of appliances need to be replaceable by the owner or be a separate module from the appliance. Also, if I detach a smart module from my refrigerator, the refrigerator should still work.
Servers store two versions of their firmware, the latest update and the previous update. When you install a firmware update, the server overwrites the older update and boots from that location.
To ensure it lasts, the devices, their api, and the hubs that control them need to be open source. Ideally all companies would open source their device software when that device reaches end of life. That’s never happened, so we need internet of things devices to be open source from the start. If you can’t recreate a device’s server features in AWS, it’s worthless.
We can’t have an app for each device. Devices need an easy to use API and support for the most common hubs.
Configuring a smart device should require pairing with the user’s computer or phone. If the device requires connecting to a service, make the user create an account or tie the account to the phone app. Unconfigured devices shouldn’t be allowed access outside the user’s home network.
Internet of things devices need to improve your life instead of measuring it. I don’t need to know how much water I drink every day. I don’t need a smart pillow or a smart bed. Not now. Not ever.
Not everything needs to be connected. Somethings can be dumb.
It’s maddening to have expensive light bulbs with wireless chips instead of expensive lamps and ceiling fans and cheap led bulbs. I get that it is easier to convince people to try out smart light bulbs when they don’t need to rewire their home, but the market has been proven. People love programmable light bulbs that can change color. Light bulbs are going to burn out. They shouldn’t be expensive. They shouldn’t be wireless.
We don’t need more wireless things. All of our wall outlets are going to be USB-C someday. Someone needs to start building the products that take advantage of our fast, low powered, wired future.
The power is out. I want to write a blog post, but the only thing worth talking about this week is Susan J. Fowler’s story about her awful year at Uber.
My friends will share her story commenting that “if this is true, it’s damning.”
I’m convinced it’s true.
Even at our favorite companies senior managers will harass female employees and those companies’ employees eventually find out that HR exists to protect the company from liability and not to help them.
Hiring people with a strong sense of entitlement very rarely works out, no matter how good they are on other axes— Sam Altman (@sama) November 30, 2016
The absolute opposites of an entitled employee are the apprentices in Jiro Dreams of Sushi. The apprentices have to work for ten years making rice and doing other menial tasks before they’re allowed to make a dish. Jiro’s desire for perfection really shows his dedication to his craft.
The film paints a portrait of an exacting patriarch who demands perfection from himself, his sons, and the hard-working apprentices who work up to 10 years before being allowed to cook eggs.— Influence Film Forum
Although… why would anyone put up with that? If you were even a mediocre chef, why would you toil under Jiro instead of creating your own restaurant or being a more senior chef at another restaurant? Only two types of employees will apprentice with Jiro, the sushi fanatics and the people who can’t find a job anywhere else.
Sam Altman wants employees who have no where else to go.
Scala finally clicked. It took a year of writing production code with it and completing Coursera’s Functional Programming Principles in Scala course (lucky me, it’s taught by the creator of Scala, Martin Odersky). When I got to the programming exercises in the Scala chapter of Seven Languages in Seven Weeks, I wanted my code to follow every Scala principle. I wanted to only use immutable variables and use functional programming components instead of for loops.
Here’s my tic tac toe code in its entirety. You can run it using Scala’s REPL. I didn’t want to spend an entire weekend optimizing it, so this is the first complete version. I’ll tell you why it sucks at the later.
I’m pretty proud of it. It highlights the best parts of Scala which are the case classes, match statements, and decomposing an object in a match statement.
Case classes are like fancy, extendable enums. They can inherit from other classes, override default methods like toString, and have new methods. We can create a fake-enum type by having our case classes inherit from a Player base class.
Case classes can have constructor arguments. This lets us associate a value with the enum.
Match statements are like fancy switch statements. They evaluate in order and can include additional logic. In Scala the underscore is the we don’t care character. In a switch statement it will always evaluate. Because it’s always evaluated, it should always be your last case match.
Match statements can also decompose an object into variables for you if it matches a specific format.
In our move method, we use a match statement to split a List into its head and its tail. Outside of a match statement the line head :: tail is appending head to the front of the List tail using the :: operator. Match is checking if your variable could be deconstructed to match this pattern.
We check that the head, the Tile at the specified location, is empty. Then we insert a new tile. Any operator beginning with a colon is right associative. head :: tail will insert head at the front of the List tail.
Below is the same code refactored to show which variable is calling the method.
Maybe our board should’ve been a Vector of Tiles instead of a List. Lists in Scala are linked lists. Linked lists are great if we want to have immutable collections, but it’s kind of hard to think about when it’s new to you. Vectors would’ve let us access tiles by their index and simplify code.
For example, we need to iterate through the List to the tile’s location to check if a it is empty or not. This is only optimal if the user’s input is valid. If the input is invalid, we have to iterate through the list multiple times. If we used a Vector, we could create a separate method to check if a move is valid instead of trying to save operations by shoving the check into our move method.
Using a Vector to check if a move is valid would fix another problem. Our game loop is recursive. Because we catch invalid input for the moves in a try catch block, it’s not tail recursive. When we call playGame, the code in the catch block could still execute. Tic tac toe has at most nine moves. If our game was more complex, we could actually cause a stack overflow.
Overall, I think using immutable values made things more complex. I spent most of my time writing the gameState method. I wanted to use Lists and foldLeft to build the results. If I allowed myself to use mutable values, I would have just used a for loop to check each of the rows, columns, and diagonals for a winner.
…you should read “Developer hiring and the market for lemons” by Dan Luu about the four dumb excuses companies give for not being able to find good employees. It’ll make you feel better about how arbitrary it all is.
One of the biggest threats to your startup are junior people who bring the germ of big company bogusness.— Paul Graham (@paulg) March 6, 2016
Some things shouldn’t be tweeted. Opinions with nuance need complete thoughts. We can assume Paul Graham meant something very specific that we can’t intuit from his tweets.
But we’re not going to do that. Because fuck Paul Graham.
Here are some things big companies are better at than startups.
HP was my first job out of college, and I worked there from 2008 to 2012. It was huge, corporate, and everything a sane person should hate in a company, but I also learned a fuck ton.
Every year at HP, we had to watch an hour long video on ergonomics and take a stupid test to prove that it took. If you didn’t complete the video, your manager would get an email about it. Then his manager. I didn’t let it get any further, but it would have trickled up to the CEO.
At my company, our interns have a week of learning about our programming languages, build tools, and culture. If ergonomics is shoved in there, it doesn’t take. Their posture is horrible.
My coworker complained about back problems. Instead of ergonomics training like HP would force upon you, our supervisor agreed to let them work from home mornings (my company really discourages working remotely), and it didn’t help. They never learned how to setup her desk.
There has to be a balance between boring videos and never teaching anything. Maybe IT could give employees a pamphlet when they set up their desk.
The biggest difference between junior developers and developers is being able to split a big task into smaller tasks. The younger you are the less you know about how long something should take to complete.
On a Rails app, I’ve seen someone try to switch the UI from Erb templates to Ember, update the models and their relationships because the old structure didn’t make sense with the UI, change the UI to match a new mockup from our UX designer, and move to Active Model Serializers all at the same time. After three months, they had a gorgeous new UI that was still unusable. They did good work, but it was never merged because it was always incomplete. They needed someone to direct them, and not let them bite off more than they could chew. Their failure was our fault.
At big companies you have a dedicated project manager and are forced to split your tasks into measurable chunks. When I was a consultant, our estimates for each ticket were measured in hours. No ticket would take more than 24 hours or it would be split up into smaller tickets. Junior developers need that guidance until they learn how to do it naturally.
Maybe I was lucky, but my manager at HP knew what he was doing. Eden saw his job as facilitating my development and getting out of my way. If something was critical, once a day he would stop by my desk and ask if I needed anything. He excelled at leaning on other teams to do their job when we were waiting on them.
At the startup where I work, communication between teams that don’t regularly work together is still… hazy. I’m working on ads. Another team is working on a new project. My manager proactively sends me to reach out to them about their ad needs. They don’t need us. The first ads will be native. A month later our team, discussing with the ad trafficking team, decides to serve native ads through Google DFP to track clicks and impressions. We release the first native ads on our site. Now when that other team starts working on ads, they’ll circle back to us. The roles aren’t defined, so there’s misdirection and wasted time.
I work on the ad rendering. What happens whenever anyone ever wants to make a change to something that sorta, kinda touches our code? We’ll give them a 30 minute overview of how our code works and… they’ll realize that we’re not the team they need to talk to.
This is a fun conversation that you can in the world of startups.
Tester: “Your branch is producing some weird logs. When are these events supposed to fire?”
Staff Engineer: “I don’t know. How does it work in master.”
Three testers start regression testing, comparing the two branches
Let me suggest that the biggest threat to startups is out of touch VCs who convince you to ignore a huge market of skilled developers.
Paul Graham is responding to clarify that it's junior developers that are a problem and senior developers and the hiring managers know the risks and what they're getting into. That... doesn't... make... sense. Junior developers are way more adaptable than older developers.
Holy fucking shit. This is propaganda. When I think of a big company, I think of HP and IBM. Not Paul Graham. Paul Graham is shaming college kids to keep them from joining Facebook, Google, and Apple. There is a shortage of qualified developers, and Paul Graham is trying to keep Y-Combinator founders and future employees of Y-Combinator companies from joining big companies. Fuck you, Paul Graham.
Hey I fixed that new hot meme ya'll are sharing pic.twitter.com/2eZvANvK7p— Make Fyles (@thealphanerd) March 7, 2016
Blake Ross, Firefox wunderkind, has the best analogy for the Apple versus the FBI debate.
There is a slim chance that there is data on a terrorist’s work phone, and the FBI wants Apple to allow a backdoor key.
An airline pilot locks the other pilot out so he can crash the plane into a mountain, and the airlines don’t add a backdoor key to the cockpit door.
They understand that there are too many bad people trying to get in, and it’s so rare that a good person is trying to get in that it’s not worth risking security with a backdoor key.
The security we encounter every day — when it works at all — is usually built out of shades of gray: Lock your door. Need more? Arm your alarm. Even more? Don’t feed Fido for a day. Marginal benefits, marginal costs.
It’s easy to assume that digital security is just another spectrum, and politicians love to reinforce that — gray’s their favorite color. Every presidential candidate is offering the same Michael Scott solution: Let’s preserve everyone’s security at once! Give a little here, take a little there, half-pregnancies for all.
Unfortunately it’s not that complicated, which means it’s not that simple. Unbreakable phones are coming. We’ll have to decide who controls the cockpit: The captain? Or the cabin? Either choice has problems, but — I’m sorry, Aunt Congress — you crash if you pick 2.— Blake Ross
A project usually has a single gamble only. Doing something you’ve never done before or has high risk/reward is a gamble. Picking a new programming language is a gamble. Using a new framework is a gamble. Using some new way to deploy the application is a gamble. Control for risk by knowing where you have gambled and what is the stable part of the software. Be prepared to re-roll (mulligan) should the gamble come out unfavorably.— Jesper L. Anderson on Medium
Jesper, who freaking tests distributed databases and other systems, has much more specific advice on how you should build your apps. He has good advice. Read it. (I promise not to make you write Erlang)