Bashing C++

It’s easy to bash C++ having Linus Torvalds on your side. But bear with me for a minute and you will see how this bashing post is more argumentative than others.

Before the flame begins, let’s speak about the following two worlds of application development: constrained software and rapid application development.

The former world includes software severily constrained in the run-time by some factor, for example by limited CPU performance or memory. Both can happen either due to cheap hardware (eg. embedded hardware, handsets, etc) or due to the sheer size of the computational task rendering any available hardware to be limited.

Typical examples are operating systems, codecs, 3D game rendering engines, or Google Search. And the top 3 priorities in this world are:

  • Run-time computational performance
    • Theoretical Big-O of used algorithms as well as ability for parallel execution
    • Practical performance of implementation (including effects of processor caching architecture, prediction, locality of data, network congestion, etc)
  • Run-time memory efficiency
    • Theoretically efficient data structures (i.e. not wasting bits for no reason)
    • Practically efficient data structures (including taking care of memory fragmentation, malloc overhead, etc)
  • White boxes instead of black boxes. In constrained situations it is almost never possible to add some new functionality as a black box module with a clearly defined inputs and outputs. Internal implementation of the module will often interfere with the whole system, therefore the black box must be stripped of its case (hence the term white box, although strictly speaking it should be transparent box).

For the lack of established term for this world I will call it CS.

The world of rapid application development (RAD) includes wide spectrum of application software, for example enterprise information systems, web sites, media players, mobile apps, office software, etc. Its top 3 priorities are

  • Productivity, defined as inverse of costs to implement a feature.
    • Money costs: how much developers will charge per feature
    • Time costs: how long we must wait until the feature hits the market
  • Flexibility, defined as inverse of costs to change some existing software
    • Money costs
    • Time costs
  • Black boxes everywhere. A great software architect will split the whole software system in such black boxes that many of them will be reused later, both inside and outside of that system. An ingenious software architect would give his black boxes such a sex-appeal that other developers would eagerly re-use them (without being forced or asked for).

These two worlds constitute by no means the complete list of software universes. There are other worlds like

  • viruses and security-related software;
  • compilers, language run-times and web browsers;
  • games and art (eg. the demoscene);
  • scientific software;
  • statistical and ah-hoc calculations;
  • and competitive programming.

But CS and RAD worlds are the biggest and primary ones, and the other worlds often overlap with one of both of them.

According to mentioned top priority lists, we can quite naturally see what are the usability requirements for the programming tools, especially for programming languages.

The CS world needs a language that is not present in run-time. Ideally, CS software should look like as if it was carefully crafted byte by byte in machine codes, to eliminate any waste possible. Programming languages higher than assembler are for CS developers an embarassing acknowledgement that their minds are not powerful enough to use assembler.

The RAD world needs a language allowing to go live before all the bugs are fixed. This language must provide a lot of information when something goes wrong, and also ideally allow to fix things without killing the process being currently executed. So RAD developers expect language to be very present at the run-time and helping them to fight the last blocker bugs under pressure of already being live with end-users stumbling upon the bugs and cursing the programmers.

The CS world needs a language that will do most its checks at compile time, and possibly check all white boxes of the system against each other, before blessing the compilation result as a whole for its first run. Whenever they can, CS developers would compile everything from OS kernel to user interface all at once, just to be sure everything is checked against everything and all sits and fits.

The RAD world needs a language allowing to replace black boxes without affecting other black boxes; and being able to do it directly in the running system without stopping it (ideally, in a running system being actively used without affecting its performance or letting its users know about the change).

Enter static vs. dynamic languages.

Enter debugging by core dump vs. RAD debugger user experience.

The CS world can only find white boxes useful, and so its libraries reflect that. For example, for a single data structure concept (a mapping between key and value) the standard library might provide an implementation based on hashes and another implementation based on lists, and might be yet another implementation for a special case of key type, as well as basic building blocks to be able to write your own custom implementation.

The RAD world needs a language one can easily (as in: quickly and cheaply) read and understand, so that a data structure concept must be directly reflected in the data structure name, and therefore there will be exactly one data type, preferrably built-in into the language, and its name will be Dictionary (or map).

Enter white box data structures vs. black box data structures.

I could go on, giving more and more detailed examples of how different these worlds are. But that should be enough for us to agree it is impossible to cover both worlds with a single programming language.

And now, it is time to bash C++, as it is guilty.

