Sunday, July 07, 2013

Are You Experienced?

A recruiter recently asked me to answer some questions for a client, so I did. I thought it might be worthwhile to save the questions and my answers and make them public so that I can refer people to them.

How many years of C++ experience do you have & have you worked with C++ during the last 2 years?

I've been using both C and C++ since before the C89/C90 standard and well before the C++98 standard. I taught myself C programming in college -- I did not learn it in a class. I initially used C++ when there were various sets of object-oriented extensions to C like THINK C and Microsoft's "structured exception handling" for Windows NT 3.5.

It's hard to provide an exact "number of years. At some positions I worked more in plain old C, or Java, or NewtonScript or other languages, but even in those jobs there were often times where I was working with small C and/or C++ projects on the side.

I own copies of the ISO standards for C and C++ (C90, C99, and C++03) and used to study them for my own edification, so that I could write more portable code. I used to subscribe to the C++ Report magazine. I used to write C and C++ interview test questions for screening people at the University of Michigan. I own dozens of books on C++ and have studied them extensively. I was definitely a C++ expert, although I was much more of an expert on C++03 than C++11. I am not so interested in the "cutting edge" of C++ these days (see below for notes about STL and C++11/C++0x). For example, here's a blog post I wrote about the C++ feature "pointers to member functions," in 2006:

