Intuit
Intuit Inc. - 2005 to 2007
Inception
I had been a loyal user of Intuit's QuickBooks for nearly a decade, starting with my founding of Charlton Innovations, Inc. in 1996. I updated every year to the latest official release, paying a new license fee each year for that privilege. In the year 2000, the reliable market leading accounting software turned into an unstable pile of shit from my perspective. I kept using Quickbooks 1999 until 2002 when the product had partially recovered from its earlier decline. I always wondered what had happened at Intuit, and its software development practices, that they took such a big nose-dive in such a short period of time.
I started to get answers in spring of 2005 when I met one of Intuit's software development managers at a social event unrelated to the company. I shared with him part of my background and history of disrupting software organizations and products for the better, and my bad experience with the Quickbooks 2000 edition. He had lived through the internal experience and shared that for the year 2000 product, Intuit had hired literally dozens of new product managers, each of whom wanted to add features to QuickBooks and make a name for themselves. Those new product managers were supported at the Board of Directors level of the company, and they received funding to grow the engineering team from the 40 who had developed QuickBooks until the 1999 release, to over 250 total engineers on staff, not counting external consultants, for the QuickBooks 2000 release. All-in-all, I got the understanding that the extended QuickBooks development team had grown by a factor of 10 in less than one year.
We formed a friendship and continued our discussions for the next few months via semi-weekly breakfast meetings at Buck's, a popular restaurant in Woodside California. During those discussions he shared that during the rapid scaling, nobody had an overarching architectural view, and that many of the 40 original developers had left the company in disgust, leaving very few who had intimate knowledge of the legacy product. I also learned that each new product manager was empowered to act with a lot of latitude, basically as a GM with P&L responsibility for their feature set and market segment. This meant that those product managers hired their own engineering teams and generally "bolted on" their new features to the core product via newly forged APIs that attempted to map the data models of the core product to the data model of the new feature. I understood that in one year, the product size tripled from 3 million lines of code to 10 million lines of code.
He also shared that the company was building a new team, overseen by the CTO, to replace all of the company's technologies and product implementations with a new SOA (service oriented architecture) and a software portfolio architectural governance structure that allowed sharing of business logic across different products such as Quicken, QuickBooks, various tax products, and others. I was sceptical -- in my career, even to this date, I have never seen a large scale 100% rewrite work unless it had a gradual migration strategy at a feature level.
I shared that what I thought was needed was fundamental technology culture change, not rapid tech stack change. Training everyone to be better at their jobs, starting with a much deeper understanding of the requirements and the end-user domain. He shared that most of those 250 engineers did not even understand basic accounting, GAAP, FASB, payroll, taxes, asset or inventory management.
Stealth Mission
We came up with a plan he thought he could sell to his management chain of leadership. The three-year arc we anticipated included targets for agile, lean, TDD (test driven development), MDD (model driven development), peer review at all stages, and creating metrics via observability and core processes to manage both development process and code metrics.
He developed support for the plan internally, and finally came back to me, saying the plan was approved, but that since the plan involved a 2-3 year culture change of the entire engineering organization, that the sponsoring executive had two requirements in addition to our plan: (1) that I onboard as a W2 employee rather than as a B2B consultant, and (2) that I work to apply culture change entirely through earned influence rather than management mandate.
Onboarding
I did not parachute in. It was more akin to a covert operation—arriving under the cloak of night, aboard an unlit vessel, navigating through dense fog on a moonless evening. It was well known in the company that a hiring moratorium was in place for the entire QuickBooks software team that year. However, Intuit’s leadership was gambling heavily on Merlin, the ambitious SOA rewrite, and concerns were expressed internally about the risks of failure—loss of institutional knowledge, fractured engineering teams, and an unproven architectural vision. My presence was Plan B, a hedge against the possibility that Merlin would stall or collapse under its own weight. My friend navigated these concerns at the executive level and secured a “critical replacement requisition” for his team, creating a rare exception to the hiring freeze. I was brought in for a formal interview process the last week of June 2005, meeting with several team members, a Merlin architect, and the architect leading Merlin. By the end of the day, with his team’s debrief behind him, my friend extended a job offer on the spot—an unspoken acknowledgment that my role had already been decided. I officially joined Intuit the Monday after the July 4th holiday, stepping into a company at a crossroads between its legacy foundation and an uncertain future.
My initial title was "staff engineer" -- a role that set an expectation of competence, but not so high a title as to generate envy or jealousy from entrenched engineers.
In my first week, I made a point of walking the three floors of engineering cubicles, introducing myself to as many people as I could find, and asking what they were working on. I also initiated conversations, many over the water-cooler as it were, with product and engineering management leaders, asking what was keeping them up at night with respect to the upcoming launch of QuickBooks 2006 scheduled for early September 2005, less than 8 weeks in the future.
Nobody, and I mean NOBODY, had the expectation that I would be able to make any contribution to the upcoming release. The engineering folklore was that it was ok to take a year just learning the codebase and environment before submitting your first commit to version control. Literally the words from their mouths. The other expectation I learned on my first two days is that it would take 4-6 weeks to requisition my workstation, and that I should just take it easy in the meantime and read hard-copy manuals and employee handbooks.
I asked my manager what my personal signature authority was for purchases and requisitions, and he stated that as a staff engineer, or a manager at his level, we could authorize up to $15,000 per month, and that was managed via the issuance of a corporate credit card (it was intended to cover travel related expenses, not capital equipment). He also shared that the corporate card would take weeks to get issued. On the second day after I arrived at Intuit, having survived the all-day Orientation from HR on Monday, that Wednesday afternoon I went to my favorite computer shop and had them build me a custom workstation that I paid for on my own credit card and took to the office later that evening. It was a multicore beast, with lots of memory and a 4 drive raid array with two Ultra320 SCSI controller cards, and I added two Dell 30" UltraSharp monitors (I always used one rotated 90-degrees to have a 100+ line code editor.) The entire setup was a bit over $10,000.
Thursday, the next day, quite a few people stopped at my cubicle to admire my rig, which I explained was my personal property at the time (at least it was until I got reimbursed by Intuit.) My manager was actually concerned about reimbursement, to which my reply was that I could simply quit if anyone denied the reimbursement. I turned my "manager" into a facilitator, where I made his primary job clearing corporate red tape and getting me invited to strategic meetings held by other teams.
I also made a habit of dropping into conference room meetings just as everyone was arriving (even if I had not been invited), and if anyone asked why I was there, I just said I was a new hire, there to learn what was going on so that I could start contributing. My practice in meetings, unless I was the presenter, was to listen quietly to everything that was said, jot notes on key points, and only speak up if someone asked my opinion. People quickly noticed that I was deeply engaged, and often disagreed with the dominant speaker in a non-threatening way.
Anyhow, that Thursday when I had my new workstation, I spent a couple of hours installing of the tooling recommended for QuickBooks engineers, and also my favorite development tools. I tracked down one of the senior engineers on the SCM build team and had him onboard me to source control (PerForce) and walk me through my first independent build on my own machine. That first build took over 6 hours - on my monster machine. I learned that most engineers worked all day, without a build, then kicked off their private build before they went home at night. I also learned from the SCM engineer that even the official production builds, which they were building with new tooling of Electric Cloud, was taking over one hour on a 20 server cluster.
Later that week, I sat down with one of the "architects" on the Merlin team who had been with the QuickBooks team for over a decade. He gave me a lecture on feature governance and boundaries in the source code, relating that each large chunk of code (from 100,000 lines to 500,000 lines of code) was "owned" by a single staff engineer who had to approve all commits in "their domain". Hmmm ... my thought was 20-30 staff engineers, each as a domain expert? However, I was most interested in identifying the "hardest open bugs" that could drive big impact. He identified a few, mostly performance related, and another one which he called "the ghosting bug", wherein after QuickBooks had been used on a desktop computer, then closed, that it would often not reopen, or sometimes would open multiple instances in separate windows, and the issue could not be fixed without rebooting the computer. He stated that the ghosting bug had been present for at least a decade, but everyone downgraded it because of the reboot work-around. This was a high visibility customer facing bug, and nobody really cared. It was Friday. I set my sights on fixing this bug for the upcoming 2006 release.
"Ghosting"
On Monday, July, 18th I started working on reproducing the ghosting bug inside of a vmware workstation instance. I later learned that nobody else was using virtual machines for their own private testing -- and the engineering management had deemed such tools an unnecessary licensing expense. I was finally able to reproduce the bug after reviewing dozens of bug reports and screenshots in the issue tracker. It was easiest to reproduce on a computer which had multiple versions of QuickBooks installed.
For the target audience of accountants, as opposed to small business owners, QuickBooks had added the ability to install multiple flavors and multiple versions, year over year, in a side-by-side configuration, but intended for only one to run at a time. This feature allowed accountants to run the same version as each of their clients, without forcing their clients to upgrade to the version used by the accountant. It also allowed multiple flavors of the same version year to run from the side-by-side installation -- QuickBooks had half a dozen flavors, with disparate feature sets, targeting different vertical markets, from main street to enterprise.
After observing the bug, in situ, I quickly realized that it was triggered by a race condition between processes, and I learned a bit more about the QuickBooks architecture after I inspected file and memory behaviors with the SysInternals toolkit (another set of Windows developer tools that nobody at Intuit was using.) What I learned about QuickBooks architecture that day was that the desktop icons, for all QuickBooks flavors and versions, launched a shared application (not a DLL library) that was supposed to open the target QBW file, determine its version, then launch the appropriate flavor and version for the specific QBW file. When it launched the secondary process, instead of passing all of the necessary state as part of the command line, it had a "clever" mechanism of sending a windows message to the new process, using the windows message queues, and waiting for a response to that message.
I had just scratched the surface -- I was observing system level behaviors, but had not yet inspected any code. The next thing I observed was that the "ghost" or orphan windows were persistent, and one could move the window frame and resize the window, but that nothing else was rendering, implying that none of the child windows had been created or rendered. I started searching for the program entry point, or "main" in the source code, and two hours later was still unsuccessful at finding the entry point(s) hiding inside of the 10 million lines of code. I broke for lunch, came back, and changed the linker command line to output all of the module symbol tables for both the launcher and the main quickbooks processes. From that I learned that the entry point was actually the initializer for MFC (Microsoft Foundations Classes) written in C++. I had not yet done a debug build with full symbol table support, something that would allow me to single-step through the code and see where the behavior deviated from expectation.
Once I knew I was working with MFC, and an application that was likely a subclass of CApplication, I went back to SysInternals and started studying the windows message queues to/from those respective processes and recorded the observation that if you named subsequent instances of the launcher L!, L2, L3 ..., and subsequent instances of the application A1, A2, A3 ..., if A1 failed to launch and became a ghost, all subsequent Ax would also be ghosts. Also, all subsequent Ly were also zombie processes. That narrowed it down a bit. Once I made that observation, it was pretty easy to conclude that something, for some reason, was jamming the windows message pump.
With SysInternals, I also observed the "custom message" being sent from the launcher to the application. I attempted to find that message number in the source code, and failed my searches again (I found it later, wherein the message number I was searching for was not in the source code, but synthesized at compile time by a macro.)
It was also obvious from looking at the SysInternals message logs that the launcher was a headless, windowless, application, and that the QuickBooks application had at least a "main window". Excited, and not yet ready to go home or kick off a multi-hour debug build from scratch, I continued using the tools I had, such as SysInternals, to observe file system behavior, and after filtering out all of the DLL and application code, I noticed that sometimes, the application process would fail to open the QBW file -- this was the breakthrough moment, and I had not even located the source code yet.
Setting the file monitor filters to only show QBW file access, I learned that the ghosting occurred in a scenario where the launcher opened the QBW file exclusively, the custom message was sent, and the application attempted to open the QBW file exclusively, and failed with a filed locked error. In the non-ghosting scenario, the launcher opened the QBW file exclusively, the custom message was sent, the launcher closed the QBW file, and the application attempted to open the QBW file exclusively, with success, at which point another message was sent from the application to the launcher, and the launcher would exit. Finally, clues.
Other than the obvious fact that there was a race condition between processes, I realized that I would not get any farther with external observations, it was time to go home for the night and kickoff the debug build before I left.
When I arrived the next morning I saw that the build had failed. Another trip to the SCM team lead -- I learned that nobody did a full debug build, and that I should only add the debug flag to the specific modules I was interested in. I removed the global debug flag, set the debug build flag for the main application module, and searched around for a bit in the obfuscated make files, found the launcher module build flags, and set the debug build flag for the launcher application module. Kicked off the build, and walked all three floors again before I returned.
When I returned after lunch, the build was STILL running. I decided to start searching the source code again, with the knowledge that MFC was being used, and looked for subclasses of CApplication and CWinApp in the source code. I located several of each, with the implication that there were even more executable modules than I previously had heard about. I pinpointed the launcher CApplication subclass, and the QuickBooks application subclass of CWinApp. Both were a spaghetti mess of someone who had quickly ported from raw C windows application to MFC, without understanding MFC message flow, and how it differed from their previous implementation directly on the Windows APIs.
From just reading the code of the launcher, I could see one way to partially fix the ghosting problem -- very simply close the QBW file handle before sending the custom message to the application process. The launcher had logic, using FindWindow, to wait until the application had launched and created a custom class for its main window. In a bit of "inspiration" (sic) the FindWindow was an infinite loop until the window class was found. FindWindow was followed by an asynchronous PostMessage of the custom message to the discovered window handle, but the file open/close was at a different scope on the stack, through several layers of delegation from the CApplication class. The file close was followed by another infinite loop, waiting for confirmation from the application with yet another custom message arriving through the message pump, that the application had launched (ie: that it had opened the QBW file). I could have stopped there, refactoring the launcher to close the file prior to sending the custom message ... which I did, and the ghosting did disappear, but that was not good enough for me when I knew that there were other obvious race conditions which were being mismanaged. I wanted to future-proof my design to make it easy for future inexperienced programmers to get their changes correct.
My fix to the launcher was to wrap the file handle in a new object, and implement an unavoidable delete on free by placing the free-handle call into the destructor of the new object. It was freed when the object left the current scope on the stack.
The next question however, was how the interaction between launcher and application had ever really worked in the first place. I could see that if PostMessage behaved in the way that it did on legacy Windows with cooperative multitasking, that the code would have worked 100% of the time, since the PostMessage did not yield, and the file close would always be called before the later check for an inbound "successful launch" message. So, why was it failing ... it was clear to me, that on preemptive Windows process switching, that the Application process could be preemptively moved to the current executing process in between the launcher's PostMessage/CloseFile logic, especially on a single core processor. But, what would cause such a preemptive task swap? The launcher was originally written in native windows code, strictly for cooperative multitasking. It had been ported (poorly) to MFC, and the current windows versions utilized preemptive multitasking in addition to the cooperative multitasking primitives such as Yield(). Given those constraints, I knew that the probable explanation had to be a page fault in the launcher, with an implicit yield in the preemptive scheduling logic of the Windows Kernel itself. Such a page fault was intermittent and depended on memory size and memory pressure against the launch process. I knew that I could trust Windows to do the right thing, and that process preemption on a page fault was bound to happen, so any new design had to be robust enough to go with the flow of the Windows Kernel preemption. Shit -- nobody I talked to that day even knew what a page fault was -- it was simply not part of their programming ecosystem or experience.
Now for reading the application process code. The first thing I looked for was registration of the custom message in the message map. It was not there where it should have been. I then read the various methods involved in the MFC message pump, such as PreTranslateMessage and WindowProc, and I found a subclass implementation of WindowProc that checked a global state flag for "waitForQBW" and "check for custom message" (another race condition with two state checks for one common condition), and could see that there were logic paths that never reached the tail delegation for processing of any window messages other than the custom message or the handful especially carved out by MFC such as SIZE, MOVE, PAINT. That was the moment that 80% of the ghosting behaviors were fully explained. Moving the custom message to the message map, with its automated dispatching, fixed all of those problems on the receiving end.
The remaining mystery from the ghosting observations was to answer the question of why all of the subsequent application instances were zombie frames instead of opening their respective QBW files, and a related requirement question of what was user expectation if they launched a second QBW file while the first file was still open and in use.
Nobody had solved or even documented the UX issue of expected behaviors. I went back to the launcher source code and found myself staring at the FindWindow function call -- if every application instance implemented the same window classname, how did anyone know which application instance to send the launch parameter block to? The real answer is -- it is indeterminate without knowing more of the operating system state, such as z-buffer ordering of the various application window instances within the Windows window manager code. Essentially, an unknowable.
My ultimate fix, which was backward compatible with unpatched legacy versions of the QuickBooks application running side-by-side, was to create a QBWInstance object which took a QBW file pathname as a constructor argument, acquired a Global Named Mutex from Windows, then opened the QBW file using the previously aforementioned QBWFile object that released the file handle in its destructor. Likewise, the QBWInstance object released the global mutex in its destructor. I turned the QBWInstance and QBWFile objects into separate source files and placed them in the Perforce source tree in a location that both the launcher and the new application instances could share the same code for consistency and reuse. This wasn’t just a fix — it was an architectural decision to enforce a single open QBW file at any given time, eliminating undefined behavior and making the QuickBooks UX predictably reliable for accountants.
Still feeling incomplete, I had to fix one last mess that I knew would cause future problems ... the custom launch parameters message. The custom launch parameters message had its own binary payload which was a binary "C" struct. The initial programmers had assumed that the "C" struct would be the same for both the sender and the receiver, but nothing can be farther from the truth when dealing with code and infrastructure frameworks which were evolving over time. The custom launch parameters were also being stored in a temporary file, using a shared "well known name", and with multiple launcher instances, the file could be overwritten, in flight, by any of them, regardless of the state of a read from the application process. Super brittle, crunchy and not very tasty.
I replaced all of the custom message creation, handlers, and file management with WM_COPYDATA, a mechanism sanctioned and well oiled by Microsoft as fundamental to Microsoft OLE (object linking and embedding), and gave it a parseable text payload marshalled from a serialized CSV object format, using CSV support which was in one of QuickBooks numerous support libraries. These days, that would be JSON or a Google-style protocolBuffer. I kept the old custom message creation around, as a separate class, so that the launcher could communicate with legacy versions of QuickBooks which did not yet understand the WM_COPYDATA message.
What had been a brittle, silent-failure-prone, IPC mechanism was now: robust, versioned, future-proof, and self-documenting.
I checked in all of my code to a personal branch in Perforce, kicked off a new debug build of those modules, and went home for some downtime.
The next day, Wednesday, I spent a day consolidating all of the ghosting bugs in the bug database into one single issue, with a complete writeup and source code reference to my new code. I also manually tested my new build to ensure it worked as I expected. I had not written any new automated tests which would detect a recurrence of the issue.
Technical problem solved. All without stepping a single line of code in the debugger.
It was now time to share my findings and work with a larger community -- I booked a meeting room and hosted a peer code review the next day, Thursday, and invited about a dozen people, as many as would fit in the conference room. The meeting included architects, staff engineers, and a couple of product managers.
Eight people showed up to that meeting, mostly out of curiosity since nobody else was actually using code reviews outside of the "code owner" for their part of the source code base. That being said, Intuit was a very social engineering culture and 6 hours of meetings per day was pretty common at that time.
Shot down over the target. Once I pulled up the remaining bug report on the projector, the very fist comment in that meeting was "what are we doing here, we've already declared code-freeze and this bug is not on our approved list of exceptions". I had not heard about the code freeze, which was declared Tuesday when I was heads down working. My response was "maybe we ship this next year then", paying homage to the corporate inertia. My response continued "I am here to share my findings and solution with this group, and I would love for people to shoot holes in it. If you are not here for that, I don't have a problem with anyone leaving this meeting". One person left the meeting. I started whiteboarding the technical issues with the multiple instances of launcher and application, and explained that my solution put a stake in the ground for UX in that only one of many launcher and application instances could open any QBW file. It would not be possible to open a second QBW file if another one was already open. The one remaining product manager indicated that she was ok with that, but wanted to run it by a focus group in the next product cycle. I also shared that who ever had ported the original QuickBooks to MFC from raw Windows code did not understand MFC and, in my mind, that itself was one of the root causes of the issue. Other than that, there was no pushback from the remaining people in the room, they were curious and eager to learn. One of the architects in attendance mentioned that the launcher was not part of the codebase assigned to any staff engineer, and likely would fall under the purview of the product installer team, since they were the only team responsible for "side-by-side" issues. That architect left and brought back with the installer team lead. After a quick recap for the installer team lead, I asked what it would take to get the bug and the fix on the approved exceptions list. The architects and team leads all said at least one product manager, and the VP of Quality Engineering, who also happened to be the line manager for both the Installer and the SCM release team. I told everyone in the room that I would be happy to take ownership of EVERYTHING in the code based on MFC and direct windows apis. That broke the ice completely, and two of the staff engineers in the meeting visibly relaxed and gave nods of approval. One of those staff engineers blurted out that she had some large portion of the codebase she would gladly give to me. What else was lurking in the MFC port? It was only the end of my second week on payroll.
The next day, Friday, July, 22 2005, I met with my manager (aka facilitator) for the weekly 1:1 cadence we had agreed on. He had already read my daily email status and the updated bug reports for "ghosting". I asked him about the product managers (there were over a dozen), which of them was frustrated, which of them was smart, and I focused on an MBA from MIT who had been with the company less than a year. We talked about the VP of Quality and the fact that the VP's secretary refused to put me on his calendar (my title was too lowly for the eminent ship date) and I asked my facilitator to set up a meeting with the VP, using his own clout. I spent the rest of the day walking the three engineering floors and asking people how things were going. I ended up pair programming for an hour with one senior engineer who was working on a "high priority" bug in the payroll system that was on the "approved list". That bug turned out to be a rounding error caused by using floating point instead of fixed point math in one of the payroll tax calculations.
Monday, July 25th, 2005. First thing in the morning, I tracked down the MIT MBA product manager, and learned that he was also an early riser who often came to the campus for breakfast in the cafeteria before starting his day. He shared his frustration with me that his first product feature was not shipping this year, and that although he wanted to vest his next tranche of ESO, that he was not took keen on staying long term at Intuit. He agreed with my take on Merlin being a big-bang which would likely end up just another black hole. After that first meeting, we set up a regular cadence of early morning breakfast meetings twice a week, with no specific agenda other than sharing and friendship. After I explained the ghosting bug to him, I asked him to take product ownership of the UX for accountants, without offending anyone else who owned accountant specific low-level features. He agreed. Later that day, my facilitator and I met with the VP of Quality, I gave him a quick recap of the "ghosting" bug, shared that I had product management support, and asked what he needed to give it his blessing. He started rambling about all of the issues on his plate, and the ship date a mere 6 weeks away, and all of the meetings he needed to attend. Establishing some common ground. I acknowledged those hardships and pivoted to his background -- he too had learned a lot about quality and metrics from his time at Hewlett-Packard, and he had joined Intuit via the CTO's office (not the engineering organization) to train and instill a metrics mindset in the engineering organization from the top down. His view was that he could implement policy hurdles between the engineering team and the production code by measuring metrics and being a gatekeeper to prevent code that did not meet the metrics from getting into production from engineering.
I asked the VP of Quality what was the biggest headache on his plate, to which his immediate response was Electric Cloud -- although EC had been onsite for over 6 months, their builds were still taking over an hour, and could not actually be used to create the gold masters of QuickBooks 2006. He also relaxed and looked at my code solution for the Ghosting problem ... he liked the general approach, but his concern was that nobody else in the company understood MFC at that level, and how to get it vetted ... at this point, we were negotiating. We settled on a smaller patch, my original fix to the launcher, which was essentially just moving one line of code from the wrong place to the destructor of a file object (one of his metrics at the time was lines of code changed per bug fix). I agreed to look into the EC install and report back later that week. Both of us were happy.
The VP of Quality split my bug report regarding the fix for the ghosting, with the original part of the split having the small patch placed on the approved list of exceptions to the code freeze for the patches for QuickBooks 2006, with my larger MFC rearchitecture split into a new bug/issue to be shipped sometime later than gold master. I got what I needed, and I fully intended to dig into at EC over the following week, and did so promptly.
In looking at the EC deployment, and working with the SCM team lead, I saw immediately that a "clean" checkout from Perforce was taking nearly 30 minutes, half the total EC build time, and also learned that there was a complex manual playbook for creating a GM from the actual build artifacts. There were actually 6 GM CD-ROM for each annual release, one per flavor, and no MAKE automation for that process. Also, just from being in the server room, and being able to observe all of the blinking lights on the network switches and the hard drive activity lights on the servers, I could literally see bottleneck behaviors on the hard disk side, wherein the disks were more than 50% idle. After logging into one of the active servers, it was apparent to me that there was too little RAM and not enough SCSI controllers to keep the 4 RAIDed SCSI drives busy on each node. I pointed the direction to the staff engineer, made a separate report to the VP of Quality, and spent the next few weeks pair programming with people who still had open bugs on the approved list of exceptions. All in all, I contributed directly to over 20 patches for the bugs on that list before the GM was created.
I shipped a cure to "ghosting" on the gold master of QuickBooks 2006, defying all expectation, and had begun a new chapter for Intuit. I became a magnet for unwanted code. I made new friends in all walks of the organization.
Organization
code metrics
Windows Vista, 64 bit
google desktop search
Code schizo
field alignment field size struct size missing fields
Database and Schema
Agile, TDD, Design review, code review
Data Structure mess
New Team initiative
Measurable Accomplishments
Aftermath
B-trieve
C
C++
C++ Template Metaprogramming
C#
Visual Basic
VB.NET
.NET
Lua
Java
JavaScript
Embedded Database
SQL
DDL
IDL
code generation
UML
Model Driven Development
Metrics Driven Development
CodeReports
code metrics
Agile
TDD
Peer Design Review
Peer Code Review
Sparx
Enterprise Architect
Automated Schema Validation
MVC
PHP
HTML
Ruby
Google Desktop Search integration
Windows (32 bit)
Windows (64 bit)
Windows Vista (64 bit)
MFC
SysInternals
Araxis Merge
IntelliJ
Visual Studio
Intel VTune
SoftICE for Windows