Saturday, May 3, 2008
Blog has moved to softwareramblings.com
Tuesday, April 29, 2008
Thread Affinity on OS X
SetThreadAffinityMask() on Windows and sched_setaffinity() on Linux. However, I was very surprised to find that it does not appear to be possible to do this on OS X! Tuesday, April 22, 2008
Coding The Architecture
Friday, April 18, 2008
ToDo Lists
After trying 20+ different applications over the past 10 or so years, I constantly return to Abstract Spoon's ToDoList application. This is without doubt one of the most flexible ToDo list managers out there and it acquires new features at a fast pace. This application really defines the meaning of feature rich. I have used it successfully for managing simple lists, project scheduling, time tracking, and SCRUM backlogs, burndown charts and even for online SCRUM boards. It is difficult to describe its feature list in a simple blog post so I encourage you to download it and give it a twirl.
Tuesday, April 8, 2008
Visual C++ 2008 Feature Pack Released
Saturday, April 5, 2008
C++ Lambda Functions
vector v(10);
generate(v.begin(), v.end(), rand);
for_each(v.begin(), v.end(),
[](int& x){ cout << x << " ";});
OK, so the syntax looks a bit strange at first, but it does add a powerful construct to the language.
Lambdas have only just been added to the C++0x standard and support for lambdas are not included in the beta version of the Visual Studio 2008 TR1 feature pack.
For more details and examples of lambda functions, check out Herb Sutter's recent trip report from the February/March ISO C++ standards meeting.
Wednesday, March 19, 2008
C++ TR1: stdint.h still missing from Visual Studio
Since the C++ standard was finalized in 1998, it missed this standard header by a year. In the latest update to the C++ standard (namely those extensions covered in TR1), support for this header has been added in the form of the cstdint header.
It is astonishing to find that a header that was standardized 9 years ago has still not made its way into Visual Studio 2008. Not even the recent feature pack beta which included support for most of the TR1 extensions, contained stdint.h! The lack of support for this header was logged as a bug with Microsoft way back in 2005 but is still in the "postponed" bucket.
Thankfully, there are a number of implementations of stdint.h available, the most notable being Paul Hsieh's cross-platform free implementation and also a Microsoft compiler specific implementation. Simply place one of these implementations into the Visual Studio standard include paths and stdint.h support magically appears ... now why can't Microsoft do something like that!
Saturday, March 15, 2008
C++ TR1: array VS 2008 Bug
The TR1 array container template provides functionality for implementing a fixed size array. This is a halfway point between plain old C style arrays and C++ STL vectors. The defining property of the array container is that its size is fixed. Consider and example of an array of 4 integers:
array = { 0, 1, 2, 3 }; Since it adheres to the STL container rules, it must implement methods such as size(), and max_size(). For the array container, both of these should return the size of the array, which is fixed. In the above example, both should return 4. However, when using the VS 2008 TR1 implementation of array, a bug appears. The code:Produces the output:#include <iostream>
#include <array>
using namespace std;
using namespace std::tr1;
int main()
{
array<int, 4> arr = {1, 2, 3, 4};
cout << "size: " << arr.size() << endl;
cout << "max_size: " << arr.max_size()
<< endl;
return 0;
}
instead of:size: 4
max_size: 1073741823
If we take a look at the implementation of max_size() we can see the problemsize: 4
max_size: 4
Instead of simply retuning N (the size of the array), it performs the same computation as if this was a vector.size_type max_size() const
{ // return maximum possible length of sequence
size_type _Count = (size_type)(-1) / sizeof(_Ty);
return (0 < _Count ? _Count : 1);
}
This issue has been logged as a bug with Microsoft and will hopefully be fixed before the "Gold" release of the feature pack.
C++ TR1
TR1 ("Technical Report 1") is a specification for new functionality being added to C++'s standard library. This functionality takes the form of new class and function templates for things like hash tables, reference-counting smart pointers, regular expressions, and more. TR1 itself is just a document.
The TR1 draft does not contain any background information on the functionality it provides and doesn't contain any examples for how it should be used. For this sort of information refer to the proposal documents which were used to define the TR1 functionality. The relevant proposal documents are nicely catalogued by Scott Myers.
Microsoft have recently released a Beta version of the Visual Studio 2008 Feature Pack which includes support for most of the C++ standard library extensions described in TR1.
GCC v4.x also provides support for most of the extensions.
Over the next few weeks (more likely months) I plan on playing with the new TR1 features and I will add thoughts, learnings and code snippets to this blog.
Friday, February 22, 2008
Effective Concurrency ... so far
The Pillars of Concurrency
How Much Scalability Do You Have or Need?
Use Critical Sections (Preferably Locks) to Eliminate Races
Apply Critical Sections Consistently Avoid Calling Unknown Code While Inside a Critical Section
Use Lock Hierarchies to Avoid Deadlock
Break Amdahl's Law!
Going Superlinear
These are an excellent set of articles on the subject of concurrency and programming for multi-core that analyzes the many facets of the subject - from background theory, to locking and on to achieving scalability and performance.
Saturday, February 16, 2008
Hiring Good Programmers
The company that I work for is currently embarking on a hiring spree. So I thought it would be a good idea to refresh my interviewing skills before I launch myself into the hiring process.
A recent Coding Horror entry highlights "The Years of experience myth" which is the inadequacy of trying to "match-- exactly and to the letter-- some highly specific laundry list of skills". Unfortunately when dealing with some recruitment agencies, I find this an all too common practice. Instead it is vital to remember that "... what software developers do best is learn. Employers should be loooking for passionate, driven, flexible self-educators who have a proven ability to code in whatever language -- and serving them up interesting projects they can engage with."
Joel Spolsky sums up the characteristics that employers should be looking for in future employees as "Smart and Gets Things Done".
So, now that we've figured out what to look for in a candidate, lets look at some resources that give tips for screening CVs, conducting phone screens or face to face interviews.
- The Guerilla Guide To Interviewing - Joel Spolsky gives practical and pragmatic advice on the whole process.
- Getting the Interview Phone Screen Right - because its very expensive to get it wrong.
- The Five Essential Phone-Screen Questions
And finally since the phone screen is probably the most important stage, it's worth highlighting the two common critical mistakes that an interviewer could make in the phone screen:
- Don't let the candidate drive the interview. The interviewer should do most of the talking, guiding the conversation along until they're satisfied the candidate knows the answers to the questions (or has given up).
- Watch out for one-trick ponies. Candidates who only know one particular language or programming environment, and protest complete ignorance of everything else, are a giant red warning flag.
Friday, January 4, 2008
» 10 techniques for gathering requirements | 10 Things | TechRepublic.com
» 10 techniques for gathering requirements 10 Things TechRepublic.com
When doing interviews of JAD sessions for the purposes of gathering requirements, try to ensure that you are in the same meeting room as the participants. This helps to build up a raport with the participants which generally leads to a more open dicussion which helps to produce better requirements.
Don't forget the 5 whys approach when gathering requirements. Often what a customer says he wants is different to what he needs. Dig into each requirement to fully understand why this is valuable to the customer and then ensure that the requirement is aimed at solving the root cause of the customers problem.
Saturday, December 29, 2007
Is Java becoming the new Cobol?
However, Java like Cobol has built a lot of infrastructure in enterprise environments and I'm sure that this will give Java some stickiness for considerable time yet.
Reading that article makes me wonder if it will become harder and harder for new languages and computing paradigms to emerge as time goes on? Does each new language or platform need to build a weight of infrastructural components in order for it to be a successful contender for the throne? I hope not and hopefully Ruby is the latest example of a language that works and is popularised simply because developers love it!
Friday, December 7, 2007
5 Generic Debugging Tips
- Think: If you can quickly build and test your application there is often the temptation to keep trying things until the bug goes away. It is easy to get caught up in a cycle of "make a change - build - test (fail) - make another change ..." without really stopping to catch your breath. The danger with this approach is that when the bug goes away it is sometimes difficult to tell if the bug is fixed or if you have just solved a symptom. Although frustrating, it is sometimes a learning experience to have to debug an application or system that takes a long time to rebuild and test. This forces you to take a step back and to think carefully about what you can glean from your current data and what the next step should be. This will help you to better understand the nature of the problem and in doing so it will help to find the root cause more quickly.
- Baby Steps: This is a really obvious but often overlooked practice. When debugging always take baby steps and only change one thing between tests. It is often very tempting to make a couple of changes or to skip a step, but this invariably results in an inconclusive test result and you will end up backtracking to figure out which change caused a change in behavior.
- Simplify: Try and reproduce a suspect piece of code in a stand-alone environment. For example if a particular algorithm is miss-behaving, try and replicate this behavior in a simple application that only contains the algorithm and may be easier to control and debug. Similarly, if debugging issues in a kernel, it is often possible to replicate the code at a user level which is a much more friendly debug environment.
- Tools: Become intimately familiar with your tool chain. Take time to learn the power and quirks of your unit test environment, debugger, memory leak checker, compiler, etc. If you develop on multiple platforms and use different tool chains on those platforms then learn them all!
- Challenge Assumptions: Assumptions can be dangerous. How many times have you assumed that a particular piece of code is working only to find you many hours later that it contained the bug that was the root cause of the issue you were debugging or that it behaved subtly different than what you expected? In general it is good practice to assume nothing and to challenge all assumptions that you find yourself making.
Sunday, August 19, 2007
Splitting large Scrum teams
Over time our team size has increased from about 4-5 to a whopping 15. We still practice SCRUM but I don't get as much out of it as I did when we had a smaller team size. Apart from the fact that it's difficult to get a space for our stand up meetings that can accomodate the entire team and still be able to hear everybody, I find it hard to keep tuned in to what everybody is saying. There is some pressure to stick to a single SCRUM for the entire team and not split into sub-teams. The rationale is to keep the daily stand up meeting as a communication channel between the entire team. So there are two problems:
- How to improve the communication within the single large team to make it more effective
- How to keep good communication across sub-teams and multiple SCRUM groups
Here is what I found from researching the problem:
How to improve the communication within a large SCRUM team?
- Hyperproductivity In Large Projects Though Distributed Scrum - relates to SCRUMs between distributed team members but the team size was 59!!!!
- Hmmm, there seems to be a lack of advice here! The only advice that I could find was to split the team into smaller sub-teams - the "scrum of scrums"!
How to keep good communication across sub-teams and multiple SCRUM groups?
- Historical data that suggests keeping the SCRUM team size under under 7
- The Magical Number Seven, Plus or Minus Two: Some Limits on Our Capacity for Processing Information
- Inefficiencies and large teams - "Two common pitfalls for crowded teams: miscommunication and lack of motivation"
- How to organize work and structure a project with multiple teams: Let small teams focus on solutions to specific problems and coordinate activity between teams.
- Scrum of Scrums
I guess the tactical approach to convincing the team to move towards smaller sub-teams and multiple SCRUMs is to point out that the larger team size is reducing the effectiveness of communication within the team. However, this must quickly be followed up with evidence that co-ordination and interaction between the smaller teams can address the communication gap caused by the split. To this end, I think I like the idea of the scrum of scrums approach where there are multiple scrum teams, and one member of each team attends a SCRUM with one member from each of the other teams. In effect this one team member becomes the communication channel between the teams.
Friday, July 13, 2007
Always an apprentice?
One of the best ways that I have found to both learn new languages/skills and to keep existing skills sharp is to practice each skill as much as possible. For programming languages this means regularly writing pieces of code in each language in the toolbox. I try to use each language that I know at least once a month for languages that I have become proficient in and at least once a week for languages that I am learning.
Dave Thomas describes this concept in greater detail in his CodeKata series.
I find the use of programming puzzles and challenges as excellent ways to find concise coding exercises that don't soak up to much time but yet provide opportunities to hone & develop skills as well as often providing opportunities to learn about new libraries, packages, algorithms etc.
Some of the best coding problem / challenge sites that I use are:
http://codekata.pragprog.com/
http://www.pythonchallenge.com/
http://www.topcoder.com/
Simple container dump using STL iterator
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main()
{vector v(10);
generate(v.begin(), v.end(), rand);
copy(v.begin(), v.end(),ostream_iterator (cout, "\n"));
return 0;
}
Friday, July 6, 2007
Pillars of Concurrency
The three "pillars" identified in the article:
- Responsiveness and Isolation Via Asynchronous Agents
- Throughput and Scalability Via Concurrent Collections
- Consistency Via Safely Shared Resources
An interesting reference from this article is to an earlier article from Herb illustrating why lock based programming is hard and insufficient: http://www.ddj.com/dept/cpp/184401930