According to Stroustrup, the initial idea for starting C++ was combining Simula with C. From C, he has used its run-time efficiency (a core CS feature). From Simula, strict static type-checking (another fine CS feature) as well as its concepts of classes and inheritance,  that is, the ability to define black boxes (RAD feature). Wait, a RAD feature in CS world?..

Later on, other RAD features were added to C++, like exceptions,  RTTI, generic programming, and, lately, garbage collection. Stroustrup himself states that C++ is a general purpose programming language with bias to systems programming.

So, what has happened to C++? Stroustrup started with a CS language, added some CS improvements that were bitterly needed (improved static type checking for example, or inlines), but then started to clutter a CS language with RAD features. As a result, we can see all kinds of mess:

1) Some naive people who work in CS world would use a RAD feature (because they don’t know better) and would shoot themselves in the leg. For example, using exceptions inside of a library or system-level tool. And we all wait for the first codec or driver using garbage collection.

2) Some naive people who work in RAD world would use C++ because “it looks so native, pretty guy” and would shoot themselves in the head, because you can’t be productive in RAD without black boxed data structures, and without more powerful reflection, and without dynamic type checking, and without useful error messages when your templates went wront, and with such a convoluted and unlogical syntax, and so on.

3) People who work in a mixed world, like game development, would use C++ both for CS part (i.e. scene rendering) and RAD part (i.e. game objects, AI), with the result that a) their RAD part will suffer from less productivity and flexibility because of poor C++ standings from RAD part of view and b) their CS and RAD parts would tend to uncontrollably diffuse in each other, for example, game objects would have some render support or physics logic.

4) Poor students whose first programming language is C++ won’t understand, what really OOP is, what really systems development is, and what really generic programming is, because all that is so horribly mixed together that you can barely find a teaching book cleanly and concisely separating the CS from RAD in this language.

C++ is an MFU. It can somehow print, and a more or less scan, and sometimes even fax a little. But none of its functions is truly user friendly.

I wonder how Objective C is designed.

The Internet Killer

I hate HTML. And not only from the technical point of view. It is deeper. You see, a lot of persons who have conceived Internet, and WWW and HTML… Their principles and goals are very far from the most folks who want to do something in and with Internet.

Well, may be it is my personal bias, because I have worked for a web company for seven years. But most people who came to us just wanted to do business in Internet. Simple, trivial business. Adam Smith business. To provide products and services for their customers, charge money or show ads for that, and use their Internet application as business platform. That is: not changing world to the better. Not doing no evil. Not publishing hyperlinked scientific papers. And not dealing with stolen properties. Just doing business.

And for doing business, the Internet as we know it, is not very reasonable. Let’s play a simple game. If I were in charge and could reinvent the Internet, with all the knowledge I have today, how would I design it?

First of, I would ensure there is a landing page. You go online, and you always land to my page. Not to a search engine. And you are not entering any URLs. You can’t. All you can, when you come to my Internet, is to open my landing page. Which is technically not avoidable or skipable. If you ever saw the start page of Amazon, you know what kind of landing page I mean. From there, you can search for products you want to consume or activities you want to participate, either using a catalog or free text search. I would employ a department of editors controlling every pixel of that page, and making money on its screen real estate, on the order the items appear in catalogs, anonymized personal profiles, at similar stuff.

As for products, there will be a largest possible variety of them: movies, music, books, photos, cars, homes, jewelry, apparel and all sort of any physical items, news, blog posts, jokes,.. Same for activities: games, chat rooms, social networks, timelines, diaries, matchmaking, genealogy searches… All items would have similar pricing and will have virtually no ordering user experience, because, for a small fee on each financial transaction, I will take care for your payments, and just charge you once a month together with your Internet bill. I will not allow providers of products and services in my Internet to charge you offline. After all, safe, instantious and cheap payments are also in your interests.

I wouldn’t ask you to pay any other usage fee except for the items bought online. You will never have to learn words traffic, gigabyte, kbit/s and won’t pay trafic- or time-based fees as they only distract and prevent you from consuming.  Perhaps you would need to pay a small monthly lease for the modem.

As for the such details like the programming language to implement Internet user experience, I would ensure it can render exactly what I want and how I want, on every your device, all the way down to subpixel level. I would ensure it can fully and directly utilize all your computing power, including full access to bare hardware. And I wouldn’t have many security issues with that, because, naturally, I would technically allow only approved and signed apps in my Internet, and developers would pay me for the priviledge developing them, enjoying in exchange the full freedom of bare hardware access and the most immersive UI and interaction technology available. Well, full freedom, as long as they comply with my terms and conditions… And I would for example force them to develop separate UIs for touch, 2-foot and 10-foot. All for your happy and comfortable consuming experience.

Does it remind you of something? Perhaps, of the dubious iScreen I’ve predicted? When it will appear, it won’t be just TV set killer. It will be killer of the Internet as we know it. And I’m saying “when” and not “if”. Let’s look what has happened today:

  • Apple has announced a quad-core GPU in the new iPad allowing them to attract more interesting games on their platform. Samsung and other handset manufacturers have already done the same, or will surely do it soon.
  • Google has announced Google Play, the Android Market replacement, which is “an integrated destination for apps, books, movies, and music, accessible to users on Android devices and to anyone on the Web”.
  • Microsoft has their gaming bases covered with XBOX and are currently adding portals to consume movies and TV content with the pace of one per month or so.

You better start planning what are you going to do in the shine new Internet world - today.

How to begin

What first programming language should learn a wannabe programmer?

When I was a beginner, we were supposed to build our computers ourselves: layout and make the board, buy the chips, solder them on the board, test and debug the hardware, organize a ROM with some operating system… When we were ready, we could turn on the PC and have two possibilities to develop anything on it: either entering machine codes, or use the built-in BASIC. So, these were the two programming languages I’ve learned first, in parallel.

My first commercial software was a teaching aid for physics lessons and was written on BASIC. I’ve sold it 20 years ago, in 1992, for 50 roubles. The very cool aspect of BASIC was the ability to program something in a reasonable time frame, and immediately see how the program works line after line of typing, which has a reinforcing effect on the motivation of a beginner programmer. On the other side, the cool aspect of machine codes was the fun of working with electronics. I can’t explain it reasonably, but at that times I had enormous fun manipulating bytes and bits in some CPU registers, and observing some effect (such as lightning of a LED) in the hardware. This was something magical. The advanced high technology, staying directly here, on my old table in an otherwise very low-tech room. There was an understanding gap though: I didn’t know how the BASIC statements exactly relate to the machine codes. I know BASIC eventually ends up being machine codes, but didn’t exactly know how and believed it is so complicated I can’t learn it in a reasonable time.

Later, times changed (as they were continuiously changing every couple of years or so), and I’ve learned and used the Clipper programming language to write various enterprise information systems. That was quite a cool language: it had code blocks (also known as closures), untyped arrays aka structs (ala modern JavaScript) allowing to have some basic OOP, and a very beautiful syntax. To program a text box in a form with validation, you’d just write

@ row, col SAY "FirstName:" GET firstname VALID !empty(firstname)

You won’t get it shorter and prettier with any modern mainstream UI language. Clipper also had statements to work with a NoSQL database as first-class concept, and supported multiple styles of programming (ala Perl and Python), so that it is pity it is so completely dead today. In fact, I’m very lucky that this was my third language, because it has gently introduced me to structural programming, to functional programming (code blocks!) and basics of OOP, without looking like “rocket science”. Unlike the modern functional languages who hit you with a hammer by speaking about type systems, monads and other useless academic stuff, Clipper was able to introduce me practical advantages of using these approaches.

Clipper has died, because it didn’t support the new graphical user interface Windows 95 has introduced at those times to the wide public. I had to switch, and my next language was Delphi. For some reason beyond of understanding, at those times I had enormous fun dragging and dropping UI components such as buttons and text boxes onto forms and so visually programming the modern GUIs. I didn’t understand much about user experience at that time, so that wasn’t the joy I feel today when creating a new wireframe or mock-up. The very notion of visual programming was fun. It was so high-level, so rapid software development comparing with the manual coding of forms on Clipper, that it felt as if I were on a roller-coaster. Delphi has introduced me to basic Windows concepts, and because this time that was a slightly more complicated enterprise information system, I’ve used a SQL database, so I could learn the world of relational databases and SQL in particular.

