- Martin Fowler, M. Mason: Why not to use feature branches and prefer feature toggles instead, when branches can actually be used (video, 12min) - feature branches are pretty common yet they are a hindrance for a good and stable development pace due to "merging hells". With trusted developers, feature toggles are a much better choice.
- M. Fowler: The LMAX Architecture - Martin describes the innovative and paradigm shaking architecture of the high-performance, high-volume financial trading platform LMAX. The platform can handle 6 million orders per second - using only a single java thread and commodity hardware. I highly recommend the article for two reasons: First, it crashes the common view that to handle such volumes you need multithreading. Second, for the rigorous, scientific approach used to arrive to this architecture. The key enablers are: 1) The main processing component does no blocking operations (I/O), those are done outside (in other threads). 2) There is no database - the state of the processor can be recreated by replaying the (persistent) input events. 3) To get further from 10k to 100k TPS they "just" wrote good code - well-factored, small methods (=> Hotspot more efficient, CPU can cache better). 4) To gain another multitude they implemented more efficient, cache-friendlier collections. All that was done based on evidence, enabled by thorough performance testing. 5) The processor and input/output components communicate without locking, using a shared (cyclic) array, where each of them operates on sum range of indexes and no element can ever be written by more than one component. Their internal range indexes do ever only increase so it is safe to read them without synchronization (at worst you will get old, lower value). The developers also tried Agents but found them in conflict with modern CPUs for their require context switch leading to emptying of the fast CPU caches.
Updated: Martin has published the post titled Memory Image which discusses the LMAX approach to persistence in a more general way.
- S. Mancuso: Working with legacy code with the goal of continual quality improvement - this was quite interesting for me as our team is in the same situation and arrived to quite similar approach. According to the author, the basic rule is "always first write tests for the piece code to be changed," even though it takes so much time - he justifies it saying "when people think we are spending too much time to write a feature because we were writing tests for the existing code first, they are rarely considering the time spend elsewhere .. more time is created [lost] when bugs are found and the QA phase needs to be extended". But it is also important to remember when to stop with refactoring to get also to creating business value and the rule for that is that quality improvements are done only with focus on a particular task. I like one of the concluding sentences: "Constantly increasing the quality level in a legacy system can make a massive difference in the amount of time and money spend on that project."
- Uncle Bob: The Land that Scrum Forgot - Scrum makes it possible to be very productive at the beginning but to be able to keep the productivity and continue meeting the expectations that are thus created we need to concentrate on some essential technical practices and code quality. Because otherwise we create a mess of growing complexity - the ultimate killer of productivity. Uncle Bob advices us what practices and how to apply to attain both high, sustainable productivity and (as required for it) high code quality. It's essential to realize that people do what they are incented to do and thus we must measure and reward both going fast and staying clean.
How do we measure quality? There is no perfect measure but we can build on the available established metrics - coverage, # (new) tests, # defects, size of tests (~ size of production code, 5-20 lines per method), test speed, cyclomatic complexity, function (< 20) and class (< 500) sizes, Brathwaite Correlation (> 2), dependency metrics (no cycles, in the direction abstraction).
The practices that enable us to stay clean include among others TDD, using tools like Chceckstyle, FindBugs to find problems and duplication, implementing Continuous Integration.
- Getting Started: Testing Concurrent Java Code - very good and worthy overview of tools for checking and testing of concurrent code with links to valuable resources. The author mentions among others FindBugs, concurrent test coverage (critical sections examined by multiple threads) measurement with IBM's ConTest, multithreaded testing with ConTest (randomly tries to create thread interleaving situations; trial version - contact the authors for the full one) and MultithreadedTC (which divides time into "ticks" and enables you to fine-configure the interactions)
- The top 9+7 things every programmer or architect should know - quite good selection of nine, respectively 7 things from the famous (on-line available) books 97 Things every programmer/architect should know.
- Beans and noses - J. Spool reveals the First Rule of Consultancy: "No matter how much you try, you can’t stop people from sticking beans up their nose." In other words, sometimes your clients decide to do some very unwise thing and no amount of reasoning can discourage them from that (quite understandably, as already the way they got to this decision defies logic). "The only thing I can do in a beans-and-noses situation is wait. Wait until the bean is in its final resting place." Then you ask the person how it is working for him and "... if sticking a bean deep into their nostril doesn’t meet the very high expectations they’d had, I can now start talking alternative approaches to reaching those expectations." Already before you can actually ask them about their expectations, in some cases (50:50) this discussion can lead them to realize they could achieve them with an alternative, less painful approach. Now, if you have read up to this point, you clearly have enough time, so go an read the article because it's really orth it!