I have used the following compilers and frameworks for paid work (off the top of my head, these are the major tools I've used, and I am probably forgetting some):

THINK C / Think Class Library


Borland C++ with the Object Windows Library and TurboVision for MS-DOS

Microsoft Visual C++ starting with 1.0 / MFC

CodeWarrior / PowerPlant class library and Qt

XCode (aka ProjectBuilder) / CoreAudio

GCC ("g++") / Lectronix AFrame library

TI Code Composer Studio

In addition, I have some experience with static checkers (Lint, Understand for C/C++, QAC, etc. -- more are mentioned on my resume.) and I would say they are a must for large commercial code bases. Also, I have worked with profilers, various run-time debuggers, and tools such as valgrind -- these are incredibly useful and helpful in finding bugs, especially in the use of uninitialized memory.

So, how do you put that in an exact number? I'd say I've used C++ daily for perhaps 12 years, but even when I was not using C++ as my primary development language for a given job or set of projects, I used it at least a little bit every year for the last 24 years. So somewhere in between those numbers.

In the Last Two Years

Yes, the most recent project was a server for Lectronix, something called the PTT Server, that sits on top of the AFrame framework and receives requests via JSON-RPC, and manages the state of all the discrete IO in the system. It is a multi-threaded application using message queues and hierarchical state machines. The server is not very big, maybe 7,500 lines of code, and the top layer of it is actually generated by some internal Python scripts. During this period, I was also maintaining and adding new features to several other servers and drivers as needed.

If the client wants to know whether I am familiar with C++11/C++0x, the answer is "not very much." I have not studied the C++ 11 changes very much yet, so I am only slightly familiar with features like enum classes and lambdas. At Lectronix, we chose not to try to adopt new features for an existing multi-million line code base, and we stuck with slightly older, well-tested versions of our compilers. I have definitely used STL, but we do not use it heavily in embedded projects, because of a conservative attitude towards memory use and hidden costs. We also tend to avoid things like and multiple inheritance in embedded programming, although I have used these features in the past. We tend to deliberately use a conservative subset of C++.

While I consider myself an expert on C++, it is not the be-all, end-all of programming languages. Learning other languages has made me a much better programmer and able to see problems from different perspectives. For example, I have on several occasions prototyped designs in other languages, for example Dylan or Haskell, to refine a _design_, and then ported the design to C++ to produce the shipping product.

I believe the industry is gradually moving towards functional programing, and languages such as Scala (that runs on the JVM) or Haskell (which can now generate code for ARM on "bare metal"), and embeddable scripting languages on top of C/C++ for configurability (for example, Lua on top of a back end written in C++ is the structure of most high-performance commercial video games). Even sticking with plain C++, there is no denying that Clang/LLVM are very promising developments -- Clang has the best error-checking and static analysis I've seen so far for C++, and for Objective-C this static analysis has allowed a feature called ARC -- automatic reference counting, which is basically garbage collection without having a separate background task that can create "pauses."

I have a strong interest in figuring out how using tools such as these, to make a business more competitive, specifically reducing line counts and bug counts and improving time to market. If the client is not interested in any of that, I'm probably not actually going to be the best fit for them, since they will not be making maximum use of my skills. I see myself as a full-stack software developer who should be able to choose the best tools for the job, not strictly as a C++ programmer.

What recent steps have you taken to improve your skills as a software developer?

Recently while still at Lectronix I was asked to re-implement some logic for handling the "PTT" (push to talk) signals for police radios, microphones, and hand controllers. My supervisor wanted me to use a library for handling HSM (hierarchical state machine) designs. I had never worked with hierarchical state machines, just flat state machines, so this was a little bit of a challenge. My first drafts of the state machines were not very good, but I arranged to meet with some other developers in my team who had more experience with HSM designs and improve them. After a couple of revisions I got the state machines up and running, they were simpler than the original design, they passed all my testing and all the bench testing, and we shipped them in a prototype for a police motorcycle product. So I now feel that I understand the basics of using hierarchical state machines as a design tool.

While unemployed, and although the job search itself takes up a great deal of time, I have been working on teaching myself Objective-C programming, something I've wanted to learn for a long time, and the basics of Apple's iOS framework for developing iPhone and iPad applications. My goal is to get a simple game up and running and available in the app store as a small demonstration project to show potential employers. Even if the first version is not sophisticated it should prove that I can build on those skills. I am doing this work "in public" -- sharing the code on github and writing about the design experiments and trade-offs on my blog. Here is one of my blog posts about the Objective-C implementation of the game:

The latest code is available on GitHub here:

I am also attempting to master some of the slightly more advanced features of the Haskell programming language, and functional programming in general, on the grounds that I believe that properly using functional languages such as F#, Scala, and Haskell can provide a competitive advantage, and give me the chance to bring that advantage to an employer.

Describe any experience you have in developing desktop applications.

Just to expand on some items from my resume and some that aren't:

In college I worked with a mathematics faculty member to develop an instructional multimedia tool using HyperCard and XCMD plug-ins that I wrote in THINK C for teaching calculus. I developed various other small applications for "classic" MacOS too, including a tool to edit version resources and a startup extension.

At the University of Michigan's Office of Instructional Technology, I built several instructional multimedia applications for students -- based around HyperCard stacks with custom XCMD and XFCN plug-ins written in C, Toolbook programs that integrated content from videodiscs, and a Visual BASIC application that used digital video to teach manufacturing process re-engineering techniques to business school students.

As a side project, I used Borland C++ and the TurboVision for MS-DOS framework, and also Visual BASIC for MS-DOS, to develop a survey application "front end" (to collect data at remote sites) and "back end" (to read the data from discs and aggregate it and display statistics) for the National Science Teachers Association (NSTA).

At Fry Multimedia, I built a prototype, with one other developer, in C++ using the MFC framework, of a Windows application to search a large CD-ROM database of compressed business data called "Calling All Business." This featured a "word wheel" feature that would match entries in the database and display matches while the user typed in search strings.

At the University of Michigan Medical Center I wrote, among other things, a Newton application that administered surveys to people in the ER waiting rooms. This was not desktop so much as "palmtop" but the same emphasis on user-centered design was there. I also either wrote entirely, or collaborated with another developer on, several internal applications, such as a Macintosh application written in C++ to upload data from the Newton devices, an application written using Metrowerks CodeWarrior (in C++ using the PowerPlant framework) to use AppleEvents to control Quark XPress in order to print batches of customized newsletters while providing text-to-speech feedback.

At Aardvark Computer Systems I completely rewrote the GUI application for controlling the company's flagship sound card product, the Aardvark Direct Pro Q10. This featured a mixer interface with knobs and sliders and animated meters to display audio input and output levels on all channels, persistent storage of mixer settings, and was built using C++ and the Qt framework. I also ran the beta-test program for this software.

At Lectronix, my work did not focus on desktop applications but I was able to occasionally contribute code to the Infotainment system GUIs, written in C++ using the Qt framework.

Describe any experience you have in developing server-side applications.

The bulk of my work at InterConnect was revisions to a server application written in Java that ran on Sun machines, and parsed "page collections" (bundles of scanned page images) along with metadata, a combination of XML including Library of Congress subject heading data and MARC records, to populate Oracle databases. These were large collections (terabytes, and that the time that was an unusually large amount of data to put into a web application). The data was housed on the client's EMC storage RAID arrays (at the time, very high-end systems). A full run of the program to populate a "page collection" would take several days. I worked with the client's Oracle team to debug issues with their database, particularly stored procedures written in PL/SQL, and with their production team to try to determine the best strategies for data issues; I wrote code to "clean" this data). The client was ProQuest (formerly University Microfilms International and Bell and Howell Information and Learning), and I worked specifically on the back-end for the Gerritsen Women's History collection and Genealogy and Family History collection. When InterConnect handed over development to ProQuest's internal team I wrote documentation on the import process and gave a presentation to explain it to their team.

Much of my work at Lectronix was also server-side applications, in the sense that all the code on products like the Rockwell iForce system was divided into drivers, servers, clients, and GUI code. Servers interact with clients and other servers using a network sockets interface wrapped in the Lecronix proprietary framework. So, for example, the Audio Zone Manager (AZM) server receives all requests as remote procedure calls and handles multiple clients. For some complex tasks like "priority audio" text-to-speech prompts it sets up a session where a client requests a session, the AZM lowers the level of "foreground" audio such as FM radio, the requesting client is granted a token, and then must make "keepalive" messages using the token, in order to keep the priority audio active. Multiple clients can request priority audio using different priority levels and the AZM must be able to handle requests that are "immediate" (only valid now) or requests which can be deferred, queue up these requests, and manage termination of expired priority audio sessions if a client process fails to send "keepalive" messages.