This was the time when I’ve graduated and started my first “freelance” projects. Delphi was a limiting factor though, because it was almost always used only in enterprise information systems. So I’ve switched to C++Builder, which had the same framework (GUI, collections, databases, etc), but was based on C++. With C++ knowledge, I’ve figured out that I could find the way to all kinds of projects and escape from the world of enterprise software. I’ve had hard times making C++ to work for me though. This is exactly the sort of language I didn’t get very well, having syntax so unlogical you could think it is sort of a natural human language, pretending to allow for abstraction level but failing and leaking from all its abstractions, the only language I know whose fans don’t find the very existance of Sutter and Alexandresku with their books and lessons strange. From my current perspective, I would prefer using GLib Object System, if I were for some reason fancy using OOP in a performance-critical app. Nevertheless, I don’t regret learning C++, because it has made me think (for the first time) about programming language designs, and it made me so desperate that I went ahead and tried other programming languages. A whole lot of them. In a merely half a year, I’ve checked out Prolog, ML, Ocaml, Clean, Scheme, Haskell, Eiffel, Perl, Erlang, VB6, Java, and Smalltalk. The latter I loved almost instantly, because it was almost the full opposite of C++ — extremely simple and beautiful syntax, real abstractions, very safe and user-friendly, allowing multi-paradigm, and relatively slow (still quicker than the modern JavaScript though).

I was fortunate to find a job on Smalltalk, and learn from a Smalltalk guru and coincidentally one of the best programmers I’ve ever met, and this experience has changed me forever. Not only I grasped OOP (which was almost destroyed in me by its C++ version), I also understood how OOP fits in the landscape, and what software architecture is all about. Smalltalk is the only programming language I know that is so fun to use and to type. It is like hearing a song that gives you creeps. Or meeting with a guru.

Later I’ve switched to .NET web development, which is basically C#, MSSQL, HTML, and JavaScript. The C# in .NET 1.1 seemed to me quite under-developed (especially after having experienced Smalltalk), but was improving rapidly, and peaked in .NET 4 to be enjoyable and quite productive language. Too bad Microsoft has almost decided to dump it in favor of the horrific C++. Coincidentally, I’ve started to develop myself away from programming, so that I didn’t care that much about the language and the frameworks.

Currently, when I program, I use pure C in an embedded environment. This is fun on its own. My typical task is to understand, how exactly

var mystring = "abc";

in JavaScript gets first allocated in the WebKit’s JavaScriptCore VM, and if VM needs to call FastAlloc to get this memory, how it is represented in its managed space, and if FastAlloc must bump sbrk or use mmap to get more memory from Linux, how exactly Linux would book keep this additional virtual memory, and if this virtual memory will be in fact used, how exactly Linux is going to handle the minor page fault to allocate physical memory, and if free physical memory pages are scarce, how exactly Linux would use kswapd to free up the memory by swaping out least used pages into the swap. This has almost nothing to do with what I did in the last 20 years, and even though it is not like learning a new programming language, it is still learning new concepts and software designs. And this is sort of a filling the gap between BASIC and machine codes, the gap I’ve mentioned at the beginning of this long post.

Learning. This is what you are going to do as computer programmer. Like, not learning two or three languages and be happy forever. This won’t happen to you. Well, I mean, hopefully not. You want to be more than just a computer programmer, don’t you?

So, does it matter then, what first language should be learned by beginners? Well I think yes, in fact it does matter. I believe, you need to start learning with two languages at the same time. The one language should be low-level, bit and byte manipulation on hardware or OS level. It will save you from embarrasment of not understanding how pointers work, or what a variable declaration in high-level languages in fact does behind the scenes. I’d say this language should be an Assember or C, and not C++. The other language should be very high-level, allowing you to quickly unlock your first achievements. But it also should be multi-paradigm and able to demonstrate you various styles of programming. I’d said it should be Smalltalk if it wasn’t so inpractical in the current situation. Well, perhaps JavaScript (including Node.js) is what you’re looking for… Yes, this combination is crazy enough to work out. Start with C and JavaScript, and be on the lookout for your next languages you’re going to learn (hint: it shouldn’t be C++ either. C++ will eventually find and kill you and eat your mind anyways, so don’t be a fool and don’t seek for the meeting yourself).

Visual Studio 2011 User Experience

Just watched the sneak peek video:

They have desaturated IDE chrome UI so that it is mostly monochrome now (i.e. no colors in the toolbar buttons), with occasional splashes of Metro-nesque deep blue colors, and I find it the most successful Visual Studio UI redesign ever.

First, it is stylish. Second, it channels the focus on the colored source code.

