|
|
Software platforms come and go, software development is forever
-
In the past eight years at Info Support, I've said goodbye lots of times, to lots of different customers. Some of my work consisted of real consultancy: visiting a customer for a day or two, to advise them on dealing with a specific problem. Other times I was more of a temp worker, being assigned full-time to a single project for several months or even years. Sometimes, my contract ended because the project was finished, the problem solved. Other times, I had to ask my manager to gently "pry me loose" from a customer, because I felt that it was time for me to move on -- that's what being a consultant means, after all. But always, there came the time to say goodbye.
Friday, December 22th was a particularly special goodbye for me, because it was not only my last day on that project, but also my last day at Info Support.
Yes, I've decided to move on to another employer. Not for a bigger salary, or because there was anything in particular which I didn't like about Info Support. However, after eight years in the enterprise software field, I've seen enough administrative software for a while. I will always be a hacker at heart, and in my new job I hope to find some new challenges to satisfy my love for hard-core technical problem solving.
Notwithstanding my decision, I've had a great time, during which I've been privileged to work on very interesting projects with some extremely smart and competent people. Fortunately I expect to stay friends with many of them, and to meet them again in the future. Nonetheless, for now, to all of my former colleagues:
Thanks, and goodbye!
(I've set up a new personal blog at http://www.mwolf.net. Like this one, it will probably be rather low-volume, with new posts appearing only when I feel that I have something genuinely interesting to share. Feel free to visit, or add me to your RSS reader!)
|
-
It doesn't matter how sincere it is, nor how heartfelt the spirit. Sentiment will not endear it; what's important is.. The price!
-- A Christmas Carol, by Tom Lehrer.
The holiday season is coming up again, and that means.. Gift giving! And with that comes, of course, drawing lots in order to assign gift recipients to gift buyers.
In my family we solved that problem years ago, with a little C# program which randomly assigns people to each other, making sure of course that nobody gets assigned to themselves, and which displays the results through a simple GUI in such a way that nobody gets to know anything other than the name of the recipient assigned to them. The algorithm is rather brute-force: For every buyer, randomly choose a recipient; if the buyer-recipient combination is valid, assign them to each other, otherwise choose again. "Valid" is defined as: the buyer must not be the same as the recipient, and the recipient must not already be assigned to another buyer. Simple and effective.
I am quite sure I can prove that this algorithm is fair, meaning that every allowed combination is equally likely. In theory, though, there's a small problem with it, which is that it might run for years before finishing. In practice, however, the algorithm is efficient even for large groups. Assuming a perfectly fair random-number generator, in a group of n people the first iteration of the "for every buyer" loop will find a valid recipient in (n/n-1) attempts on average, the next iteration will find a valid recipient in (n/n-2) attempts on average, and so on. So the average total running time of the program will be O(n*n), which is good enough for our purpose. The program's running time could easily be made deterministic, of course, by looking only in the pool of valid recipients to begin with.
My friend Dirk-Jan Binnema is currently wrestling with the same problem, but he chose a different approach: first shuffle the group of people into a random order, then let each person buy a gift for the next person in the sequence (treating the sequence as cyclical). This is certainly a more elegant algorithm than mine (whether or not it is easier to implement depends somewhat on whether your programming environment offers an "array shuffle" function, or a fast way to hack one up -- see his post for a nice one-liner in Ruby).
In addition to the obvious requirement of not assigning people to themselves, Dirk-Jan adds a second requirement of not creating pairs of people assigned to each other. He then proves that his algorithm satisfies both requirements.
I would argue, however, that the algorithm does not satisfy another important requirement: fairness. By fairness, I mean that every allowed combination of assignments should be equally likely. The "shuffle and sequence" algorithm does not satisfy this requirement. For example, in a group of six people, the outcome [1-2, 2-3, 3-1, 4-5, 5-6, 6-4] is not possible. In fact, the only possible outcome of this algorithm is a single unidirectional cycle.
Therefore, I think I'll stick to my nested-loop implementation for now. Besides, I lost the source code.
|
-
(Yeah, I'm a bit late -- the contest was over two weeks ago and I'm just now posting about it..)
Most of our customers know Info Support as a company that specializes in administrative applications, mostly web-based. Little do they know that when the day's work is done, some of us switch to something rather different -- such as building and programming fully autonomous robots!
The StarTel RoboChallenge is an annual contest held in Groningen, The Netherlands. The aim is for students, companies and individuals to build robots that compete against each other for fame and fortune. Unlike in such pathetic spectacles as Robot Wars, in which the devices are remote controlled by human operators, these robots need to be truly autonomous: once the referee starts the game, you push the "start" button and after that, all you can do is watch and pray..
A brief summary of the rules of the game: the robots are placed in an arena of 5 x 5 meters. In this arena, plastic balls in various colours hang suspended from the ceiling at heights ranging from 10 to 60 cm above the ground. The contest is divided into three different "missions", each with its own rules about which balls to collect. The first mission is a qualification round, in which the robot's objective is to collect at least 3 out of 8 yellow balls, while avoiding the green ones. In the second mission, two robots are placed in the arena at the same time, but each has its own colour of balls to collect. In the third and final mission, both robots compete for the same balls, with points being awarded based on their colour. The winner of the third mission is the winner of the competition, with points scored in the first two missions being used as tie-breakers.
Here's our robot, called SeeSharp, after the programming language in which it was written and after the (intended) quality of our image recognition algorithms.
Almost all of the hardware work was done by Willem Jan, our excessively capable head system administrator, but yours truly also got to briefly handle a soldering iron in the course of the proceedings (and you know what they say about trusting programmers with soldering irons). Some notable components are, from top to bottom: Firewire camera from theimagingsource.com, robotic arm from Lynxmotion, servo controller board, Car-PC mini-ITX board running WinXP, another servo controller board, two heavy lead batteries and four wheels, of which two are powered. All of this is arranged on a number of plywood planks in a "Tower of Pizza" configuration.
Here's another pic, in which our little guy (this time wearing its sponsorship clothes) is competing against Jack the Gripper.
The software was written in C# for the .NET 2.0 platform (I voted for Java of course, but I was outvoted by the rest of the team, which may be a good thing in hindsight because I'm not sure that we would have gotten the proprietary camera drivers working just as easily). At the core of the system is our own port of the CMVision library for classifying colour areas. Based on the size of such an area, a coarse estimation is done of the ball's position in 3D space, relative to the robot's position, which is then refined continuously as the robot moves towards the ball. The robot arm also has its own laser-based distance sensor for helping to grab the ball once it's close enough. Most of the software was written by my colleagues Mark and Marco and myself, with Mark doing the lion's share of the work.
In their current form, our ball detection and movement algorithms are rather sensitive to the exact positioning of the camera, the ambient light conditions, the battery charge levels, and so on. As a result, whenever any of these variables had changed, we needed to spend some time calibrating everything again. This made the actual contest very exciting for us, as we never knew for certain how well our creation was going to perform this time.
So, how did we do? Quite well actually, or at least so we like to believe. In the qualification mission, little SeeSharp (or "ducky" as we sometimes affectionately called him, after the duct tape used for various last-minute repairs) attained a shared second place by collecting four yellow balls, with no green balls and no fumbles. The fourth ball was succesfully dropped off in the last second of our allotted time, with the entire audience holding their breath.. Seventeen teams appeared at the start, out of which nine made it through the qualification, so we did very well there.
In the second mission we were considerably less sucessful, unfortunately -- the poor little thing got confused about which colour of ball it was supposed to collect, and was driving around rather sadly (while our opponents did only marginally better, by the way -- this was definitely the most complex part of the contest in terms of the high-level logic involved).
In the third and final mission, we actually did pretty well again in terms of the number of points we scored: 40 points, same as in the qualification, and I believe that would have gotten us another shared second place if scoring were based on points. Unfortunately, it was a knockout race, and we had the misfortune to be placed against Jack the Gripper in the very first round. Jack the Gripper, a very professionally-designed robot, consisted of some 15000 euros of hardware and several man-years of programming work. Our little boy was good, but not quite that good, and so we were out of the race after the first round (Ole Jack developed some hardware trouble later on, otherwise he would almost certainly have won the contest; instead he placed second, after having won against the LogicaCMG robot despite not actually moving at all).
But, most importantly of course, we had lots and lots of fun. The intellectual challenges involved in building something very different from our usual jobs, the camaderie, the endless tweaking and tuning, the last-minute disasters ("why is our motherboard suddenly rebooting spontaneously?"), watching the other teams' robots do their thing, the "geek chic" feeling of the whole event..
Even the weekly run-ins with the security guard were fun, in their own way. I don't think there ever was a thursday evening or saturday afternoon that we did not accidentally set off the alarm. "Hi, the alarm went off, everything OK?" "Yeah sure, we're just building a robot over here." "Huh? Oh well, can I have your name?" "Sure, it's Martin Wolf." "Can you spell your last name?" "W-O-L-F. Whiskey Oscar Lima Foxtrot" "Eh, what was that first part again?" "WHIS-KEY! Whiskey Hotel India Sierra ..."
I'll definitely be there again next year, and so will all of the other team members, plus quite a few other colleagues who watched jealously from the sidelines this time. And next year, we're going to win!
To the best of my knowledge, this is just a funny coincidence..
|
-
The concept of coroutines, typically attributed to Donald Knuth, has existed for decades so why do so few mainstream programming languages properly implement it?
Since the concept is not as well-known as it should be, let me start by refreshing your memory of what a coroutine is. Basically, it's a piece of code which has multiple entry/exit points, as opposed to a subroutine which can have multiple exit points but never has more than one entry point. The local state of a subroutine is lost when it exits; a coroutine keeps its state and will continue where it left off when you call it a second time. Another way to describe it is that with subroutines, the called code needs to finish completely before returning to the caller, whereas with coroutines you have two pieces of code running at the same level of abstraction, passing control back and forth between them.
For a simple example, take a look at the following code:
public static IEnumerable Squares(int count)
{
for (int i = 0; i < count; ++i)
{
yield return i * i;
}
}
This is an example of how a collection-like object can be written in C# 2.0. Whenever the 'yield return' statement is encountered, the next value from the for loop will be returned to the calling code, which might look like this:
foreach (int y in Squares(20))
{
Console.Write("{0} ", y);
}
Unfortunately, the C# designers did not go all the way in implementing real coroutines. Instead, the 'yield' keyword only works for the specific case of a method which returns IEnumerable.
So, why do I want them, besides the fact that it's just generally a cool concept? Here's why. In our current application, written in Java 5, we need to make a deep copy of a rather complex data structure. Because of various issues related to object identity rules, the precise semantics for this operation are rather hairy. Fortunately, we have solved all those issues already, in our XML import/export code. So, the obvious solution would be to connect the output stream of the XML exporter to the input stream of the XML importer, right? There's a bit of a performance hit, of course, but we were quite willing to accept that.
But that turns out to be a lot more difficult than it would seem at first. What you need is a PipedInputStream/PipedOutputStream pair, which seems like it should do what you want, except that as soon as you run the code you get a deadlock: the import code is sitting at an empty buffer waiting for the next batch of data, which will never arrive because the export code, which it is waiting for, will never run. So you need to run either the export code or the import code on a separate thread, which leads to all kinds of ugly hacks regarding exception handling and properly closing all streams after you're done with them. Ugh. It works by now, but it's not exactly the piece of code we're most proud of.
The problem with threads, in this case, is that they are too powerful. Once you have multiple threads running, they can interrupt each other at unpredictable moments, so you need to manually synchronise things, beware of deadlocks, etc. Also, because they are so generic and powerful, starting/stopping and switching between threads are relatively expensive operations. In our case, we know exactly when we want to do the switch: the import code should run as long as there's data available in the buffer, and then it should yield to the export code which should run until the buffer is full, at which point it should yield back to the importer again. In other words, a textbook case for coroutines. Only we don't have them in Java.
Well.. Not really, at least. Some impressive (in the "oh my God I can't believe you did that" sense) attempts have been made to fake it anyway. For example, the Xalan implementation contains a Coroutine manager which implements logical coroutines on top of physical threads. That way you don't have the efficiency advantages of coroutines over threads, but you do retain most of the elegant programming model. But a proper implementation really should be implemented inside the VM and operate below the abstraction level of threads, not above it.
Many platforms do offer a feature that looks very much like coroutines: co-operative threads, a.k.a. fibers. Those are logical threads where the code being executed has to explicitly yield (hey!) control to the next thread, typically by calling a system function called "yield" (hey!!). When the fiber implementation you are using is deterministic enough, you could build a coroutine implementation on top of it, and in fact somebody did just that by combining the Win32 Fiber API with the .NET framework. Note the editor's warning at the top of the article, though: this is not the kind of thing you want to stick into your production code. And his code also does not implement generic coroutines, but only the special case of generator-based collections -- only he did it in .NET 1.1, which I have to admit is a pretty cool hack.
Oh well, it looks like I'm going to need to solve my problems the ugly way for now. If you want true coroutines, you'll need to look into some of the less mainstream languages. Python has had a generator-style iterator mechanism for a while now, pretty much identical to the C# example given above, and Python 1.5 (out in alpha release as I write this) has "bidirectional" generators which come very, very close to being true generic coroutines. Ruby also claims to support coroutines, but as far as I can tell, it only does generators, too, and not the full general case. Most Lisp dialects have the real thing, though, as do some functional languages. Hmm, maybe there's something to Paul Graham's Blub Paradox rant after all?
|
-
Every now and then, a story comes along which reminds me why I love the Linux/open-source world so much. Today's gem:
There's a new proof-of-concept virus out (wel, "out" is not really the right word -- unless you're a pro virus researcher you'll probably never see it), which is able to infect both Linux and Windows machines. See here, for example, but it has been pretty widely reported.
Only, if you are running the latest kernel, 2.6.16, the virus won't be able to propagate itself on your machine. Is that because the virus was exploiting a security bug which has been fixed in the latest kernel? No, it turns out to be a bug in the kernel which incorrectly prevents the virus from working. Linus Torvalds personally created a patch for the problem, so in the next version you too can infect yourself with Virus.Linux.Bi.a!
I love this world.
(By the way, in case you were worried: like most modern "viruses", this is actually more of a trojan horse in that the user needs to be tricked into manually running the executable in order to get infected. It is not a worm which can spread itself without help from the user. Obviously, if that was possible, it would indicate a bug in Linux wich would need to be fixed).
|
-
Well, Wouter, if weird comic strips for Linux users are your thing, then check this out..
|
-
The Free Software Foundation has just posted the first draft of their proposal for a version 3 of the GNU General Public License, the most popular Open Source license and the one that started the "copyleft" movement (where software is distributed freely, under the condition that all derived versions of the software must remain free as well). That's pretty big news; the last update to version 2 was in 1991.
At first sight, the new version still looks pretty much like the old one. The "viral" aspect of the license seems to have been made a little more explicit, and there's a paragraph titled "Liberty or Death" which seems a bit out of place with the faux-legalistic tone of the rest of the document -- I wonder if that will survive into the final version.
Other than that, the big changes appear to be about patents and DRM, as was to be expected. The patent-related clauses do not appear to go as far as some would wish, but the license now explicitly gives you the right to threaten "patent retaliation" against those who would threaten to use their patents against you. I assume that this makes the GPL3 compatible with the Apache Software License? (As explained here, the ASL has a patent retaliation clause which makes it more restrictive than, and therefore incompatible with, GPL2).
As for DRM (Digital Rights Management, sometimes referred to as Digital Restrictions Management), the license does not forbid GPL'd software to implement DRM altogether, but it does state that "No covered work constitutes part of an effective technological protection measure: that is to say, distribution of a covered work as part of a system to generate or access certain data constitutes general permission at least for development, distribution and use, under this License, of other software capable of accessing the same data." Nice one!
One thing which is significantly missing, is a clause about using GPL'd software to offer functionality on a public server. Should the users of that server be able to demand the source code of the software they are using? On the one hand, this would place a large burden on the owners of such a server, and make a lot of people shy away from the use of Free Software. On the other hand, with the rise of web services and other means of making software available without actually distributing it, this could be seen as a way to circumvent the GPL.
For example, see Joel Spolsky's new product, Copilot, which is offered as a commercial service and is based on a heavily modified version of VNC. The client software is distributed to the users and is available with source code, but the server software is never distributed and therefore Fog Creek is able to keep the source code proprietary, even though it is based on a product which is licensed under the GPL. It's all legal and proper, but one wonders if this is what the original VNC developers had in mind?
This is one of the things that were specifically mentioned as something which v3 of the GPL would address. Nontheless, this draft version is silent about it, and the Rationale document explains why. "Given the variety of needs and concerns in this area, in which different parties have disparate and strongly-held positions, we have chosen not to add requirements about public use of modified versions in the GPL itself. Instead we have made a variety of possible license requirements compatible with the GPL, through an enhanced compatibility provision; thus we leave individual developers scope for choosing among requirements to apply for public use of their code. We have intentionally done nothing that might threaten to divide free software developers from free software users."
I think this was the right decision. No matter what choice the FSF might have made, it would have been the wrong choice according to roughly 50% of the people. The expanded compatibility provisions also make it easier to make a GPL'd program or library co-operate with, for example, an Apache-licensed program.
All in all, it looks like this new version was worth the wait! Updated and modernized to reflect new concerns that have come up in the past fourteen years, but without losing the essence of what made the GPL succesful, or trying to micro-manage things that are better left to sort themselves out in practice. I'm looking forward to the final version!
|
-
-
It's a small step, but a step in the right direction: European Commissioner for Competition, former member of the Dutch parliament Neelie Kroes, has apparently ordered the members of an influential standards body, ETSI, to make sure that its standards do not fall victim to the threat of "patent ambush". I'm still looking for more details on this; the ETSI website does not have anything yet, so we'll need to see how far this goes.
"Patent ambush" is when a company cooperates with the development of an industry standard, or simply stands by while others are developing the standard, without divulging that it holds patents covering the standard. Then, after the standard has been accepted and many different parties have become firmly dependent on it: Ta-daah! It's paytime!
Probably the most famous example of this is the Unisys GIF patent, in which Unisys stood by for seven years while the GIF image format became the de-facto standard for image exchange on the Web, and then once it had become essentially impossible to switch to another format, they announced that they held a patent on the compression algorithm, so everybody please either pay up or remove GIF support from you graphics application (thus making it unsellable).
Patent ambush is hardly the only common abuse of software patents. Other well-known tricks are:
- Patenting the problem rather than the solution. For example, claiming a patent on the generic concept of selling music over the Internet, rather than patenting a specific innovative technical solution to that problem. Except that there is no technical problem with selling music over the Internet. Which is why it should not be patentable. Likewise, if you've invented a new kind of Dutch-language grammar checker, that's great, but it should not give you the right to sue any grammar checker produced afterwards just because it works somewhat similarly.
- Patenting existing technology. This one is even more blatant. Like the various attempts to patent, basically, the Internet, during the late 1990's.
- Patenting things that are obvious to anybody working in the field. The classic example of this is the guy who, during the first publicity about the "Year 2000 problem", patented the idea of "windowing". For example, if you have a customer database which uses two-digit fields for storing customers' birth dates, and for technical reasons you can't easily increase the field size, you can declare that the numbers 20-99 map to 1920 - 1999, and numbers 00-19 map to 2000-2019. That way, you have solved the Y2K issue, and by the time people born in 2020 start becoming customers, you have probably replaced the software anyway. The problem with this patent is that if you put a couple of average programmers in a room and ask them to come up with a solution to this problem, they are going to come up with the windowing idea within ten minutes, max. Patents should be awarded to cover the investment needed to invent something, not to reward someone's clever idea in the shower.
- Using patents to fight interoperability. Selling value-adding add-ons for other people's products is a time-honoured practice. I can get hands-free kits for my Nokia phone from people other than Nokia, and I can get LED-based replacement heads for Maglite flash-lights from people other than Maglite. This is not unfair competition: Nokia is quite free to produce its own hands-free kit and compete on the open market, and those third-party flashlight heads would not do any business if Maglite would finally enter the 21st century and start selling the bloody things themselves. With software, it should be the same: A given word processor or photo-editing application should succeed or fail on its own merits, not because its file format happens to be the de-facto standard and no other software can handle it. Yet an increasingly popular practice is to patent your file format (even if it uses no particularly inventive techniques) and then use the law, rather than technical superiority, to lock out the competition.
|
-
Versant, producers of one of the larger commercial JDO implementations, recently made an interesting announcement on their site. A while ago, they open-sourced their JDO implementation (Versant Open Access) and offered to take the project lead role for the Eclipse JSR220-ORM project, which aims to integrate Object-Relational Mapping into the Eclipse platform. Originally, the aim was to support both the upcoming JDO2 standard and the upcoming EJB3 standard. Recently however, they essentially abandoned most of their ambitions for JDO2, saying: "Versant is very disappointed to have taken this approach, but the whole point for Versant of supporting JDO to begin with was to have an industry standard interface. It is extremely unfortunate and comes at great cost to Versant that JDO will not be that standard interface. Yes, JDO is a standard, but it will not be widely used and therefore would serve no long term benefit to Versant, it's long term stability and in turn Versant's customer base." In other words, this once-prominent JDO vendor is saying that EJB3 and POJO persistence are the way to go, and that JDO is losing ground already and is expected to lose more of it as time goes on. Of course, one vendor's opinion does not determine the market. For example, SolarMetric, recently aquired by BEA, seems to be still going strong. It's an interesting development however. Now that EJB3 is moving in the direction of the more lightweight POJO persistence technique popularized by Hibernate, while at the same time Hibernate is basically becoming an EJB3 implementation (or vice versa, depending on who you ask), there's a lot more overlap between the three major ORM standards than there used to be. Is it time for a showdown in which the winner takes all?
|
-
Yesterday, I attended the Holland Open conference in Amsterdam. Unfortunately, I could only attend the first day of the three-day conference. Nonetheless, a very interesting day!
The highlight, for me, was the presentation of Eclipse WTP, the Web Tools Platform, by Naci Dai, lead dev of the J2EE Standard Tools subproject. Currently, Eclipse itself is already an extremely powerful and mature IDE for building generic Java applications. However, the commercial development platforms still have an edge when it comes to such typical "Enterprise" subjects as Web services and J2EE applications.
Well, with WTP, it looks as if that is going to change. The project scope is ambitious indeed: according to Mr. Dai, they basically intend to become the standard toolset for developing Web applications, not just the basis for commercial development platforms such as IBM Websphere and BEA WebLogic, but good enough that there won't be a lot of missing functionality left to add on top of it. The words "world domination" were uttered. Twice.
Of course, those commercial IDE's tend to be based on Eclipse today anyway, so they don't seem to mind too much. In fact, the demo consisted largely of an enhanced version of IBM's Web Service explorer and test tool, which we know from Websphere and which IBM has donated to the WTP project.
The core WTP tools are going into feature freeze right around now, and should see their 1.0 release together with Eclipse 3.1. Personally, I can hardly wait!
Other interesting presentations involved MMBase, the Dutch Content Management System, which had quite a presence at the conference. MMBase was originally developed for the VPRO (one of our public TV broadcasters), and today is an example not only of a succesful open-source application but of a succesful open-source business model as well, as there are quite a few companies making money with it.
The formal part of the day ended with a "debate" session on innovation and open-source software, which was quite interesting even though there wasn't a lot of debating going on as the panel members mostly seemed to agree with each other.
|
-
There's a small number of blogs which I read religiously, and Joel Spolsky's Joel on Software is right at the top of that list. I certainly don't always agree with what he writes, but even when I don't he always makes me think, and I like being made to think. His latest article, containing a spirited defense of Hungarian notation and an attack on the use of exceptions for error handling, certainly falls in the "makes me think" category.
Some of my personal favorites among his previous articles:
The Joel Test -- CMMi-3 it ain't, but for a lot of software development teams in smaller organizations, following these twelve simple rules would be a good first step towards a more structured and more effective development process. Or at least the first ten -- I have my doubts about the last two, actually, but as I said: the point is to make you think, not to blindly follow the rules.
Big Macs versus The Naked Chef -- procedures are good, but they can never be a substitute for personal competence.
The law of Leaky Abstractions.
The top 5 (wrong) reasons why you don't have testers.
Painless software schedules -- please skip this one if you are responsible for a 60-people team building an operating system, but if your project scheduling methodology currently consists of "make a wild guess, and find out three months later that it was wrong", you could do worse than give the simple method described in this article a swing.
In fact, why don't you just go to the complete archive and start at the top.
|
-
When you are first introduced to Generics in Java 5, it seems pretty simple (especially if you already know C++ templates) and you wonder how the language ever made it through four previous versions without having this wonderful feature. Then you encounter the mysterious "? extends" syntax, and suddenly things don't seem too simple anymore. After a while, you understand the concept, and then it becomes simple again.
I'm pretty sure I have reached the third stage by now, so I wrote a little article about it. It's not the first one, probably not even the best one, but this one is mine.
|
-
|
Info Support is a heavily Microsoft-oriented company, with Java in a strong second place and still gaining momentum. Most people choose one of those tracks and specialize in it; we're a company with a strong focus on technology expertise, and I daresay we have a few of the country's best Microsoft and Java specialists on our payroll.
In this environment, I am a bit of a maverick. I started out as a C++ developer on Windows, in the NT4 era. This was followed by a period in which I alternated between .NET and LAMP (Linux/Apache/MySQL/PHP) development, and since then I have moved to Java for a while. It is no secret among my colleagues that Linux is my primary love interest, but give me an interesting problem to solve and I will happily take up whatever platform you want me to.
While this versatility makes it difficult for me to really focus my energies into a single specialism, I find that experiency gained in one area often proves useful elsewhere in unexpected ways. When working on a Windows C++ project, I use Perl and other Unix-heritage tools to automate the development process; when building a PHP app, I take inspiration from the .NET and Java platforms to design a structured application framework. I think every developer, of any specialism, should take a little tourist trip into one of the other platforms every now and then, just to make sure that "the way we do it" does not become "the only way to do it". Variety is the spice of life!
In this blog, expect posts from me about Java, Linux, open-source software and whatever else takes my fancy. I can get seriously nerdy at times, so expect me to dive deep into the bits & bytes every now and then, but I might also pontificate about software architecture, development practices, the pros and cons of different open-source licenses (OK, I guess that still qualifies as "seriously nerdy") or The Meaning of Life. When I do, you'll find out here!
|
|
|
|