The more recent PTT server has a similar, multi-threaded design, where multiple instances of hierarchical state machines are fed messages via a serializing message queue, and there were various APIs to drivers that the code called, some that returned immediately, and some which blocked and returned only when a new state was available from the DSP (for example).

These are two examples; depending on what is meant, some other things I've worked on might qualify. For example, applications that support AppleEvents, wait for serial data, or run as "daemons" handling audio transfer between a driver and user-space applications on MacOS X, or run as interrupt-driven tasks to mix audio data.

Describe any experience you have in developing web applications.

I am not familiar with Microsoft web frameworks like ASP.NET so if this employer is looking for someone who would "hit the ground running" to develop web applications using that framework, I'm not that guy. I would be willing to learn, though, and I think I have a track record that indicates that I could.

I am not a database guru -- I have worked with databases and solved problems with databases, and I can understand basic database queries and the basics of database design but I am not an expert on (for example) query optimization for SQL Server; again, that is something I'd have to spend time learning.

I have not recently developed web applications using stacks such as LAMP (Linux, Apache, MySQL, PHP) or Ruby on Rails. However, I did work on several early web applications using Perl CGI scripts and plain old HTML -- for example, at Fry Multimedia I developed the web site for the Association of American Publishers. I was a beta-tester for Java before the 1.0 release and wrote early experimental "applets."

At the University of Michigan I used Apple's WebObjects (Java, with the WebObjects framework) to port my design for the Apple Newton survey engine to the web.

Later, while at InterConnect, I did some work (fixing bugs) on InterConnect's Perl and Java framework for "front-end" web sites -- the engine that generated HTML from database queries and templates, and made fixes to the web applications themselves in Perl, although this work was not my primary focus (see above).

I can solve basic Apache configuration issues and I've done small projects to set up, for example, a personal Wiki written in Haskell on an Ubuntu server. For example, I had to do some problem-solving to get this functioning under Mountain Lion (MacOS X 10.8). I wrote recently about this here:

What development project have you enjoyed the most? Why?

I have enjoyed a lot of them, but I'll give you one specific example. Back at the Office of Instructional Technology at the University of Michigan I worked with a faculty member in the School of Nursing to develop a program to teach nursing students about the side effects of antipsychotic medications. For this project we hired an actor to act out various horrible side effects, from drowsiness to shuffling to a seizure, and videotaped him. I enjoyed this project a lot because I got to collaborate with several people, including Dr. Reg Williams. I got to have creative input at all levels, from conception to final development -- for example, while developing the ToolBook application, I added animations to show how neurotransmitters move across synapses. I learned a number of new skills, including how to light a video shoot and the use of a non-linear video-editing equipment (Avid Composer), and I got to see the final system in use and receive positive feedback.

So I would say that what I liked most about that project was (1) being involved in the design and implementation at all stages, (2) the chance to work with some very collegial and welcoming people, and (3) being able to learn several new skills, and (4) being able to "close the loop" and see how the final product was received by the customers (in this case, faculty and students). I have since then worked in many development situations where different parts of that process were lacking or non-existent and they often make projects less enjoyable.

Here's a "runner-up." In 2000 I did some consulting work for Aardvark Computer Systems, assisting them with getting their flagship audio card working on Macintosh systems. Where the multimedia application I worked on several years earlier was high-level, this was very low-level: the issues involved included data representation ("big-endian" versus "little-endian"), and the low-level behavior of the PCI bus (allowed "shot size" and retry logic). Debugging this involved working closely with an electrical engineer who set up wires on the board and connected them to logic analyzer probes, and configuring GPIO pins so that we could toggle them to signal where in the DSP code we were executing. This was tedious and fragile -- even while wearing a wrist strap, moving around the office near the desk could produce enough static electricity to cause the computer to reboot. The solution eventually required a very careful re-implementation of the PCI data transfer code using a combination of C and inline Motorola 56301 DSP assembly language. I had to pull out a lot of very low-level tricks here, paying close attention to the run-time of individual assembly instructions from the data sheet, borrowing bits from registers to count partially completed buffers, studying chip errata and documentation errors in the data sheet, and dealing with a compiler that did not properly support ISO standard C and would let you know this by, for example, crashing when it saw a variable declared const. This also was very enjoyable for the chance to work very close to the hardware, learning new things, solving a difficult problem, working in close collaboration with a talented engineer, and getting the chance to actually ship the solution we came up with. In retrospect we forget the tedium and bleary eyes and remember the success.

No comments: