Hiring Engineers

A company in Texas was trying to hire a C++ programmer. They were getting absolutely no candidates. So they asked a development forum for help in determining what they were doing wrong. Let’s see what actual developers told them.

Actually we can start with the ad this company placed. They were looking for a video software engineer. They require solid video experience. And they want with app or driver experience. There are some other details like full life cycle, high reliability, and multi threading. But you get the idea.

Most of the comments from developers was to list the salary being offered. Even if it was just $85k, the amount might get you some bites. You can get a lot of interest if you list the pay rate as $160k per year. One guy came out and said “everything has a price”.

Next you can reword your job listing copy. Change the job title, as a video engineer is rare. Or you could just list the bare minimum of requirements and weed out the candidates that come in.

Another tactic is to relax the requirements for the job to open the net wider. You could accept non-local candidates. You could also allow working remotely. Perhaps you could also consider C# or Java programmers who could pick up C++.

There might be a root problem preventing candidates from coming in. Good C++ developers are working on Wall Street or doing game development. C++ developers usually stay at their companies for a long time. It is rare to be able to catch them between jobs. Depending on how you look at it, C++ is either dying or becoming a niche market.

I personally love C++ development. For the last 10 years I have been coding mainly in C++. Although I am not tied to it, I prefer coding in C++. Unfortunately I am too far away from this particular job opportunity.

Model Driven Theory Wrap Up

Some time ago I read a whole book about Model Driven Software Development. This seemed like a hot topic. However I found the subject a bit boring. There were some key points I picked up from the book. I share them here today.

Define your model using UML. Then you should automatically generate between 60 and 80 percent of your code. Keep the this auto gen code separate from developer produced code.

Here are the four meta levels for Model Driven Design: M0 is the instance, M1 is the model, M2 is the meta model, and M3 is the meta meta model. Look at that for a second? How can you not LOL at meta meta model?

How do you know whether you have a good architecture? First it meets all of the requirements. It allows future growth of the system. It is clear and succinct. Finally you have good supporting documentation. Hopefully the next theoretical book I read will be more interesting. I tried reading some of the classic more recently. They were even more boring. I could not finish them.

Technical Debt Solutions

Schedule pressure often results in developers hacking to get the job done quickly. Unfortunately these hacks become the production code and do not get fixed. Over time this can make a legacy product difficult to work with. We call this Technical Debt. The best fix to this problem is to not resort to hacking. But tight schedules are a part of life. And bad code gets put into production. Once the damage is done, we need to regroup. Otherwise legacy systems will become impossible to maintain.

Here is a small process that can be used to address Technical Debt. Identify where you have the debt. Construct a business case to justify working this issue. Fix the debt. Rinse, lather, and repeat. The process sounds simple. But it might be hard to sell the business case. You should therefore try to choose the debt where you will get the biggest bang for your buck. It is also best to get team consensus before moving forward with a plan to remove the debt.

There should be a main point of contact for your technical debt reduction program. Here are some other tips to sell the idea. Produce tangible examples of how the debt affects the business. Make use of analogies to communicate the effects. It is easy to get into debt with software systems. Just like credit cards, it will take a big effort to get out of debt.

Development Estimates

There are many difficulties in estimating how long a software development project will take. You cannot compare estimate for small systems to those of large ones. The rate of development is not linear as the project size goes up. It just does not scale.

Another common fallacy in estimates is that developers spend the whole day coding. You will be lucky if they get to spend 50% of their time in development. Productivity also depends on the task complexity. Expect to get around a thousand lines of high level code a year per developer.

Here is another tragedy. Sometimes when a developer just tries to get their part done, it is to the detriment of the overall project. Want to hear more depressing news? The first system built is hardly ever a usable one. Next time I will continue with ideas about design and development.

The Power of Documentation

It is best if your user manuals are accurate. Choose this over exciting text. It is difficult to be exact. The spoken English language does not lend itself to written clarity. Know this. When there is some discrepancy between the system and the documentation, it is easy to fix the documentation.

If an implementer has a problem understanding the design, they should get on the phone and call up the architect. I know I get calls all the time on stuff I design. This is natural. It is better to do this than to guess and get it wrong. By then it will be too late or too costly to resolve.

A rare combination of skills is the technical guru who can also do project management. However if you can find one, it is best if they manage a small team of about 5 developers. This team will have great productivity and success.

Next time I will share a lot of pitfalls with scheduling estimates.

Model Driven Software Development

I read a book from 2003 on Model Driven software development. Let's first define what we mean by model. A model is an abstraction. It is cheaper than a real system. The problem is that models are not kept up to date with the code.

MDSD stands for Model Driven Software Development. It is also known as MDD. Right now models are just treated as documentation. However in MDD, models are at the same level as code.

A related topic is MDA, which stands for Model Driven Architecture. This is where you focus on UML to do design. UML produces nice looking documentation. Some problems that plague software development are productivity and risk management. MDSD intends to address these shortcomings.

Next time I will start with the hot topic of Domain Specific Languages (DSLs).

Airplane Experiment

Let us imagine an experiment. We transport some engineers from the 1890's to the present time. Then we give them a ride on a 747 airplane. After that they return to 1890. Having experienced flight in an airplane, they now know it is possible and want to build some planes in their own time.

This is problematic. The engineers recall the heavy metal bird from the future. So they conclude that weight is not a problem in propelling planes. They also fondly remember the plush seats inside the plane. The engineers design that into their primitive 1890 plane. Finally they recall that steel was used extensively in the 747. They take their own 19th century steel, and try to form an airplane. The result? Fail.

The whole exercise is to get you to understand how an observer of something that works does not necessarily gain the deep knowledge required to replicate the technology. The same probably holds true for Artificial Intelligence. You can study an intelligent being like man. However that does not mean you are any further in developing AI. In fact, you might be tripped up by your limited understanding and go down the wrong path. You got to take those baby steps like the Wright brothers. Otherwise you may never even get off the ground.

The Chinese Room

Here is an artificial intelligence riddle of sorts. There is an English bloke locked in a room. There is room enough under the door to the room to slide a single sheet of paper. The guy frequently finds papers shoved under the door.

The papers the guy in the room receives has strange markings on them. However he has a big book in the room. The book provides instructions on how to formulate responses to the papers that come into the room. The English gent follows these instructions to the tee. He composes similar sheets with weird markings in accordance to the Book of Knowledge in the room. He then slides these response papers back under the door out of the room.

On the outside, there are a bunch of Chinese scholars. They pose tough questions written in the Chinese language to the guy in the room. They write their questions on pieces of paper in Chinese. Each of them is amazed at the answers that come back out written in perfect Chinese. These scholars presume that a great Chinese scholar is on the other side of the door in the room. However this guy does not speak or read Chinese. He just follows the instructions from the big book.

Does the room speak Chinese? Or more specifically, does the system know as the room know Chinese? If it does, you probably could concoct a computer that thinks using a similar process. Once you know what is behind the code used to run the program, you will know that the computer can't think. However from the outside, it would be difficult for one to tell the difference. Such a computer program might be able to pass the Turing Test.

Computer Chess

You would think it an easy task to get a computer to play chess. That might be true. But it is not easy to get the computer to play chess very well. Perhaps chess is not just some mathematical equation to be solved.

True you could have the computer consider all kinds of future moves. The processing power helps with this task. However there are just too many computations to do this in real time.

The next best bet would be to get a computer to learn how to play chess well, almost like a human would do. Well IBM put its programmers to the task. The produced Deep Blue, which took on the world's human chess champion.

The programming behind the scenes with Deep Blue could occupy a whole book. Here are two tidbits. The computer program evaluates the situation of the chess board for every possible move. To speed things up, the program prunes off poor decisions from the tree of possible future moves. This helps it spend time "thinking" about the best moves.

Next time I will tell you a riddle about The Chinese Room.

The Real Turing Test

The original Turing Test is a little different than I normally hear it described. It starts with a man, a woman, and an interrogator. They communicate using text. The interrogator tries to determine which one is a woman. The man impersonates a woman.

The trick is that the man is then replaced by a computer. Now the interrogator tries to determines which of the two (computer or woman) is the computer. It is a test of how well the computer can simulate a human.

There is an annual contest to see whether new computer programs can pass the Turing Test. The best attempt wins $2,000. And if any program can actually pass the test, they win $100,000.

Next time I will go into other artificial intelligence topics such as a computer playing chess.

Artificial Intelligence

I went to the library and picked up a book on Artificial Intelligence. This book was written with the general reader in mind. It made no assumptions that you knew about AI, or that you were a technical person.

Some people in the AI field have made a lot of money in the commercial sector. If you really want to learn AI, you should first learn programming.

I have heard about the Turing Test before. You put a computer up against a human, and see whether a third observer can detect which one is the computer. However this book helped provide a lot more insight into the history and current attempts at winning the Turing Test.

More on this delicious book later.

User Interface Design

We had a new developer design a couple screens for changes in our application. He had a couple busy screens. Sure one of the screens was dictated by the customer. But the other one was a monster that he created himself.

When we did a review of the design, I pointed out that there were way too many buttons on the screen. The new guy explained the use of each of the buttons. I determined it was time to step back and figure out what our goals were.

The top goal should be to make the most common operations easy for our customer. After that, the screen should be intuitive enough that you don't have to read a manual to figure it out. The design for this one new screen was not achieving any of those goals. What happened to the good old Windows user interface design principles? It might be time to get back to basics on our project.

Bulding Robust Systems

There are many principles you can employ to design systems that don't break often. This will help you sleep better at night. That is because the system won't crash, and they won't have to call you for help. I should know about this. I just got a support call this evening. We must not be following the right principles at work.

One this you can do is to manage your events with a queue. There is standard technology to deal with queues. An example is Microsoft's MSMQ. You can even choose a queue in the cloud if you want to get fancy. Wait. Hold that thought. You do not want the support calls. So choose a mature and stable queuing technology.

Many business processes are batch oriented. Each stage requires the output from the prior stage. Our back end is a big UNIX system. You would think you could just pipes the processes along. That works in theory. This is a bad practice in reality. You should design a scheduling system that spawns the processes separately. The results from each stage should go to a file. The scheduler can wake up every so often, see if a stage has completed, then start up the next stage. We have our loading software follow this pattern. It is rock solid, even when things go awry.

A final tip is one that I have heard before. Every time you resolve some trouble ticket, you should turn that into an additional automated unit test. You already are investing the time to test your bug fixes. It is a marginal extra effort to automate that testing. This helps you grow your unit test code base and coverage. Sometimes prevention helps you avoid the pain that you would get otherwise.

Scrum and DSDM

A magazine article I read recently reviewed different agile software methodologies. I have previously written about Extreme Programming. Now I will go over Scrum, and a new one I am not familiar with (DSDM).

Scrum is a management technique. One of its goals is to stabilize requirements. That alone is a noble goal. I find our requirements lacking in general. However Scrum also advocates a daily stand up meeting. Those I have found degenerating into a waste of a whole lot of time.

DSDM stands for Dynamic Systems Development Method. Have you ever heard of it? Neither have I until now. It attempts to hold the resources and delivery date constant. The way to achieve that is to modify the scope of the deliverable. I like the sound of that. It comes from Britain. I don't think it is popular in the States.

I will have more later on things like Continuous Integration and Test Driven Development.

Agile Methodology

I got a really good overview about Agile Methods from a magazine I read this weekend. Surprisingly it was a magazine on testing. It seems the techniques have progreesed past plain development to the world of software test.

Let's start with the first, and what I consider the biggest. That's XP which stands for Extreme Programming. It sounds funny when applied to testing. XP was created by a guy working for Chrysler.

XP focuses on delivering small release quickly. Then you can circle back and add more functionality in later releases. That has the distinct advantage of getting something done fast. It also provides a tangible program for the user to try out. You can get some great feedback from such a responsive development cycle.

There are a number of techniques used in the XP world. These include Test Driven Development (TDD), Pair Programming, and Refactoring. Perhaps I will go into these techniques at a later time. In the mean time, I plan on explaining Scrum and a new method called DSDM. Later.

Programming Rules

I read an article on the web by Rob Pike. He is an important guy in the UNIX/C world. I know I own at least one UNIX text authored by him. For some reason, I thought he was also one of the authors of the awk scripting language. However that does not seem to make sense as the letters in awk are supposed to represent the first letter of the last names of the three guys who invented the language.

It seems I digress. The article I read was entitled “Notes on Programming in C”. The funny thing is that many of the topics discussed by Pike are not specific to C. They can be applied to most programming languages. That is kind of like a Code Complete by McConnell. Let’s start with some of the C specific items as they are few. One is that you should not include another file within an include file itself. In other words, you should not nest include files. Another tip was that pointers are preferable to objects. I think that means pass pointers to objects instead of making copies of the objects themselves.

Now let’s move on to some of the guidance that can be applied whatever programming language you are working with. The first is the short variable names are often better. For instance, it is reasonable to use the variable i for a loop index variable. Next you should strive to eliminate comments. This may sound contrary to what you were taught when you first started programming. However the best code is clean, simple, and easy to understand on its own. It does not need to be littered with comments. This eases maintainability. You can also trust the code always. Comments that are wrong or misleading are harmful.

Finally let’s talk about procedures and functions. Procedure should be named according to what they actually do. That sounds simple. But you would be surprised how some procedures are named which have nothing to do with their function. Next you know that a function returns a value. You should name the function based on the type of value it returns. Any functions returning a BOOL should be in the form of a question. Examples of this are isOpen() and canDelete().

More Object Oriented

Some time back I went back over a textbook I had from my Object Oriented Analysis and Design class. The book was authored by Grady Booch. The title of the book was Object-Oriented Analysis and Design with Applications. I have covered some ideas from this book in previous blog posts. This time I want to finish up some topics I read in the book.

A very popular term within the OO world is polymorphism. This means one name with many implementations. In other words, you have multiple related classes with the same function name. Then depending on the object upon which you are calling the method, you will get the right implementation executed.