Unfortunately, they seemingly haven’t changed a thing in how the source code is colored, which is pity. Source code colorizer developers seem generally to believe being solving the classic computer science problem of “how many colors do you need to paint a map” and use arbitrary well distinguishable colors. The UX aspect of colorized text is ignored. As a result, one can try to enjoy the source code mostly consisting of bold red text with some lighting blue islands in there.

Another thing I liked was a slight improvement of TFS usability for those who use Scrum. The previous TFS UI, known as Team Exporer, was looking like just some random enterprisey piece of shit. Visual Studio never gave it enough screen estate to look reasonable so that you were forced to scroll and to change the window sizes constantly and a lot of times, even I you just wanted to accomplish a very simple task. Besides, it was unbelievable overcrowded with various text boxes and drop downs, most of them being never used in any company of any size and with any process whatsoever, except of perhaps some teams inside of Microsoft.

So, now, in Visual Studio 2011, they have liberated the TFS UI and put it into a browser. Entering a new sprint item takes typing its text and hitting Enter – exactly the same amount of interaction the best tools in this area support (I mean FoxBugs). Adding tasks to the sprint item is more complicated than it has to be and is not polished enough. For example, I’ve found it funny how the presenter was himself not aware of a usability issue, routinely skipping with a quick double-tab the iteration drop-box when entering a new task (0:36:49 in the video).

In general, when I look at the new task dialog, the worst memories of the Team Explorer go through my mind, and I can’t help but ask:

  • Why this warning ”The field ‘Title’ cannot be empty” on the top of the form? It is wrong on so many levels:
    • Reading this warning even before I had a chance to enter anything in the title field insults me.  It really does.
    • This message doesn’t have much value in informing the users how this form works. Users are supposed to use it several times a day, in all sort of circumstances, so that they will quickly learn how to use it and will know even more about it than the guy who has developed it. Because this guy only knows how it is supposed to work, and the users know how it really works.
    • There are bazillions of web sites in the Internet having a form, and absolutely most of them (like, 99.9999%) indicate obligatory fields directly in there (by using a star, or a less bold color for optional fields). Why not follow this practice?
    • Isn’t the title field actually the only one obligatory field in this form? If it is, why do they need to use a validation framework producing this very robotic, inhumane wording of the message, instead of just checking it with a single if-statement and printing a handcrafted message?
    • The message is technically wrong, because, well, the Title field can in fact be empty. If anything, it must read “You probably don’t want to create a task with an empty title” and appear only after the user hits Save.
    • Why having users to read anything at all? Just mark the title field red. Your users are software developers. They do really know, what it means.
  • Why the title field doesn’t have a title? All other fields have one.
  • Why do we need an iteration drop-box just below the title?
    • Isn’t the description what is the second-important field after the title, so it must be directly below it?
    • Do we want to have sprint items spanning across the sprints, or what is the other reason for the possibility to set the iteration on the task level?
    • Even if we want to enter iteration on the task level, is a drop-box the best possibility? Or perhaps just a check-box “not in this iteration” would suffice to move the task to the next sprint?
    • Why do we both use words iteration and sprint? Can’t we just agree once what software process we’re using and configure TFS so that it uses consistent wording everywhere?
  • Status and Details are split into two columns. Sometimes you have to do it, if you have a lot of information and not enough screen real estate. But in this case, why can’t we just scrap a lot of fields? This is a form to enter a new task, not to edit existing task, right? So, for a new task, we for sure don’t need the fields State, Reason, Blocked, Activity, and History. Let’s see if we can remove even more fields.
  • Backlog Priority. The same question as with the Iteration. Do we want to have tasks with a different priority that the corresponding sprint item, and why? Even if we really want, why not implementing the priority by using drag and drop just like they can do it with sprint items?
  • Area. This is something I haven’t understood in TFS and still refuse to understand. I mean, why do we need to have two trees (the iteration tree and the area tree) if we can live with a single, combined tree? Well, OK, if your business is to develop a leading desktop and server operating system deployed everywhere in the world, your component and iteration structure might become so complicated that this would require splitting these two fields. But Microsoft, there are really other companies who develop software using the Microsoft Ecosystem. And most of them (like, 99.9999%) never ever develop a product that would have more than a couple of iterations and components in the same TFS repository. Besides, in the most scenarios, the person(s) assigned to the task uniquely identifies the area, because, normally, it is a good idea to clarify responsibilities in the team even before the first sprint planning starts, so that everybody knows that, say, Alice is the database gal, and Bob is the frontend guy, and Chris oversees the REST web services. So, let’s make an uneasy decision and remove the area field and see if the percentage of those who disagree can be ignored!
  • The “Links” functionality seems to be implemented in the same way as in the Team Explorer – each link is an item in a list box, and you have to push a button every time you enter a link to add it to the list. Yikes. Let’s just allow users to paste links into the description field, and recognize and summarize them in a list automatically. Even Facebook can do that.
  • The “Attachments” functionality has a similar issue. Just let folks to copy the image, PDF, DOC or whatever file they have and paste it into the description.
  • The “Description” field. There is no rich text formatting there, is it? Why? You have to be a Byron to compose a really expressive description without usage of typographic tools and formatting.
  • The buttons below the form. TFS is a product targeted for Windows developers. If there are such persons who are Mac or Linux users but still use TFS, God will surely bless them, but let’s concentrate on our core public. And in Windows, these buttons are always called “Apply”, “OK” and “Cancel”. Always. Ever.
  • And last but not least, the Assigned To field. I don’t know how does it exactly work in there. In the Team Explorer, I couldn’t select several assignees. I was constantly finding myself in a situation where a task can be done by anyone of several developers, and wanted to leave it up to them. The one who cares most should pick up the task. So I ended with assigning the task to a dummy user “nobody” and communicating with the affected coworkers offline.

