I’ve been doing a moderate amount of native Win32 C++ programming over the past few weeks, and occasionally I’ve needed to set up some debug points to print errors that occur during file and memory I/O.
When something goes wrong inside the Win32 API, some methods will return a system error code directly (such as all of the registry methods) and others will simple return a NULL pointer or a 0-length DWORD and require you to poll the GetLastError method yourself.
Unfortunately, these error codes are just long integers (DWORDs) and don’t contain any of that human-friendly information that I’m used to for .NET exceptions.
I created a Gist on Github that shows how we do it and have also included the code below:
DWORD dLastError = GetLastError();
LPCTSTR strErrorMessage = NULL;
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_ALLOCATE_BUFFER,
//Prints debug output to the console
If you enjoyed this post, make sure you subscribe to my RSS feed!
This post is about how to find success in any situation and draws entirely from my own experiences. Your mileage may vary.
July was a rough month for me this year – I endured simultaneous failure on all fronts. I had put on a shitload of weight, ended a relationship, and market conditions changed unfavorably for MarkedUp. All of this occurred within a couple of weeks at the tail end of the month.
I am well-accustomed to stress and handle it well. I’ve had things not go my way before, and I’ve always found my footing again.
This time something was different. Maybe it’s because of how deeply invested I am in MarkedUp or because of everything going wrong at once, I don’t know. But the difference this time I walked away with a major dent in my self-confidence and self-sureness. That’s a new one.
I wasn’t even aware that my confidence took a dip at the time. I figured that out more recently, when I started noticing a huge increase in my anxiety and apprehension when it came to routine things.
I started asking myself, “wait a second – this shit never used to bother you. What’s changed?”
Then I remembered the truth. Let’s flash back a few years.
An Unusual Habit
I was an immensely awkward kid my first two years of college. You know the formula: under-socialized kid who spent more time in front computers than people during his developmental years suddenly thrust into a co-ed dorm with babes and booze aplenty, 2,000 miles from the nearest person he knows, unsure of himself, finding his way in the dark.
In particular, I was utterly terrible with women. Terrible enough that my Freudian defense mechanism kicks in with full force when I try to relive the full horror of my own awkward blunders with the opposite sex. Jesus.
Second semester freshman year, I discovered alcohol and spent more time partying than studying, receiving poor grades for the first time in my life.
When Sophomore year rolled around my advisor put the ever-loving fear of God into me that if I did not clean up my act then there was no chance I’d ever make it to a decent Computer Science graduate program. I immediately dropped the partying and focused on my school work, and somehow my social life managed to get even worse than it was the year before.
Worst of all, my grades improved but not by a big enough margin to move the needle. I still wasn’t succeeding. Failure on all fronts. Sound familiar?
So I made a decision.
At the very end of Sophomore year, I signed up for study abroad the following summer in Berlin, during the 2006 World Cup.
None of the people on that trip from Vanderbilt knew me, and certainly none of the other students in Berlin. I had a clean slate, and since I had fucked my last one up during freshman year of college, I was going to do things right this time, damn it.
The decision I made was simple: I would not give a single iota of shit about my schoolwork and not take myself seriously. And drink beer. Can’t forget the beer drinking.
The results were astonishing: I had an easy time making friends, socializing at parties and clubs, and my grades were actually pretty good to boot. FWIW, alcohol tolerance was insane by the time we left Berlin, but we’ll save that story for another time.
So I doubled down at the start of junior year. I decided I would not care about anything other than getting the most out of my college experience. I joined a fraternity, took graduate-level courses, dated some fun and interesting women, and pretty much felt like a bad ass. My GPA junior year was a 3.8 – and the amount of effort I put into my schoolwork was a fraction of what I had put in the year before.
Senior year, same thing – I stopped giving a shit about everything by default and with the confidence that I could turn any situation in my favor when I needed to. And I did.
By the time I left Vanderbilt, I felt like a bad ass. But when I entered the real-world and got a job, everything changed. I had to start all over again and build myself back up piece by piece.
Set Your Own Odds
The point of that story is that my ability to succeed personally, physically, and professionally was inversely related to my level of emotional investment into whatever I did. It was that way all along.
I still put in a lot of hours on my school work, I worked out often at the gym, and I spent a lot of time trying to come up with fun ideas for dates.
I put a high level of effort into things that mattered, but for very different reasons than my freshman and sophomore year. I put effort into those things because I wanted to, not because I felt like I needed to.
Not giving a shit simply means doing what you want to do without any emotional investment in the outcome. Put differently, you gradually develop habits to counter your mind’s self-protective “flinch” reflexes.
Negative outcomes and consequences were still possibilities with everything I did, but I hardly thought about them. After all, I live in a part of the world where it’s considered a really bad day if you lose Internet access for 24 hours – what’s the worst that could happen, really?
Once you stop worrying about the negative possibilities, every opportunity has nothing but upside. Ask the cute girl / guy at your gym out for drinks – the worst thing that can happen is a slightly awkward story that you and your friends can laugh about over drinks later. It’s all upside from there.
Stop giving a shit. Stop caring about what other people will think about you if you fail. Worry only about what you’ll think of yourself if you don’t try. No one likes a pussy.
Bold without Knowing It
So, jumping back to the present. Once I realized what was going on, I ran through my process for putting my brain back into “don’t give a shit” mode:
Work towards concrete goals – we can’t control our calendars and circumstances at every given moment, but we are always in charge of deciding what’s important to us. Remember what those goals are. Create a path for realizing them. All of them. Follow it. Even if it takes years. Ignore everything else.
Step into every punch – an old boxing metaphor; if you’ve ever tried boxing, your first natural reflex when someone tries to punch you in the face is to jerk your head back out of the way.
If you let that happen, you drop your cover and leave your face exposed, which allows experienced boxers beat the shit out of you.
So the antidote is to train boxers to step into their opponents’ punches with their guards up and use counter attacks or controlled evasions, instead of flinch reflexes.
The same goes for every day life – when your chest tenses up right before you send a critical email, condition yourself to just press send and don’t think twice. Do the opposite of what your pain-avoiding reflexes tell you.
Practice taking risks – read my full post about the subject. Start habitually taking risks on small things, so you’re prepared for the really important stuff in the future.
Decide how you want to react to things – from the Seven Habits of Highly Effective People: “you can’t control everything that happens, but you can always control how you react to them.”
My (chosen) default response to most things: “meh.” Celebrate victories and learn from defeats, but don’t dwell on either.
Find the upsides – as mentioned earlier, every day risks offer very little for us to be afraid of beyond mild embarrassment and maybe some financial / temporal setbacks here in the comfortable first world. So look at your opportunities, even the small ones, and use the upside as your primary decision making metric, rather than fear of failure. You’ll make bolder, better decisions that your 80-year-old self will appreciate.
Find the things you like about yourself, then show them off – there’s an engaging, interesting person inside all of us. Find him or her and let the rest of the world in. Me? I’m pretty sure I can make just about anyone laugh.
So even though this post makes me feel a little vulnerable and reads like dust jacket of a self-help book, I’m publishing it anyway. If it helps someone else find their stride, that’s all that matters to me.
Nothing ventured, nothing gained.
If you enjoyed this post, make sure you subscribe to my RSS feed!
It was about four or five years ago that I had an intrinsic need to be “right” all the time.
I couldn’t let it go when someone made a mistake, or slighted me, or disputed the quality / direction of my work. Everyone else was wrong. I wasn’t alone in this regard either: a number of the people around me did the same thing.
Being right made me feel superior; it made me feel better than the idiot who did that thing wrong; it made me feel moral; it made me feel righteous.
When someone made a mistake, I felt compelled to point it out – even if it meant interrupting a speaker’s presentation during a team meeting. People started spending a lot more time perfecting their talking points and PowerPoints – time that should have probably been spent on something that actually impacted the bottom line for the business.
When someone criticized my work, I deflected their criticisms or manufactured my own reasons for why their criticisms were invalid. My work is a fucking masterpiece, after all. The quality of my work didn’t improve, and I didn’t learn anything unless it was the hard way. People didn’t care about what I had to say about their work either, since they knew I didn’t listen.
I went throughout all of my work fervently believing that what I was doing was correct and righteous – there was no room for self-doubt in this guy’s super powerful brain. I made a lot of mistakes that could have been avoided, and looked the part of the arrogant idiot on a climb-down after each one.
But at least I was “right” and everyone else was wrong.
I have an assertive personality, so my need to be “right” manifested this way. You can easily substitute this with passive-aggressive behavior, which is what most “right” people do.
My life changed early in my career when one of my mentors dropped the following bombshell on me after I had a friendly but needlessly assertive altercation with another employee:
You can choose to be right, or you can choose to be effective. It is a binary choice. You pick one, or the other. They are separate circles on the Venn diagram with zero overlap in between.
I choose “effective” every time.
There hasn’t been a day in my life since, nearly five years ago, that I haven’t said this line to myself over the course of any given day. “You can choose to be right, or be effective.” I don’t always make the correct choice, but I’m a thousand times more effective today than I was five years ago.
I stopped caring about people’s small mistakes. And if I did care, it stopped mattering to me who made the mistake or who fixed it; as long as we took care of it.
People became less afraid of sharing their ideas with me and more empowered in their roles the longer we went without the appearance of the “You’re wrong, I’m right” stick.
If someone took issue with the way I was doing something, I would break down the problem for them and ask for data-supported suggestions on how to do something better. In many cases, their criticisms were valid and we changed whatever I was doing. Other times, their suggestions were based on bad data and we didn’t implement them. We stopped taking it personally.
Gradually, everyone put their weapons down and became less worried about accepting, acknowledging, and offering criticism. People began to share their successes with each other, and everyone felt good.
I stopped worrying about if I was doing the “right” thing when it came time to take care of business – I did the best I could, owned up to any problems I created, and tried to fix them. I gave myself some room to question whether I was doing the most effective thing at any given time.
People in the office became less afraid of making a mistake and tried new things. People offered a simple “well, that didn’t work – my bad” when something went wrong, and people stopping caring if it did. We became simultaneously more productive and accountable.
Being comfortable with yourself
The contrast is drastic between the “right” period and the “effective” period. The team became a “we” once people stopped caring about being right. Everybody felt a lot better and accomplished a lot more.
Those changes pale in comparison to how my feelings about myself changed. I no longer felt superior to anyone – because I stopped needing to. All of the feelings of superiority and righteousness that come from being “right” are a façade that hide internal weakness and insecurity.
When I changed my goal from preserving my own sense of superiority to just trying to do the best I can, everything became much more impersonal and objective.
Ultimately, this shift in priorities helped me become radically more comfortable with myself. There are still things that bother me and things I feel aggrieved about, but I rarely do I think about who’s right and who’s wrong anymore. There’s simply nothing to gain by it.
I owe every thing good that’s happened to me since I graduated from college to this change in thinking. It’s empowered me to become a leader and made me much more comfortable in my own skin than I was just a few years ago.
Being “right” is a war of attrition waged by the weak against the strong; it’s designed to systemically give weaker people leverage over others by gradually instilling doubt and undermining moral authority.
Comfortable, strong people will recognize this behavior for exactly what it is: whimpering and squeaking from small people who feel like shit about themselves.
When you stop needing to play the “who’s right and who’s wrong” game, every encounter you have with a “right”-minded person makes you think “there’s a piece of work; probably not going anywhere fast.”
You can choose to be right or be effective. Being right is always the wrong choice.
If you enjoyed this post, make sure you subscribe to my RSS feed!
Our engineering team has been neck-deep in configuration hell lately. Editing 2000-line Solr configuration files, trying to get Apache Oozie integrated into DataStax Enterprise, Cassandra 1.2 upgrades, and more – and the one thing in common with all of these tasks is the prevalence of enormous XML configuration files.
Having wasted countless hours trying to use tools like SCP and various Sublime Text plugins to try to edit (or hell, even view) the configuration files on our dozens of Linux machines, I finally had a “fuck this shit” moment this week and wrote instant-fileserver, a stand-alone file server that you can start using a single command on any directory on any operating system.
instant-fileserver (ifs) allows you to:
- expose the contents of any file system via HTTP;
- view individual files as well as directory listings;
- create, read, update, or delete any file using ifs’ dead-simple RESTful API;
- create multiple ifs instances using a simple command; and
- safely edit any file from the comfort of your Windows / OS X machine and push the results back onto your Linux servers once you’re finished.
$ npm install -g ifs
$ (ifs is added to your PATH; go anywhere on your system)
$ ifs -help
$ ifs [arguments...]
... starting ifs on 0.0.0.0:1337
Here’s a quick demo video to show you how easy ifs is compared to the alternative
Using Instant File Server (IFS) – Video Demo
If you hate having to move heaven and earth to do something as mundane as edit a damn file, IFS is the werewolf-destroying silver bullet you desperately need.
ifs is built using Node.JS and it has a tremendously slim codebase, so anyone can edit it or extend it if they wish. ifs is licensed under the MIT permissive license.
Fork the ifs source code on Github – we accept pull requests!
If you enjoyed this post, make sure you subscribe to my RSS feed!
I spoke at the Cassandra Summit this year about how we use Cassandra, Hive, and Solr in production at MarkedUp Analytics.
Planet Cassandra recently made all of the videos and slides available and I thought I would share. Enjoy!
If you enjoyed this post, make sure you subscribe to my RSS feed!
This post is about stress.
It's been nearly a year since I started MarkedUp Analytics, and we've come a long way - I've raised money, won the business of some amazing customers, built the nucleus of a really talented team, and developed a product that people rave about. At the previous //BUILD conference, no one had ever heard of us - this time our logo was shown onstage during a keynote. Feels like progress; none of it was easy.
I took my first vacation in two years last week and had a chance to put some distance between myself and MarkedUp for the first time since inception, and I thought a lot about some of the assumptions I had about starting a company when I was just getting started, in particular this section from "The Seven Unproductive Habits of Startup Founders:"
7. Sacrificing nearly all social, physical, and personal needs in the name of “getting it done”
You can push yourself to a large volume of work over a short period of time – you can cram 80 hours into a work week if you can try. But you can’t do it forever.
You know what a successful entrepreneur needs?
They need to work out and get sleep so they can maintain their stamina and energy level. They need to go out with friends and blow off steam. They need to go out on dates. They need “me” time to collect themselves.
Creating a balanced life takes discipline – I dropped the ball on this epically at Microsoft. I starting changing my behavior before I left Microsoft and it’s made me more effective and productive.
Counter point: I've put three inches on my waistline since we went live with customers on September 29th, 2012. I stopped working out within a week of our product launch and burned the candle from both ends often since. It's been nearly 300 days since I last synced my Fitbit. My diet consists largely of whatever-I-can-get-in-5-minutes choices, which doesn't correspond well with healthy ones.
Why did I not heed my own advice?
Adding customers as stakeholders to your product produces an immediate and intense set of external pressures on your company. The timelines for delivering everything increase by an order of magnitude and the pressure can be so tremendous that it can crush some employees and founders like empty beer cans. Add investors and a fixed amount of operating capital to the mix and it intensifies the pressure and the timelines by another order of magnitude. Even if you don't panic, you have to move and act like you are.
The immediacy of it all never goes away; it's there waiting for you when you get home; when you sleep; when you're in the shower; when you're out with your friends; when you're in the car; when you're with your family; when you're alone. You are damned by the contents of your inbox; the social media mentions; the Github issues list; the sales inquiries; the status updates from your teammates; the error rate alerts from your monitoring systems; the bid alerts from AdWords; the investor email updates; accounts payable; quarterly taxes; insurance; rent; lawyers; accountants; interviewees; PR; fuck. Your life quickly becomes a list of things you failed to do when you intended to do them.
You can never distance yourself from the pressure; there's no one to cover for you. You are haunted. You are cursed. And if you don't stop running as hard as you can to keep up, your company dies, your hopes and confidence with it.
At least, that's how it's felt for the past 8 months.
Your salvation is in accepting that you can never do all of the things and everything always takes longer than you anticipate. In your role as a highly accountable person you have to give yourself permission to leave things in an incomplete state each and every day. The stress you experience throughout your life is an unconscious choice to self-flagellate and self-punish. It may feel real, but isn't.
You will always harbor doubts; you will always have deadlines; you will always have some negative outcomes; you will have disappointments; and you will always have the ability to choose your priorities and act accordingly.
The inflection point for me was when I spoke onstage at a conference recently and saw just how large I looked in the recording, like one of those retired NFL linebackers who forgot to change his dietary habits after leaving the football behind.
So I wage a campaign against demons of my own making in order to reclaim my time and life. I will not judge myself or my company so harshly. I will not deny myself a glass of red wine with my girlfriend because we have a deadline. And I will get my ass back in the gym, even if it means coming into the office later each morning. I will not beat myself up over unread emails in my inbox, because there's no value in it.
Your accountabilities will always be there for you; what's left of your life and youth will not.
You'll have a list of things to do that is temporally impossible to satisfy; accept it and don't let it slowly strangle the other parts of your life like weeds.
Give yourself permission to go home with a full to-do list each day. Give yourself the permission to enjoy the things that matter to you but don't cross anything off the list. Get used to having people bitch at you for not responding to their emails ("my free time belongs to my kids," as one of my investors put it.) Who cares? Those feelings of guilt and shame are an illusion. Keep your priorities organized, your head clear, and your chin up.
If you enjoyed this post, make sure you subscribe to my RSS feed!
MarkedUp Analytics’s customers are developers and so are most of the people who work at the company, so I spend a lot of time thinking about and refining my answers to the following two questions:
- What are the lowest common denominator skills and programming knowledge that my customers have?
- What are the lowest common denominator skills and traits that the developers on my team need to have in order to best serve our customers?
As I’ve been exposed to more customers and as I’ve turned over members of our team I’ve started refining my answers to these questions.
Turns out that most of our customers are fairly sophisticated and thus I expect the developers on our team to be one step ahead of them.
I’m sure every company says this, but in our case it’s true: we need elite developers in order to solve our customer’s problems.
MarkedUp builds distributed systems that integrate into native third-party applications, written by our customers, on multiple platforms and use machine learning to create insights in as short a timeframe as possible, a task that’s many orders of magnitude more challenging than your average iPhone or web application.
There are companies like DataStax or Liquid Robotics that have to deal with radically harder problems than ours, and I’m amazed by their ability to attract really great engineering talent. So this problem is solvable, but how do I identify elite developers who are going to be able to contribute to the business and tackle these challenges?
I’m still figuring it out, and I’ve made some big mistakes along the way thus far. But I’ve had some successes in attracting great engineering talent to our company too. Here’s my opinion on what makes a software developer elite (your mileage may vary!)
An elite developer is determined more by their character, attitude, intellect, and diligence more than anything else. Knowing any specific framework, programming language, design pattern, development platform, and so forth isn’t nearly as relevant.
So what character traits does an elite developer have?
Humility – the best developers I’ve worked with know that they are talented but don’t know just how good they are relative to their peers. Even if they did know, it wouldn’t change their attitude. They do the best job that they can and do it knowing that their work isn’t perfect; contains bugs; might not completely meet the spec; and might be changed in the future.
Able to accept criticism – part and parcel with humility is the ability to accept criticism, whether it comes from a peer, a customer, a manager, or anyone else. Whenever you do anything of consequence you should expect criticism from some corner of the universe. Elite developers not only accept it, but they listen to it and try to distill actionable insights if possible.
Doesn’t let good be the enemy of perfect – a lot of talented developers struggle with perfectionism, myself included; over time the great ones learn to live with impurities and get software deployed to production while the perfectionists piss time away on remote edge cases and other activities with no economic value.
Inquisitive – some of our interview questions at MarkedUp are live-coding exercises, and here’s a little secret: we really don’t care very much about the quality of the code produced by a candidate during an interview.
But we care a lot about the questions a candidate asks about the programming challenge.
If a candidate starts coding right away without asking us any questions about the scope of the challenge or the technical details, it’s usually an instant fail. Inquisitive developers do a much better job of learning how their code fits inside a larger system and learning about the real-world use cases for it.
Independent learners – the developers who’ve delivered the most value for me are ones who constantly want to learn and improve their skill set; they ask if they can pair-program with me while I work on our API or on the SDK; independently review some of our code and create JIRA issues for me when they find bugs with my own code (!); they buy O’Reilly books on some of the technologies we use, like Hive and Hadoop, and read them over lunch; and they ask if they can leave work early to attend a tech talk or even give one themselves (!).
Everyone needs help along the way, but the truly great developers are the ones who learn for the sake of learning and the satisfaction of self-improvement. It’s humbling to work with this type of developer, because typically they get other members of the team excited about learning too and turn this into a group activity.
Able to break down large projects into small tasks – people don’t launch rockets or build massive systems by setting out to do everything all at once; they break down massive projects into smaller milestones and small, fine-grained tasks. Really strong developers have the ability to visualize the end in mind and the steps for getting there. It’s an essential skill for an architect of any sort.
Able to visualize relationships between abstractions – part and parcel with the previous point, really great developers have the ability to visualize relationships between abstractions in the systems they work with and build. This can be as simple as being able to see how services interact with each-other in the course of fulfilling an end-user’s request or how classes should be composed inside any given system. This allows a developer to work on a small part of a really large system and understand how their work will integrate with components that aren’t finished or haven’t been started yet.
Embraces challenges – great developers can operate outside their comfort zone, even if it means failing initially. Challenges are viewed as an opportunity to learn and improve, not as a threat to appearance and performance.
Focuses on immediate results – sticking with the previous analogy about launching rockets, great developers break up their work into small deliverables and ship small pieces immediately and frequently into a development branch. They don’t hoard commits or wait until “it’s done.” They ship small deliverables often.
The traits above are the most important ingredients of a great developer, but there are learned and acquired behaviors that every developer must develop before they can become elite.
Unconsciously, religiously commits everything source control – the greatest sin you can commit as a developer is failing to put something into source control for you deploy it. Most companies try to automate deployment in such a way that it’s impossible for deployment to occur without source control involvement, but this isn’t always feasible. Little things like shell scripts, SQL queries, configuration files, and others often fall between the cracks since they aren’t considered part of “the app.”
However, a great developer is religious in their use of source control – anything that gets used in the course of regular business, even a one-off business intelligence script, finds its way into source control when an elite developer is behind the wheel. They rack up pull requests and HipChat spam with religious fervor, because they live in perpetual fear of being the stupid asshole who forced someone else to reverse-engineer a critical backup / restore script during an emergency.
They master their source control system, make liberal use of feature branches and version tags, and clean up after themselves once a feature goes into production. Source control is as natural to them as breathing.
Writes README files, comments, and docs even for internal tools – I tell every developer this when they start at MarkedUp “your code will be a part of this organization longer than you will.” The point of that is that people change careers, companies, and jobs frequently – so when we write a piece of code that does something important, we need to make it possible for someone else to use and modify it without us present to answer questions.
Great developers recognize this and make it easy for other developers to leverage their work, during and after their time on the job.
Embraces bug tracking and agile processes – organizing your work is just as important as performing it, and bug tracking / agile tools like Pivotal Tracker and JIRA enable teams to prioritize and distribute workloads across large projects.
But more importantly, they allow PMs and peers to see what work has been completed / performed without having to hold numerous meetings or calls. Bug tracking, pull requests, and agile boards are communication tools – and great developers embrace them for efficacy in measuring, quantifying, and communicating progress.
Masters debugging, tracing, and monitoring methods – just because the code is in production doesn’t mean it’s finished. Great developers master the tools they use for debugging, logging, tracing, and monitoring apps that are in production or are about to be.
In the .NET universe, this means mastering the Visual Studio debugger, Fiddler, IntelliTrace, the Windows Event Viewer, performance counters, and others. In the OSS world this might mean performance monitoring tools like Graphite and Nagios, or others.
Great developers understand the necessity of these tools and master them, which enables them to respond more quickly to infrastructure failures and bugs.
Communicates concisely and asks relevant questions – most developers are not social butterflies; like any STEM field, it’s often populated with introverted people who like to spend most of their working hours concentrating on issues at-hand.
However, the elite developers are ones who recognize what needs and doesn’t need to be communicated – if there’s something contradictory in a customer spec, it needs to be raised with the stakeholder. If someone broke convention and used camel case instead of PASCAL, just go fix it and send the offender a note, not the entire team alias.
Engages other developers on the team – programming is a team sport, and elite developers love working with other people whom they can help and who can help them. They ask for and solicit help when necessary.
Now for the programming part – what skills does a programmer need to have before he or she can be considered elite? This is subjective and sometimes domain-specific, but there’s my take.
Experience with multiple languages and platforms – diverse taste in tools is the greatest skill that a developer can have, because it keeps the developer on a position where they know how to learn new things if necessary (and it often is!)
Being a one-trick pony and limiting yourself to a single platform will naturally limit your ability to grow and learn, so great developers try their hands at new things even if it’s just for fun.
Understands language / framework implementations – the most powerful .NET developers I met prior to joining Microsoft all highly recommended that I read this book: CLR via C#. I did, and the content from this book was directly responsible for passing my technical interview at Microsoft. Above that, it’s changed the way I look at all of my .NET code.
Understanding your how code is executed at the OS or hardware level can provide some huge benefits, especially if you’re doing a lot of work with concurrency or native programming. For instance, understanding how SQL Server’s row / table locking algorithms and its journaling system work allow you to design around potential performance bottlenecks in high-performance systems. Great developers learn these implementation details and leverage that knowledge to write more robust code.
Writes code for patterns, not specific instances – it’s an intuitive skill that can’t really be learned, in my opinion. You either have it or you don’t. Really talented developers infer the patterns in a system, even before a module or a piece of code is written and they code for those patterns, rather than specific instances. This skill limits technical debt and results in a tighter, more usable codebase.
Knows how to learn – this might seem obvious, but I’ll reiterate: there are a lot of developers who simply do not know how to learn something new. They can ape examples they’ve seen before and often need to be hand-held along the way, and they can’t truly internalize a new concept and form the muscle memory to code independently with new technologies.
Great developers know their mind and know how to teach it something new – what works for one developer may not work for another, but nonetheless they all know how ot learn.
Has experience with multiple types of software (native, distributed, web, etc…) – a great developer is a well-rounded developer; if your only experience doing software development is with simple CRUD applications, then you’re missing out on a lot of the corpus of modern software development. A great developer isn’t necessarily an adept professional in each domain area of programming – they might focus primarily on web development and dabble in native, but they take away new lessons from each experience and understand more about computing overall.
Until I wrote the MarkedUp SDK, I never had any practical experience with advanced data structures in production like concurrent binary heaps and circular buffers; I likely would never have encountered those had I stuck to doing just ASP.NET MVC or Node.JS development all the time. Now that I have that experience, who knows – I might find some applications for those in a distributed program or a Web API application in the future.
Experience with multiple types of development tools (IDEs, Text Editors, command line compilers, and more) – I have some bad news: if you’re an EMACS ONLY or VS2012 ONLY developer, you’re limiting yourself. Experience with multiple types of development tools is a good thing, because great developers recognize that improving your workflow habits over time is just as important as improving your programming knowledge and experience.
Some sysadmin / operational knowledge – writing the code is only the first step; deploying it or releasing it comes next. Great developers are not often expert system administrators also, but they know enough about their operating environment to avoid pitfalls and execute a basic deployment if necessary.
Knowing how to run a build / release process, deploy a piece of server software to production, or how to configure a piece of COTS software like Apache or IIS to host a web application is critical to ensuring that the software actually meets its functional requirements. If you aren’t able to produce a development build of a native app using compiler flags, then you can’t very well participate in that part of the QA process, can you?
The point is – great developers don’t wait for someone else to solve their problems; they can do enough sysadmin work to build and test on their local environment, and are self-aware enough to not proceed any further if they don’t know enough to run a live deployment.
If you enjoyed this post, make sure you subscribe to my RSS feed!
I came across a blog post by Michael Halligan on Hacker News last week entitled “Benefits matter, or why I won’t work for your YCombinator start-up.” As a fledging entrepreneur trying to attract senior engineering talent to my startup, his post bothered me immensely. I spent about a week mulling it over before I decided to write this.
Michael’s attitude in the post is abrasive, needlessly cynical, and mercenary, but well-argued on its pure economic merits. He describes himself on his own blog thusly:
I'm just this guy who used to enjoy tech, now I would rather build bicycles. I still work in the tech industry, for the money, but I no longer call myself a "technologist".
And he ends his blog post with this call to action for other senior technologists like himself:
To all of my colleagues with whom I have been in the trenches, please repeat after me, "Fuck you, pay me."
This paints a picture of someone who’s been burned before by startup flameouts; who’s put in 100 hour weeks without seeing any life-changing financial benefit; who has real financial obligations like children to put through school; and lastly, a little burned out with his career.
It wouldn’t have bothered me so much were it not for the boorish cheerleading from scores of Hacker News commenters, which indicated to me that this attitude may be more widely held than I would have believed (more on that in a second.)
I really appreciate Michael being so honest about it, because I suspect that this is an attitude that neither he nor any of the supportive Hacker News commenters have ever had the balls to actually express in a verbal salary negotiation with a flesh-and-blood human being like me sitting across the table.
What bothers me about Michael’s post and the Hacker News comments is the cynical view of founders and employers; it dehumanizes them to self-interested profiteers who don’t give a shit about the people who work for them. And the attitude I grok from Michael’s post is “developers: don’t give a shit about [your employer / the founders] either – tell them ‘fuck you, pay me.’”
Let me show you why this bothers me. Here is my honest to God list of things I care about with respect to MarkedUp in order of importance:
1. My personal integrity – because startups are not things of life or death themselves, but integrity is one of the few character traits that outlives the man or woman.
2. The financial health of the company – because a failing company isn’t in a position to serve anyone well, whether they be founders, customers, employees, or investors.
3. The well-being of MarkedUp’s employees – because they are present and future of the business, and I’m going to spend more time with them than my own family.
4. The experience of our customers – because our customers trust us with important information they need to run their own businesses, and we are our own customer.
5. My personal well-being – because I have I dreams of my own but I know that getting items 1-4 right on this list leads to the realization of #5.
I’m sure that if Michael or any of the Hacker News commenters read this list they’d scream “bullshit!”
I treat the growth and well-being of my employees as a non-negotiable requirement for my own happiness and satisfaction, but that conflicts with the Hacker News worldview of the VC-land profiteering dipshit douchebag 27 year old founder (I am, in fact, 27.)
I hire people whom I want to invest in – sure, like any startup we have short-term needs that have to be filled. But the long term health of any business that’s being built to last depends on a high trust culture – where employers and employees interdepend on each other.
I’d crawl over glass for the full time people on my team who take work off of my plate and enable the business to grow – I need them. They support me, so I’d better damn well support them when they need it. I’m making sure they get important benefits like healthcare and the best compensation that I can afford – everything within the bounds of what’s economically feasible for an early stage company of our size and funding level.
I’m invested in MarkedUp’s employees – and when we’re not able to support an employee’s needs I feel like I’ve personally failed as a manager and employer.
So this brings me back to “Fuck you, pay me.” I would never hire anyone who doesn’t want to invest in our product, the other people on the team, and in the company as a whole – because I can’t depend on them to be there for me and everyone else when things aren’t going perfectly. They’d be the first to bounce and the first ones to put the screws on me and their teammates in a bind. I’d never be able to make a person with this attitude happy, so I’d never try.
“Fuck you, pay me” is a self-fulfilling prophecy that will doom you to work for exactly the sort of employers this attitude is supposed to save you from – the kind who won’t invest in you and don’t care about you. When you open the conversation with an employer with “fuck you, pay me” you’re telling them that you don’t give a shit about the product or people, so why should they care about your well being again?
You’ll be passed over for every promotion, every project of any import, any conference or occasional perk, and your opinion will not be solicited or valued on anything that doesn’t pertain strictly to your role. Your teammates will resent you for being unavailable and disinterested. Your managers and executives will treat you with all of the mercenary courtesy and cynicism with which you’ve treated them.
A job is a lot more than a salary and benefits – it’s about enabling people to be happy, employers and employees both. Anyone who comes to work with the attitude of “fuck you, pay me” is miserable by default, an assertion you can validate with a single read over the front page of Michael’s blog. There is little I can do as an employer for someone who is innately miserable. And that makes me sad and frustrated.
Throughout the course of your career you will inevitably deal with shithead employers who don’t appreciate you – quit and move on. Don’t make the situation worse by deciding not to appreciate all employers regardless of who they are – you’ll just alienate the ones who actually want to help you even if they can’t match another employment offer you have on the table.
If money and benefits are literally the only thing that matters to an employee, then they’re worse than the self-interested greedy founder stereotype described earlier. At least the greedy self-interested founders had the balls to take some risks.
So look at your employment opportunities this way – there’s a lot more to working somewhere than just the tangibles. That’s why developers, sales people, and marketers regularly take below market salaries to work at startups – because they get the rare chance to shape the work environment into one that will make them happy.
Happiness is what matters, and benefits + salary shouldn’t be the only factor at the expense of culture, colleagues, creativity, and self-ownership.
If you enjoyed this post, make sure you subscribe to my RSS feed!
Today on the MarkedUp Analytics Blog I authored a post entitled “Cassandra, Hive, and Hadoop: How We Picked Our Analytics Stack.”
In it I explain MarkedUp’s evaluation process for choosing a new database, how we selected Cassandra, and some benchmarks from our test. If you want to learn more, go read it.
I’ve written about RavenDB in the past on and I’ve spoken about it at code camp before. I think it’s a great technology for prototyping and it has some really interesting concepts not found in any other database that make Raven really simple and elegant to operate.
So I wanted to copy over a section from our blog post about building MarkedUp on Cassandra which explains why we ultimately needed to move away from RavenDB:
Looking back to what went wrong with RavenDB, we determined that it was fundamentally flawed in the following ways:
- Raven’s indexing system is very expensive on disk, which makes it difficult to scale vertically – even on SSDs Raven’s indexing system would keep indexes stale by as much as three or four days;
- Raven’s map/reduce system requires re-aggregation once it’s written by our data collection API, which works great at low volumes but scales at an inverted ratio to data growth – the more people using us, the worse the performance gets for everyone;
- Raven’s sharding system is really more of a hack at the client level which marries your network topology to your data, which is a really bad design choice – it literally appends the ID of your server to all document identifiers;
- Raven’s sharding system actually makes read performance on indices orders of magnitude worse (has to hit every server in the cluster on every request to an index) and doesn’t alleviate any issues with writing to indexes – no benefit there;
- Raven’s map/reduce pipeline was too simplistic, which stopped us from being able to do some more in-depth queries that we wanted; and
- We had to figure out everything related to RavenDB on our own – we even had to write our own backup software and our own indexing-building tool for RavenDB; there’s very little in the way of a RavenDB ecosystem.
So based on all of this, we decided that our next database system needed to be capable of:
- Integrating with Hadoop and the Hadoop ecosystem, so we could get more powerful map/reduce capabilities;
- “Linear” hardware scale – make it easy for us to increase our service’s capacity with better / more hardware;
- Aggregate-on-write – eliminate the need to constantly iterate over our data set;
- Utilizing higher I/O – it’s difficult to get RavenDB to move any of its I/O to memory, hence why it’s so hard on disk;
- Fast setup time – need to be able to move quickly;
- Great ecosystem support – we don’t want to be the biggest company using whatever database we pick next.
So there you have it. If you want to learn more about our migration to Cassandra, check out our original blog post.
If you enjoyed this post, make sure you subscribe to my RSS feed!
Since going full-time on my own startup 6 months ago, I’ve spent a lot of my time recruiting, evaluating, and working with a lot of different developers. My startup, MarkedUp, is an analytics provider for Windows 8 apps (and eventually, other platforms.)
Our technology is sophisticated and difficult even for large companies to master, so the bar is pretty high for developers who join our team. We’re selective about who we work with, but even with careful recruiting practices it’s still difficult to find developers talented enough to pull their own weight on a complex product like ours.
So I want to help average developers who want to improve by calling out 10 performance-killing behaviors that stagnate the careers of most developers.
Most developers stagnate both intellectually and productively after 4-5 years in industry; they adopt some tools, pick up some patterns, learn a language or two, and maybe they’re even able to work at a successful company and contribute to some important products. Great!
But what happens when you hand a developer a blank sheet of paper and the opportunity for them to own a product?
Most of the time: chaos and failure.
Many developers fantasize about being able to own a product and make big technical decisions, but the truth of the matter is most of developers can’t handle anything more complicated than building formulaic CRUD Rails websites using the same 30 gems each and every time.
So what are the behaviors that limit the growth of average developers?
You’re too afraid of failure to learn new tools / languages / frameworks.
During my first quarter at Microsoft I gave a talk to the LA .NET User’s Group on ASP.NET MVC3, which was in beta at the time. For the most part the attendees asked me thoughtful questions and showed a legitimate interest in what the ASP.NET team was cooking up in Redmond.
However, there was a trio of attendees who kept asking me a very suspicious set of questions:
“What are the weaknesses of ASP.NET MVC3?”
“Isn’t ASP.NET MVC too unstable for use in the enterprise?”
“But doesn’t ASP.NET WebForms already do a better job?”
I realized shortly after the Q&A was finished, when I had a chance to speak to them privately, that they were attending my talk to actively look for reasons why ASP.NET MVC shouldn’t replace WebForms at their place of work!
These developers were so afraid of trying something new and possibly failing that they actually went out of their way to research just the talking points they needed to not have to learn it!
This is an extreme example, but the point is the same: average developers cling to their favorite tools and stop learning new ones because they worry that leaving their pet languages and tools behind invalidates their years of experience.
Strong developers embrace the challenge and opportunity to learn new ways of doing things.
You won’t push your commits until the feature is “done.” (It’s never done!)
We call this “commit hoarding” at MarkedUp. This happens with developers who don’t have the confidence to tolerate criticism or scrutiny from the rest of the development team try to hide their work until it’s in a “finished” state.
Ultimately these developers hurt the productivity of the rest of the team, because we lose visibility into their daily output and they tend not to ask for help in the course of regular development. They’re responsible both for delays in shipping and for lots of last-minute bugs.
Strong developers recognize that they are not their code, and thus will put code out in front of the rest of the team more frequently and take criticism and suggestions with dignity and confidence.
You know just enough to be dangerous.
In an age where it’s become a lot easier for developers to work with threads, concurrent programming, distributed databases, and so forth you run into a lot of devs who can talk a good game. They can tell you all about thread pools, a hot new design pattern, or why a headless database is better than a masterful one in some scenarios.
They are able to know what something is and its potential benefits, but they don’t understand it.
I’ll give you a recent example: in C# 5.0 Microsoft recently introduced the async and await keywords, which make it radically easier to create and manage asynchronous callbacks. These keywords have even lead to the rise of some exciting new concurrent programming patterns like the TAP pattern.
However, do you know what this keyword has also lead to? A ton of average developers who suddenly think they can harness the awesome power of multithreading simply by wrapping every I/O call into a Task object in C#. They do this blindly, without any thought as to the costs of context-switching, multi-thread access to shared resources, and more.
And this creates dangerous, unpredictable, and very-difficult-to-test code in the hands of average developers who blindly uses this new toy everywhere.
Good developers not only know what something does, but they seek to understand why it was done this way and under what conditions it should be used.
Sometimes you’ll hear a member of our development team say “dude, stop Gandalfing the documentation and start coding something,” referring to the scene from The Lord of the Rings depicted above.
Analysis paralysis is a classic problem that affects lots of average developers; it’s often a problem of over-analysis, but in my experience the root cause is usually fear of making a bad decision.
Research is easy – implementations are hard! As a developer, you don’t want to make a mistake when it comes time to do the actual work. So just research the issue until the heat death of the universe and you’ll make a perfect decision for which you won’t ever be criticized!
Average developers worry about looking bad or making a mistake – they want to get it right on the first try.
Strong developers who are in unfamiliar territory don’t care – they’ll write shit code, unit test it, and throw it away in 45 minutes if they don’t think it can get the job done. Strong developers actively limit the amount of time they spend researching, because they recognize that it’s a trap – it feels like work but often isn’t.
You don’t invest in your tools or development process.
Average developers will spend a lot of time learning how some fancy new language feature or API works. They’ll invest a ton of time mastering the minutia of the Windows runtime or some new D3-based charting framework, but at the end of the day that doesn’t change the fact that they’re still average developers who churn out mediocre work at a glacial pace.
If you want to be a talented developer, you have to invest time into improving your skills and knowledge, and the number one factor that separates the men from the boys in most software markets is the ability to turn out production-grade code quickly. You can have both good code and speed – but you have to invest in your process you use for building it first!
Average developers don’t invest in their tools, their process, or their environment.
Think about it – when was the last time you took a step back and thought about the way you test your code or how you look for bugs? Have you tried experimenting with different types of abstractions for the same problems and seen which one produces more maintainable code? Have you tried picking up a new IDE or text editor to see if it can help speed up common tasks? What about investing in build or deployment automation?
Often times, the biggest improvement you can get as a developer isn’t focusing on improving the code you write – it’s optimizing your process for writing it.
Free protip for anyone who follows my blog regularly: the biggest improvement I’ve made in my own development process easily is decreasing my usage of interface-driven design and dependency injection. I do a lot more work using static classes and compositions these days and it results in radically less code to test and maintain.
You’re too embarrassed to ask for help.
When we started digging into the guts of Hive for some of our work at MarkedUp, we got a little stuck on how to tackle some problems we had specific to our use case. So what did we do? We reached out to one of the guys who wrote the O’Reilly book on Hive and asked him over LinkedIn. And he replied back!
We try to be self-sufficient developers to the furthest extent possible, but we also know when it’s more economical to simply ask someone for a favor versus beating our heads against our desks for hours on end.
Average developers get embarrassed and don’t want to reveal their ignorance, so they pretend they know what’s up until they commit some sort of horrible fuck-up in the codebase itself.
There is nothing wrong with saying “I don’t know how to do this.” Strong developers know this, so they go and ask for help when they’re stuck.
You don’t know how to make it easy for other programmers to work with your code.
Like an only child growing up, you never learned how to share your toys with anyone else. The same goes for your code – you developed some bad habits and an over-abstracted style that is impossible for other developers to follow.
An important part of working on any technical team is human parallelism – the ability for multiple people to be able to work simultaneously on the same codebase. But it’s also important for teams to be able to work asynchronously too – I should be able to make changes to your code when you’re away, and vice versa.
Average developers don’t think about their code this way – they simply set out to do a task and write it through to completion with the assumption being that they will always own that piece of code. Strong developers understand technical debt and try to limit it by designing code that is as maintainable and self-explainable as possible.
Writing readable code really requires developers to change their outlook – your code should last longer in the organization that you.
You don’t know how to read someone else’s code (or don’t want to.)
It’s an interesting paradox – average developers can’t handle a blank sheet of paper very well, but they can’t write the last 30 pages of a novel in progress either. Average developers are really hesitant to try to learn an existing codebase and often have to be handled all the way through it until they’re able to produce something.
A drastic example is when an average developer is brought in on a codebase written in a language / framework that they aren’t familiar with and will immediately want to rewrite it without a second thought to business value or time to market. It’s a type of pain avoidance – having to live with the precipitation of some other programmer.
Strong developers accept that the business costs in a rewrite are usually unacceptable and should be avoided, and they’ll diligently try to understand, learn, and modify the existing codebase sitting in front of them.
Reading code is harder than writing code, but strong developers invest time into learning how to excel at it.
You can’t code from the end-user’s point of view (you think too small.)
Average developers who manage to make it a lot closer to the “great programmer” end of the bell curve usually trip up here. You may have mastered some of the technical details and you may know how to work with other developers, but you’re still missing the most important piece: being able to see your code from the point of view of the real-world.
As a programmer, you job isn’t really to solve technical problems – you solve technical problems in order to solve business problems.
An average-to-bad developer will chase technical problems down deep rabbit holes without remembering why they were solving the problem in the first place. You’re not upgrading the version of MongoDB you’re using because there’s inherent value in upgrading – you’re upgrading because your team agreed that it was worth taking the risk to upgrade because of potential business upside due to new features / performance / reliability / whatever.
More offensively, average developers struggle and fail to produce anything of business value from scratch. When asked to design a new feature based off of a simple customer story average developers will take a rigid, literal interpretation of the story or spec and ship something that is barely useable by a human.
Average developers don’t anticipate other related use cases; don’t think about the end-user’s experience; and basically have to be managed heavily when working on anything user-facing. This is why so many of them get stuck writing line of business apps instead of products.
Great developers look at their code from the perspective of the end-user. How do I make this easier to solve my user’s problem? What are some other facets outside the literal content of the story that might make this feature even better for an end user?
If you’re a developer and don’t ask yourself these questions, then you’re not a great developer. You’re passable at best.
You aren’t able to judge the business value of any programming task.
Related to the previous issue – many technically strong developers fail to realize their potential due because they aren’t able to take a step back and look at their work from the perspective of the business or organization itself.
Strong developers are able to self-manage and make good business decisions about how they choose to invest their time. They’ll ask questions like:
Is this the most valuable thing I should be working on right now? How much time should I invest into doing this? Given the deliverables I have due in two weeks, is there something I can invest in right now that will make it a lot easier for me to hit that target?
Average developers don’t – they’ll take a spec and blindly implement it until it’s finished, without accounting for how their work relates to the company’s business goals and impacts other members of the team / other business groups.
The highest cost of any engineering team is development time, and average developers waste lots of it on minutia and technical tasks that are ultimately low business value.
If you want to be a better developer, it starts with changing the way you look at your code and how you program.
You have to understand and appreciate the business costs behind each line of code you write. You have to be able to step outside of your text editor or IDE and look at your work from the perspective of a customer or end-user.
You have to accept that your code will outlast you in any organization your work with, so design everything to be inherited by other developers one day.
Most importantly, never be afraid to take on new challenges and ask for help along the way. You won’t improve working alone in the corner on technologies you’re already familiar with. Software development is inherently social – learn how to bring other people into the experience.
If you enjoyed this post, make sure you subscribe to my RSS feed!