There is another scenario where you have the same function name, but multiple implementations. This is where you have multiple functions within the same class that have the same name. However they are differentiated by the number and/or types of parameters that are passed in to the function. The official name for this behavior is overloading.

Another key idea in OO is that of aggregation. This is a big word to say that one object has another object or item as part of it. A synonym for this idea is containment. There are some lesser used OO topics that Booch mentions. One of them is that of a meta class, where the instances of the class are classes themselves. That does not sound familiar from my experience.

Some techniques for performing object oriented analysis and design are use cases and CRC cards. I have only hear about but never participated in CRC card analysis. Apparently you get together in a room and write down things on physical cards. I have done a lot of use case work in the past. However these days we skip that during out analysis phase. So do our requirements people.

Finally I read up on parametrized classes. These are classes whose behavior depends on parameters passed to the class. In C++, this idea is implemented as templates. I do have a little experience with templates in general. However I believe I want to beef up that experience.

Object Oriented

Some time ago I reread an Object Oriented Analysis and Design book by Grady Booch. It brought back a lot of memories from my first college class on OOA. So I thought I would talk about some more main topics from this book.

As far as programming languages go, the two ends of the spectrum are static binding and late binding. Most languages may one or the other. However a language may fall between the two extremes. Static binding is where variable types are fixed at compile time. It is also called early binding.

Dynamic binding is where variable types are not all known at compile type. This is also known as late binding. Having just completed an introductory class on Java, I now know that Java is a language with dynamic binding.

Why do object oriented modeling anyway? In theory, it encourages reuse of design. It also allows you to build upon components which are already tested and known good. Furthermore, some of the object oriented outlook feels nature to people. Evangelists say that Object Oriented Programming gives you great power. I am not so sure about that claim.

Let’s wrap up by defining some important terms in OOA. State is the properties of objects, along with the current value of those properties. A class defines a common structure and behavior for objects. And cardinality refers to the numeric relationship between classes. For example, a car has four wheels.

Next time I will go into big topics such as polymorphism and aggregation. Again this all seems very relevant as I just learn Java, which is an object oriented language.

Universal Object Oriented Topics

I am a veteran C++ programmer. This year I decided to seriously take of the challenge of learning to program in Java. Now I am starting to see that many object oriented topics are universal. They are language independent. Yes this might be obvious to some. But given my long history with C++, I always seemed to think of the principles in terms of how C++ implements them. Here I will discuss some of these universal topics that I recalled by reading a book by Grady Booch.

An abstraction denotes the essential characteristics of an object. Encapsulation divides structure and behavior. It separates interfaces and implementation. This is all done through information hiding. Modularity refers to decomposes complexity into separate products.

Abstractions are related in a hierarchical manner. One example of this is multiple inheritance. You can receive behavior from more than one source. Another example is aggregation. This is a fancy way of stating that something contains something else.

Typing is enforcing a class on an object. It restricts and defines what the object can and can not do. It prevents a programmer from exchanging objects that have different types. This is a safety feature. Most of the time, if you try to assign something of the wrong type to something else, you have a bug.

Like I mentioned earlier, I am learning Java programming. Unfortunately we are learning the basics of the programming language. So we have not covered some of the deeper topics like inheritance. However a good thing about this is that we are taking it from the very top. So we are covering basic things such as encapsulation and abstraction.

Object Oriented

I had reread a book by Grady Booch and recalled some topics about object oriented analysis and design that I had learned a while ago. And I thought I would share and discuss some of these ideas here. The first topic is that of complex systems.

Complex systems have a number of shared traits. They have a lot of subsystems. There is often an arbitrary choice of components in the system. There are dependencies between these components. The subsystems are combined in different ways. They often have evolved from a simple working prototype system.

There are a number of approaches that can be taken to design complex systems. There is a top down structured design. There is also a data driven design approach. And finally there is the object oriented design approach. When we use the word object, we are referring to a tangible entity that has a well defined behavior.

Object oriented analysis is an examination of the requirements in terms of classes and objects. Object oriented design has multiple facets. There is an object oriented decomposition of the problem. There is notational symbols for both the logical and physical design models. And there is also notation for both static and dynamic models.

Likewise, object oriented programming has multiple parts to it. Programs are made up of cooperating objects. The objects themselves are instances of classes which are the blueprints. Classes are arranged in a hierarchical structure. The classes in the structure are related by a term called inheritance.

There is a lot more to object orientation that what I discussed here. This is merely a review if you are already somewhat familiar with object oriented analysis and design. Normally I would point newcomers to the actual text of Grady Booch himself. However given enough time, I might be able to start a number of articles here that teaches this in more detail.