Gee, that was a lot of harsh critique. I’m looking for someone who can teach me how to criticize in a less aggressive way…

Anyways, here is what I would propose instead:

I push a button to create a new sprint item. A window with Microsoft Word like UI opens up.

In addition to the usual text styles, there are styles to represent sprint item title, task title, a person and so on. The current text style is preset to be sprint item title. I type the title and hit Enter. The text style changes to description. I type the description. Now, when I type “@Damian”, the window automatically recognizes it and changes the text style to person. Similarly I can enter a task title.

Generally, I communicate with my team in the same kind I would use if I was writing an E-Mail with tasks. When I hit the Save button, the following happens in the background. TFS parses each sentence. For each sentence containing text with task title style, it creates a task and assigns to it all the persons mentioned in the same sentence. The persons get notification links leading to this sprint item (not to their particular task). The tasks are automatically assigned to the same iteration the containing sprint item is assigned to.

I can right-click on a task title, and an overlay (in the same look as the overlay in Microsoft Word) appears near it, allowing me to enter the remaining work hours for it and change its state. These changes are directly represented in the text, for example by partially coloring the background of the task title, or by striking it through.

One way to reassign a task is by directly replacing the person’s name in the corresponding sentence. When I save the text, a history will be created for that change, and I can optionally enter a comment for it. I also can pass the ball by writing an additional sentence, mentioning the task and another person there. In this case, this additional person will be assigned to the task and will be notified.

If any of words can be recognized as Microsoft Exchange calender resource (eg. Meeting Room, Beamer etc), it will be underlined. If I click on it, Outlook will open with a meeting planning window. Me myself and all persons mentioned in the same sentence will be automatically added to the meeting, and the sprint item and task titles will be put into the subject.

I believe, this UI has several advantages. For the end users, it is plainly more ergonomic and allows for a more humane communication at the workplace. For the decision makers, it looks not less enterprise-ready than the original TFS interface, because it just capitalizes on (and integrates with) existing enterprise-grade tools like Word and Outlook. For Microsoft, it allows to additionally target startups and middle-sized companies still working “in startup mode” because of much less bureaucracy in the UI. And, just in case Microsoft would like to support other big companies allowing them to develop software as huge as Windows using TFS, they can still hide somewhere in the context menu the “Properties” menu item, opening the full property sheet of the corresponding task. But, frankly speaking, I would rather not do even this and allowed to access the full scope of the task object by using a command-line tool like tf.

But that’s another story.

 

Software Development Culture Test

This is a test of your organization software development culture. The answer ”a” gives you 0 points, “b” gives 1 point, “c” gives you 2 points, etc. Sum all the points. You can spent as much time as you want to.

1. Software Design Approach.
You need to program a new feature.
a) You read a manual, a book or search in google for possible solutions, and select the best one.
b) You inform yourself about the used tools (programming language, framework, templates etc) and come up with an own solution.
c) You come up with at least two different solutions before you start coding, compare them, understand positive and negative features of them, tentatively select one of them, code, test, and perhaps switch to another approach.

