As we hit the college campuses for the second half of recruiting, it seemed like a good idea to pick up where we left off.
Development at Microsoft
Let's talk about development at Microsoft and what it is like to be a Software Design Engineer (or SDE as we call them, or just "dev"). My last post described PM at Microsoft (Office in particular) so I thought I would talk about Development today. Development does not have the subtleties that PM does so I don't think it will take as many bytes to describe. From the very beginning Microsoft has been a development driven culture and organization. Of course this starts with Bill Gates and Paul Allen two developers with a very famous story about writing a BASIC interpreter in a weekend.
Obviously the first thing that comes to mind is that at a software company, without developers the company really doesn't exist. And of course Microsoft is no exception. While the company has grown from what I would say was a "developer-driven" company where basically everything was about development, to a more grown-up and well-rounded company with the right focus on customers, business, and the market, we have consistently remained very much a technical and product company. Of course this starts at the top, where our Chairman of the Board is also the company's Chief Software Architect. Also, this post might show a bit more of me and be a bit more personal because development is where I started at Microsoft and because I am one of those folks that has a very romantic view of programming.
At the risk of perhaps ruffling the feathers of some others at Microsoft (myself included), one analogy that was shared with me back when I was a developer is that being a developer at Microsoft is like being a fighter pilot on an aircraft carrier (can you tell about what year this was and what movie was still top of mind?) An aircraft carrier exists to push the airpower and does so on ships that have over 80 aircraft on them, and those aircraft are supported by a crew of nearly 6,000 (on a ship like the Nimitz). So you can imagine while there are a bunch of pilots, the infrastructure of the ship (from mechanics, to naval officers, to doctors, ship's defenses, etc.) are all focused on insuring that the aircraft and resources and doing their duty. So in a sense, if you're a developer at Microsoft then you're on a ship that is all about making sure you can accomplish your mission.
The mission of being a developer is much easier to detail than that of program management--developers write the tightest, most secure, most robust, most performant code possible. At the same time, it is not just any code, but the best code that addresses customer problems in innovative ways for the broadest audience. You can write great code in a lot of places. Being a developer at Microsoft means you're writing code used by hundreds of millions of people who literally bet their livelihood on us.
A year after I joined Microsoft, my recruiter asked me for a quote for our recruiting brochure (I can't find it or I'd scan it in) saying why I wanted to work at Microsoft. For me, the thing about being a developer here is that impact. In graduate school I was working on a class library and working on connecting it up to databases. It was super cool and I had a great time. I came to Microsoft and worked on that same type of project, but instead of sharing the code with my lab mates and a few other interested researchers we were selling the product as a big part of our C++ product line. And before I knew it we had hundreds of thousands of developers using our tools making software for millions. For me that has always been the greatest rush.
As a quick story, I was on one of my reasonably regular recruiting trips to Cornell back around 1995 or so. It was late at night and of course high on my agenda was returning to the Hot Truck on west campus for on of Bob's PMPs ("French bread pizza", an idea copied by Stouffer's mind you). As a quick side note, about 10 years after you graduate your body is not really able to handle these treats, which explains why they only serve PMPs at your 5 year reunion. In any event, it was cold and some others were waiting for food along with me (waiting means standing on a stairway in front of the truck) and I'm sure they were wondering what this grown up was doing there ("loser grad student" comes to mind). They were talking about a cool program they were using in their comp sci class. As the details unfolded it was clear they were talking about Microsoft Visual C++.
I couldn't resist so I jumped in with a "hey I worked on that". Somewhat amazed (perhaps at my rudeness) but nonetheless interested. We ended up having a detailed conversation about the emerging importance of C++ and the implementation issues they faced in class, with particular emphasis on code and technical details (multiple inheritance, virtual function tables, etc.). One student was so excited he said "wait a minute" and ran back to his room to get his box of C++ so that I could autograph it.
Here's the hot truck in action (this is a reunion photo so it is warm and the people waiting are not students):
OK you get it, being a developer is cool. So what does a developer do at Microsoft? Like all the product development jobs, a good way to think about this is to look at the primary phases of a product cycle -- in developer terms you could think of these as evaluate, architecture and scaffolding, construction, and polish. Like all disciplines, development is one equal part of our product development process. In some ways, the other disciplines exist to make sure our developers are 100% focused on building great features, writing great code, and doing a great job. For the record, this most certainly includes me!
As is often the case when I talk with students about the product cycle, the conventional wisdom these days continues to be that it is way cool to work on short projects and that the world has moved on from big long software projects--this is the myth of cool projects can be done in one summer. It is hard to disagree in some sense--if you can have all the benefits of lots of customers, long term success, and profits by doing a small amount of work in a short time, then that is definitely preferable to doing a lot of work over 24 months. Unfortunately, there are very few small programs that are also interesting from a business perspective, especially over any sustained time. And of course today's small program is tomorrow's big program and asset that customers want to bring forward. In several posts I've talked about the product cycle and how we work in Office. I think the rewards that come from building a unique "economic asset" for Microsoft and customers are very great (from a personal accomplishment and a business perspective). I love a cool "project" and we definitely have those for interns, but trying to make a big company out of a lot of projects is exceedingly difficult (a wise leader of Microsoft once said, you can't make a billion dollar company out of one hundred $10 million dollar products). There are some other myths of development that I will follow up on next post.
Evaluate and Estimate
Let’s assume program management has done the groundwork to come up with a good range of feature ideas and you’re now facing a long list of potential features. Many of them are exciting. Many are things you wish you had *today*. Some of them look dorky. Some of them look like implementing them in code involves changing the laws of physics. This is where development brings their point of view to the picture and collaborates with program management (and test) to determine what can possibly be implemented.
At this point a lot of organizations would just pass the baton to development and they would take a “spec” or a “market requirements document” and do the set of things that make sense to them, without much of a feedback loop (until perhaps later when some features that were important to the boss fail to show up). In Office, this feedback loop is a critical one that takes a lot of energy—we call this “adds/cuts” since during this time we are building a list of the features we will implement and deciding which ones go on the list (add) and which ones fall off (cut).
At the same time, particularly for work that is reworking past ideas or improving in-market features, developers have their own ideas about what makes sense. Just as a program manager would do, the role of development is to convince program management to devote the bandwidth to adding those features. It goes without saying, but developers dream up some of the coolest ideas around. One of the coolest that I can think of recently has been the evolution of “Watson” – this is the quality assurance feature in Office that uses the internet to reflect back to Microsoft (anonymously and privately and opt-in) the experience customers are having with the software. This was dreamed up and executed by developers in their spare time.
So development is not there just to “code” the aspirations of program management. Development is also not there to dream up all the features on their own. Remember, there is a lot that went into the program management feature list, vision, and other groundwork. Of course in the end developers “own the code” and they could just go off and do things their own way, but this does not scale very well—you can imagine that as a developer you might know a whole lot about how to use a feature like pivot tables in Excel, but unless you’ve spent the time with bankers looking at how they use them and time talking to VARs who build solutions on pivot tables there is a good chance your views of what to do are based more on the code and the possibilities of the code, rather than the customer’s needs. After all, the most amazing developers are those that make the code do what the customer wants, rather than make the customer like what the code (or developer) wants to do 🙂
With this rough list of features in hand, as a developer you are responsible for looking at the challenge and looking at the cost of implementing it. You are responsible for understanding the problem to a level of depth that can allow you to estimate the cost of the feature, including all the edge conditions, error handling, scale and performance, quality, globalization, and more. Of course at this phase you are not expected to get the estimate down to the day (and frankly, it is not likely your program manager counterparts have ironed out the details enough anyway). But what you need to do is to be able to determine the feasibility of the work. This feasibility is super important. If you are off in this area then there is a good chance your work will be very hard to ship. The best part about being a developer, even a new one out of college, is that you own this decision. You can say "no it cannot be done" or "it can be done, but perhaps there is a better way", or "you bet, I'm the one to get this done just like you described". This back-and-forth is critical to being able to successfully determine what is in the product or not.
This brings us to another quick aside, which is the notion that you should just try stuff out and see if it works and if it doesn't, "oh well". I think this is a great notion to strive for and for small products it might be a good idea. But for anything that has any level of complexity, even trying something out is expensive enough that you want to have a high confidence in success before you start. What's the old carpenter saying, measure twice, cut once -- I think that holds just as much for software even though you don't immediately see the downside of a bad estimate. While this looks like some serial “waterfall” process, in fact it is entirely iterative and the goal of this is to allow small groups of people to act as a small team within a big team. But having this information allows us to coordinate and make decisions as a whole. So this way you can have two small teams contribute to a mission, work independently as possible, and have some coordination. It fosters shared code that does not have to get defined at a very rigorous level, but a much more collaborative level, which is often what grinds cooperating teams and code sharing to a halt.
As a developer exits this phase of the product he/she is equipped with a set of features and a rough estimate for the time it will take to get the work done. The developer, working with the dev lead and dev manager, is busy at this point developing a high level task list of what aspects of the work need to get done and an ordering. At this point you will iron out things like scoping the amount of user interface work, the amount of new infrastructure work, the amount of backward compatibility work, the amount of developer/API work, etc. These big buckets look a lot like the specification areas from program management, but of course as a developer you are thinking about the amount of code that needs to get done for each based on those areas. There is also work across the team because there are likely some serializations that will need to take place. Of course the next step is to develop some architectural view of how to really go about implementing this work.
Architect and Scaffold
For many developers the really fun part of a project is determining the architecture. By architecture I mean precisely what you learn about in college courses--what are the systems, sub-systems, data-structures, and algorithms you will use for the major parts of a project. As a developer, you are of course entirely responsible for these decisions. Even if you are new you own these choices. The good news in that case is you will have a dev lead who has experience with the code base and the project who will likely work very closely with you on this phase.
I love walking by developer offices during this phase of the project. Whiteboards are filled with diagrams of pointers, data structures, and lots of "DO NOT ERASE". There are always heated discussions about what choices to make. It is during this phase that I believe developers make the most crucial decisions of a project. As you know the architecture determines not just what can be built well right now, but how responsive to changing requirements the project will be in the future. While it is great for every architecture you design to be able to respond to any change, that is really tough to do in practice. So the best developers are those that work the closest with program management to really understand the direction that things might evolve--to the best of everyone's knowledge. At the same time, it is always worth cautioning that trying to get your PM to say "no I will never ask you for this" might get you into trouble later in the project when things change. That can lead to frustration, but it is of course always the best way to demonstrate the flexibility of your architecture.
During this phase developers make up not just the code architecture, but the assumptions about what the code can handle down the road. The data structures will be chosen to assume certain field lengths, certain limitations, or certain performance traits. All the size v. space tradeoffs you learn about in college come into play here because as you know you can't just use infinite memory or infinite cycles. It turns out that for client based applications the primary gating factor is memory usage, so being very clever about how you use memory and how many pages you touch can make a big difference in how your code performs (for example, in toolbars it is often an elegant design to just have each button be a bitmap, but loading 100 bitmaps off disk can be insanely time consuming at boot time when all you want to do is get work done, so you have to be clever about designing a system that can load one bitmap and create 100 buttons). At the same time, the success of client applications depend immensely on the perceived performance. So these choices early on have a big impact. This is where experience and you mentor really help, because there are many things that come up time and time again. Similarly on server code, the use of CPU and networking have similar issues and an architecture that assumes these are low cost might be very elegant but in practice be problematic. The creativity involved in elegance plus performance plus making something meaningful for customers is very fun!
I have met a lot of developers that say they want to be architects. At Microsoft (and definitely in Office) *all* developers are architects. In some ways I think the job title for everyone on our team should be Software Design Architect. The reason is simple in that we want everyone to be thinking and acting architecturally with their code. Because of that we have not historically needed separate people to be telling people what to do and how to do it without actually doing the work themselves.
With the idea of what the overall architecture will be the next step is to put in place the scaffolding of the project. This is a very personal thing for developers as each have their own way to go about doing this. Some prefer take a depth first approach (I once read that great programmers spend 90% of the time on 10% of the problem, so maybe depth first isn't best, then again I think I spent my life on the CFile class of MFC). Others prefer to take a breadth approach. One of the most architecturally focused developers in Office who designed the line and page layout code in modern Word used a process where before any code at all was written all the header files and structure definitions needed to be complete--and the rule was that once coding started these were not going to change. He wasn't stubborn, but rather just brilliant at doing the complete design ahead of time after appropriately studying the problem.
There are a lot of things to consider at this point as well such as what code can be reused--why implement a new data structure when one exists to do the work. There are items to consider like compatibility. If your work will trample on an existing API that customers used then you will need to figure out how to continue to support that API. You can look at these as a burden or as I prefer you get to look at them as useful engineering constraints. An architect once told me that he loves doing projects where the land the house will be on has a lot of quirks--it makes the project interesting because it introduces constraints that aren't there in a flat quarter acre lot with no trees.
In a three milestone project, this portion usually takes the first milestone. As a developer you exit this milestone with a much clearer idea of the schedule and a much clearer idea of the work ahead of you. Closing out this work and getting all the scaffolding checked in and getting those data structures working is a very significant milestone -- you feel like you wrapped your arms around the problem and can move on.
Of course what comes next is just solid coding. This too is super fun because this is where you get those feelings of coming into work, writing some code, and showing off a new feature by lunch and maybe another new feature at the end of the day. Like a long car trip from Florida to New England it feels like you made it through Florida and Georgia are hitting the Carolinas and you're knocking off states at a rapid pace (don't forget to stop at South of the Border though).
For the most part during the construction phase you are writing code and making things work. Every day brings new excitement. You know you have really rounded the corner when people start dropping by your office because word traveled around the hallways about a new feature that is running on your machine. Often you'll see a screen shot passed around in email or a URL mailed around that we should all try out. One of the new features in Office "12" that was done was the ability to use InfoPath forms in Groove -- this is a super important scenario for reliably collecting data when you are using a laptop not connected to the internet (such as when Groove is used in disaster relief work, for example). I remember being in the Beverly,MA office where Groove is and seeing a super early demo -- you could literally open up a form in Groove. You couldn't type or anything yet, but it was super exciting because it showed that the scaffolding and architecture were well on their way to being proven.
Of course other folks are hard at work while you are writing code, namely the testers you work with. As you complete features or sub-systems the testers will begin to investigate the work you are doing and they might find some problems 🙂 Some of these will be because features are not done or the error handling code is not there, but you might also have things that didn't work as planned. In fact the more you make it through this the more testing will likely be able to push your code to the limits. All of this of course helps you to make the code better. As a developer you always strive to make no mistakes, but we know that is not possible, and so your best ally in building a great product in this phase are your coworkers in testing. Similarly during this phase as a developer you will need to be very aware of the real world performance--things that are slow now will only get slower. So you might find yourself revisiting some architectural decisions, since you know that it is much easier to deal with these upstream than hold off.
As you wrap up this phase we are generally in what we call "code complete". This means the feature work is done. It means all the edge cases that were planned on are handled. It means that as far as development is concerned the feature is ready for people to start to use and for the real feedback to begin. There is still a lot of work to do, but your work now looks like a product.
Integrate and Polish
We're now getting ready for the beta test for the product. The product is rough and we can't sell it, but you know what it is going to look like and most of all you are very excited to see what others might think. When you build the product you see the incremental steps so when it all comes together it sometimes isn't as exciting as the first look at the feature. For me, in Office "12" the PDF feature was like this. Alex (and others) worked away on this for quite some time of course, but to us we knew it was a very simple "save as PDF" feature that would be on the "File" menu. It was super cool of course but we'd seen the work evolve. Then we had the chance to demo it to the MVPs when we announced the support and for those that were there we got to hear the memorable quote "if this works, I'll have your baby". We were in the end-phase of the product but it sure reminded us just how cool customers thought the feature was!
One of the most fun parts of this phase is when we invite BillG to the Office hallway and he spends the day going to developer offices and talking about the details of the code and architecture. This is a tradition we do each release and is enormous fun for everyone, especially Bill. We pick devs from each of our teams to demo their features and they prepare and plan on Bill stopping by. You just hang out in your office and then Bill pops his head in. You start your demo and hope that he doesn't stump you out of the gate!
Of course the polish phase is not always just fun reactions from customers. There is a lot of great development that takes place as we really smooth out the product, nail the performance, and nail the quality. The polish phase really is about fixing the bugs. The fun part about being a developer during this phase is that you are working from a list of bugs and fixing them--a lot of people really like this style of work in that you know where you stand every day and nothing is too open ended. Bug fixing for many is a sport. My first manager was just amazing at being able to almost detect the source of the bug by sensing some sort of EMF from the monitor--he was especially adept at using intel hardware breakpoints to track down errant pointers. Some developers will likely become informal tech leads of projects at this phase because they can track down anything. There is also a big aspect of being experienced here that shows and so the more experience you have the easier this phase becomes. Of course from an agility perspective, the buglist represents the backlog of work and one could argue the buglist should always be a “virtual zero”.
Similar to bugs is performance. Even with 3ghz multi-core processors and 1gb of RAM performance is still critical. A lot of people think that perf shouldn't be a problem or if it is it is just because we add too many features. I wish it were that since we could just do less features and not have to work on perf. But the reality is that as fast as we can add features people use more and more of their PCs. So our original benchmarks for Excel were around booting Excel into a Windows runtime used only for Excel--no network, no AV software, and basically nothing but Excel. It is no wonder it could work in 1MB of real mode memory!But today when you boot Excel you are probably running mail, Word, a browser, a media player, a network and firewall, and on and on. So we can’t let our resource utilization grow because there is always contention. All of our work on the server has these same issues relative to scale, pages per second, etc. As a developer on Office you will spend a lot of time looking at how your new work impacts the release-over-release benchmarks. Our goal is that each release should use the same resources and take the same time to do the same tasks. This is a tough goal for software and it is a testament to the team that our applications still perform at these relative levels. And at the same time people can do lots of new stuff.
During this phase some of the classic integration engineering takes place as well. Software represents a complex system and when you bring those systems together the behavior across them and the boundary conditions yields some interesting issues to track down. Microsoft develops a lot of automation testing and a lot of scenario based views of how the products should function that assist the developer during this phase.
Finally for features that interact with users, this is the time we get tons of feedback on the experience and we work hard to incorporate that as appropriate. We learn lots about the features at this point and because the product is working, program management is out there learning. And developers are watching the reviews and feedback and responding as well. I remember when working on the VC++ compiler/IDE and we really wanted to compile the most lines per minute relative to the competition as the spec said we should. The beta feedback I saw said people thought we were slower. Now I was pissed--I had like 3 stop watches and 4 machines in my office and I knew every benchmark for compile speed and tracked these on a daily basis. I knew our speed was faster. Well I talked to some outside developers on the beta and I realized that they thought it was slower and they showed me how the competitor had a very fancy spinning line count telling you how many lines were compiled and we just had a status bar thing. I got so excited because I got to tell them that I used to have that but realized it slowed the compile down by a fixed overhead of about 0.2s and for big files it really slowed things down even more just to TextOut those line numbers. Of course I learned something too that sometimes perceived responsiveness matters just as much as clock time. A good lesson for all.
The best feedback of all though is reading reviews, watching your friends, and maybe signing a few autographs at the Hot Truck!
With that we've made it through the product cycle -- we've architected, estimated, scaffolded, constructed, and polished. The product is ready for customers. Whether that was a customer requested DCR that took 2 weeks, an update of OfficeOnline that took 6 months, or a full release of Office, as a developer you will take your code through all of these phases. If you're considering an SDE role at Microsoft (or Office), from my perspective a couple of things you will get:
- Part of a small team focused on the customer or technology area
- The opportunity to write the very best code for products used by millions of people, not just used but relied on to earn a living, get a degree, or run governments.
- Access to the best resources to get your job done -- working with the best in the industry in product groups to being able to tap the resources of Microsoft Research
- A very strong mentor who as part of small team will be there for you on a daily basis
Of course it goes without saying that to be a great developer you need to write great code, but the following are a few characteristics that our team finds valuable when finding great developers for our team:
- Able to foresee what will need to change in the next round without over-architecting the current round -- many people can write a quick solution to a problem, but quickly program themselves into a corner. That is why you might get asked an interview question and then after you answer it you might get asked "ok, now what if the person's language reads right to left". So great developers know the foresight they are building into the code and understand the limitations that will appear down the road--all code has that of course, but being deliberate and informed about that is a great skill.
- Debugs other people's code -- Great developers can jump into other code and make progress in pretty short order. This is super hard. So getting good at building a mental map of a new system and understanding the patterns in foreign code is a great skill.
- Makes the code dance for customers -- Many developers are very content to prove their code does cool things. That is definitely good. But to be really great, a developer should be able to show how their code solves a problem that a paying customer would have.
- Works well with others -- All great programmers that I've known have told me how much they love The Fountainhead or Atlas Shrugged. Yet at the same time, programming is inherently a collaborative field so all great programmers know when to work well with others and how to use their dev skills to get the most out of the team. This is not just other devs, but test, pm, design, usability, and others.
- Knows when to say "no" and when to say "yes" -- Many developers are spectacular at saying "yes" early in their careers which is quickly followed by a tremendous ability to say "no" (after a tough project or two). Great developers know how to make it work and know when something is important that they can find a way to get a quality job done. They can find clever solutions to incredibly hard problems.
- Humble -- Everyone probably remembers the scene in Top Gun when Maverick was explaining his MIG encounter--Maverick was calm, cool, collected, and understated. As confident as he was in his flying he told the story with a certain modesty ("[cough] we were inverted" with emphasis added by Goose "no really we were"). Most of all, great programmers are humble about their ability to crank out the best code and make it look easy.
PS: A word on comments – I strongly encourage comments. I especially encourage comments from college students and people considering a career at Microsoft. If you already work here, feel free to drop by my office, send me mail, or anything—we can have a great discussion without going through this pipe that is a bit more narrow that my front door!