2. Code implementation approach.
a) You find a solution in google and paste it to your code without reading.
b) You find solutions in the Internet, read them, and re-implement them, using your code style.
c) You write your own solution.
d) You write your own solution and open source it.
e) Same as above, but you also write a unit test.
f) Same as above, but you also write some documentation.

3. Interface design approach.
You have two different processes and have to design an RPC interface between them.
a) You don’t create your own interface, but find and use some another existing function instead, that sometimes coincidentally does almost the same thing you need.
b) You think of one possible piece of data that should be transferred between the systems, define a function for that, and call it a day.
c) You think the interaction between systems through, possibly helping yourself with UML sequence diagrams. You go through all use-cases you want to focus on in the first version, and ensure that the API has a complete set of functions and data structures.
d) Same as above, but you also implement both sides of the interface (create DTOs and function proxies) as a library.
e) You also check that both sides of communication are always in a predictable, correct state, no matter how the other party might misbehave during the communication. You ensure absence of racing conditions. When appropriate, you implement the communication in a secure way. Both sides of the communication log the sent and received data to enable API debugging.

4. System architecture design approach
You have a single feature that has to be distributed across different systems (eg. client / server system, or systems with several CPUs).
a) You find at most one possible cutting line and cut the feature along it.
b) You split the feature into the layers (eg. Application & UI, Middleware and Hardware-specific Code) and draw the border along a layer.
c) All your features are split along the same line, so that layers nicely map to systems.

5. Bug fixing approach
a) You guess bug reason without reproducing it, perform a change, check that the software works, and close the ticket.
b) You first ensure the bug is present by reproducing it, then proceed as above.
c) You reproduce the bug, then understand exactly why it happens, then fix it, then check it is fixed, then remove the fix, check it is broken again, the redo the fix and check it is fixed, then set ticket to “ready to test”
d) As above, but you also create an automated unit test for this very bug, and run it every time you release the new version (or even every time somebody commits a change)
e) Same as above, but you also reflect what other parts of  software could have a bug of similar nature. For each such place, you reproduce the bug, implement similar fix, and test it.
f) Same as above, but you also post a wiki article / communicate with other team members in case of an especially nasty bug.
g) Same as above, but you also submit a bugfix, in case you’ve fixed an open-source software.

6. Usage of SCM
a) You don’t use any SCM
b) You commit once a week without writing a comment.
c) You commit once a day, but regularly have changed files you never commit to SCM, and your comments are not very informative.
d) You commit several times a day; after each commit you don’t have any changed local files anymore. But you think branching and merging is dangerous.
e) You can freely use all SCM features (including merging). You prefer using SCM over commenting out unused code paths, because it is more comfortable.
f) You have hooks on SCM server (for example, a continuous integration server, an automatic e-mail, or a automatic policy checker)
g) You have an established code review process.

7. Release process
a) You just copy over some compiled files happen to be stored in various folders on your development PC. You don’t label the state nor have a trackable version identifier.
b) You set a label in SCM, but create your release by manually and selectively cherry-picking some specific files.
c) You label a release in SCM and create a release from that state automatically, so that you can always recreate a bit-identical release by running an automatic script.
d) After each release, you run automated tests and then optionally automatically deploy the software in production

8. Code Ownership
a) Each team member owns a specific set of source files. Nobody else is allowed to touch them.
b) Everybody is allowed to change any files. Nobody feels responsible for any file.
c) Everybody is allowed to change any file by implementing the change locally, testing it and sending it to the file owner with suggestion to check and integrate the patch.
d) Even when changing my own files, I send my change to a peer code reviewer and get his sign-off.

9. Communication strategy
a) Information doesn’t flow horizontally or flows accidentally (meeting someone in the coffee kitchen: oh, by the way, do you know that…)
b) There are dedicated persons (leads, coaches, managers) who are responsible for information flow
c) Information gets stored in the project’s wiki
d) Project’s wiki is a very popular highly visited place, not less entertaining than Facebook/twitter

10. Project planning
a) Software developers don’t plan projects and ignore project planning of other people (eg. managers).
b) Software developers try to achieve deadlines declared from outside (eg. by managers) and fail doing that.
c) Software developers write down an own realistic plan and work at least once a week with management to establish a common realistic roadmap.
d) Most deadlines are met.

 

26 to 37 points: you probably work at some Software Developer Paradise like Google

15 to 25 points: you’re industry standard.

0 to 15 points: you’re in hell, get out of here!