1,007 karma · joined August 8, 2011
Find out more about me at http://davidtanzer.net Twitter: https://twitter.com/dtanzer Email: business@davidtanzer.net
OTOH, I recently had an interview at a company who have quite a bit of groth and scaling problems right now (but probably not Silicon Valley level), and they still said: "We constantly have to learn new things, so the most important thing a candidate has to have is they have to enjoy learning new things".
AND: there are quite a lot of companies who are in the stable / profitable / predictable growth category and could afford to train/develop their people - But don't.
The CEO of one of my past clients, a consulting company, always said: "You can teach everyone to be a great programmer". And he put his money where his mouth was: He hired people with no programming experience (even with no university education) and personally trained them for several months. Also, senior people in the company were encouraged to also help them and guid them.
He had to fire some of those people later, mostly because they were not a good fit for the company. But some of them became great programmers and software consultants.
"Hire only the best" is really only half of the battle. Give people an environment where learning is encouraged and failure is expected. And help them wherever you can. Most will learn and enjoy it.
So, inheritance is not always bad, and you should not avoid it at any cost. But you should avoid it where you can. AFAIR, the original quote from the GoF book ("Design Patterns") was something like: "Favour composition over inheritance", not "Stop using inheritance alltogether".
The biggest cost of inheritance (that is, inheritance of concrete methods and state) is tight coupling. You couple two classes together in a way that makes them really hard to test, change and evolve in isolation. Everything becomes worse if you have mutable state in one of the two classes.
This can cause ripple effects in your code: You try to fix one little defect, and in fact you end up changing several classes and unit tests because everything is so tightly coupled and because everything has side effects.
There are several techniques to reuse code that give you better decoupling: You can extract pure functions from your code - They are really easy and painless to reuse when you get the abstractions right. You can compose objects instead of inheriting from them. You can use callbacks or lambda expressions instead of abstract methods.
To recap: Inheritance always comes at a cost. And you can often find solutions that are just as easy or easier to understand, and that will better decouple and isolate parts of your code.
Thanks for the hints about defects. I like "unacceptable code", but it's probably still a definition not everyone can live with :)
"It's Not Much Slower Anyway The Microsoft study on TDD"
"You're conflating quality and testing here. They're not the same."
You are right. My arguments here are only for TDD, and I actually did not want to write a TDD article :) I'll think about how to improve that section. Also, CleanRoom is really interesting, but I don't know very much about it and never experienced it.
"At some point, your users will recognize that it takes longer and longer..." "Should be one of the top points."
I was thinking about the order of the points a lot, and no particular order seemed really right. It now comes at a point where I think I have established all the preconditions: Speed means lead time, cost depends on speed, high external quality means faster, high internal quality means faster. But you're right, the main points I want to bring across come very late in the article. As for the illustrations: Maybe I'll write another article about how users care about internal quality - Because I've worked in so many legacy code projects that I think I have a good view on that :)
I like your points about the iOS stuff and the short-term jobs. I'll think about them some more. I'm still not sure if I believe the "unlimited downside" idea 100% (because only very few things are truly unlimited), but it's an interesting concept.
I did not read that paper (book?), but will add it to my "To Read" pile. Thank you ;)
The first thing I noticed is that no-one tuned out. When I organized my trainings so that participants do the exercises alone or in pairs, some would just not do them. They might have too much problems to even get started. Or, when pairing with a better developer, just let them do the work. In the mob, paid attention everybody joined the discussion. [1]
Also, I think there was a better shared understanding of the examples and the solutions after the mob programming. When working in pairs, I had to monitor 5-8 pairs in parallel and give them hints and explain stuff. With the mob, I could concentrate on one screen and join the discussion all the time.
And: Others were helping me out. At one point, a participant said: "I don't want to take the driver seat, I am no programmer, just a manager". Before I could even say something, someone else from the audience said: "Come on, try it. We tell you what to write, and after 10 minutes, we'll change again anyway".
So, to recap: I really like mob programming for teaching. I think it could also work well when a team wants to learn something new, has a hard design session or wants to bring new team members up to speed. I even think it could work during day-to-day work, but I have never tried that.
[1] Maybe I was just lucky and had a great group when we were duing mob programming. But I doubt that.
In discussions about software metrics, I'm always trying to make the point that you can only use most metrics from within a team to gain insights, not as an external measure about how good/bad the code (or the team) is. In other words, if a team thinks they have a problem, they can use metrics to gain insights and explore possible solutions. But as soon as someone says "[foo metric] needs to be at least [value]", you have already lost - the cheating and gaming begins. Even if the agreement on [value] comes from within the team.
Back to the topic :) I am not surprised by the findings - Higher test coverage does not mean that everything is fine. But very low test coverage indicates that there might be hidden problems here or there. This is how I like to use test coverage and how I try to teach it.
But it is great that we have now empirical data here: From now on, I can point others to this study when we are discussing whether the build server should reject commits with less than [value] coverage.
(The following is kinda a side note...) Some time ago, a friend told me "You are so lucky! You never apply anywhere - Companies come to your and ask you if you want to work for them!" Which is not entirely true, I do apply for projects, but...
I have been working as an independent consultant for almost 10 years now. And creating a steady stream of business is crucial for my survival. So I spend a lot of time - more than some are willing to spend on their hobbies - to make sure as many people as possible know me - and that they know what I can and what I cannot do for them. Also, that the right people know me.
I'm still not as good as it as I would like. But sometimes, good jobs "just" come to me. I can just tell you: It still requires a lot of work from my side. This work just doesn't include writing job applications / RFPs.
Do not even try to write what you think is effective code before
benchmarking. The VM has many clever optimizations. And even if
you will somehow learn of all of them, in the next release they
still can be changed. Instead, write a simple and clean piece of
code, make a benchmark, find the real bottleneck and rewrite code
in small parts.
Every now and then I see some strange code at a client I work with, and the justification is "Performance". Because somebody thought it might be faster - But they didn't check it back then. And they don't have an automated performance test that continuosly validates if their "dirty but fast" code is still faster than the clean version...Don't even ask how many hours of developer time I saw wasted because of "dirty but fast" code. Where the code often was not much faster then the clean version. Or it was faster, but speed was not crucial in the area where the code operated.
Also, I guess a lot of the optimizations from old blog posts or the first "Effective Java" will not yield amazing results anymore, as compilers and runtimes are getting better.
I also like this one:
Do not think that programming in C++ or any other lower-level language
is a must for having good performance. Good architecture, benchmarking
and profiling are far more important.
But I don't think it is as clear-cut as the author writes it. For some problems, having total control over your memory layout and what gets exectued when (i.e. C or C++ or ...) can lead to huge benefits. And sometimes, the runtime is just more clever optimizing the code than you are.BTW, if any technique in software development leads you to bad design, and you don't stop and try to improve something, you're doing software development wrong. If a technique does not help you, you have two possibilities: Trying to do it better (maybe with outside help), or trying something different.
[1] http://www.makinggoodsoftware.com/2012/01/27/the-evil-unit-t...
I mean, you can say that. But doing so makes you look... ignorant - at best. You know, there is a possibility that you just got it wrong.
So, many great programmers say that they get benefits from TDD. They get benefits. Not the suits. Not their co-workers. They.
TDD is hard. I had to learn it and practice it. And I'm still learning and practicing it, even though I'm now also teaching it to others and helping teams implement it. But I get benefits from it. Writing tests helps me to think about problems and to actually improve my designs [2]. And writing tests helps me to know when to stop - To not gold-plate my designs.
Sorry, but this "article" is just an angry rant, with no real arguments. Please, don't give up on TDD early because of rants like this. If you have any questions about TDD or need help getting started, feel free to ask (here or in private - you'll find my email address in my profile)...
[1] http://davidtanzer.net/no_true_scotsman_in_agile
[2] But you have to refactor ruthlessly. And learn and practice refactoring, which is hard.
You know, there is a reason nobody uses client certificates...
What I like: I am authenticated by some proof of ownership, and, unlike with password authentication, the "thing I own" is never transferred over a wire or stored at the server. This is even better than what I have now (unique passwords for every site, managed with 1Password, and 2FA for important sites).
But the SSH callback would have to be automatic - Via a browser plugin, or even better, implemented by the browser itself. I don't think I want to start a terminal and past a string every time I log in to a site.
The "paste this into your terminal" also opens up a completely different can of worms - Social engineering!
Also, I was once co-teaching a C# workshop where we showed people how to work with LINQ and extension methods (long, long time ago ;) ). Some participants asked us if there was a way to configure the compiler to forbid those features for their team.
Not everybody likes "modern" features, I guess ;)
If you are using Java and have not tried Lambda Expressions, method references and default methods, do so now! After that, you'll think "How was I able to live without that?".
I also think that the way Java integrates lambda expressions (via functional interfaces) is really nice. Sure, you have to write some boilerplate code in some scenarios. But since they re-used interfaces and did not event some "function" type (or similar), it fits really nicely into the existing language.
If you don't know Java, this tutorial will probably not be enough - But that probably wasn't the intentian anyway. It's a great intro to what has changed with Java 8 (and all those changes are real improvements for the Java language, IMHO).
For Java code, it's often easier to predict the performance characteristics of a part of the code. But you shouldn't trust your judgements anyway - instead use a profiler - so this is not really a reason.
Speaking of performance: I once talked to someone working for Elasticsearch, and they told me that they cannot use clojure for most of their code because of their performance requirements. Clojure collections are almost as fast as Java collections in many scenarios, but that is apparently not fast enough for them. This is probably not a valid reason for most projects, though.
There is a huge number of Java developers out there, and Java is easier to learn for someone coming from C++ or C# or JavaScript than clojure (at least I am pretty sure about that). So hiring cheap developers might be easier if you use Java. You might count that one as a political statement.
There are some great tools for Java out there: IntelliJ Idea, Yourkit Profiler, JRebel, ... Cursive Clojure is great, but IntelliJ for Java has even more integrated workflows.
There are very mature open source libraries / frameworks / tools for Java: JUnit, Spring, Guice, Dropwizard, Gradle, Elasticsearch, ... You can have commercial support for many of them. Most of the libraries I use with clojure are version 0.3 or something like that with no possibility for commercial support (but they work fine anyway).
Static typing: A lot of people complain about it, but it can really help you to create maintainable code. See for example http://talks.samirtalwar.com/use-your-type-system.html
I think that the primary goal of court scentences should not be revenge, but "justice". Whatever that means. The possibility of punishment should be there to deter people from committing crimes. And they should be there so that after a crime, society can say: "See, we are serious about this. We do not want people to do those things".
So, the "revenge" thinking (with the extreme of "Take one life, and we'll kill you") does not seem right to me. Also, AFAIK, it was not designed into our juridical system - Which was designed to get past the "eye for an eye" system that was there before.
I also think that the primary goal of our prisons should be to re-integrate people into society, not punish them, but this is a completely different topic...
Edit: Clarified "The possibility of punishment should be there to deter"
But I guess that would work only in theory, because those plants would probably need quite a lot of infrastructure - right?
[Edit: Clarifications after reading the replies]
Gune: [holding up a small device] Does this look familiar? Do you know what it is?
Neither do I. I made it last night in my sleep.
Apparently I used Gindrogac. Highly unstable.
Preed: Gune...
Gune: I put at button on it. Yes. I wish to press it,
but I'm not sure what will happen if I do.
http://www.imdb.com/title/tt0120913/Seriously, this is a cool device. And I have no idea what I could use it for...
I think we need to believe in Europe and that also means that we have to accept european arrest warrents. We can also reasonably believe that all EU member states have acceptable standards when it comes to human rights and fair trial.
Only you hurt the creator more online, since the advertisers can now measure the views+clicks. Which is also perfectly fair - They should not have to pay for ads nobody sees. This would also be fair on TV - But there it's impossible to measure.
They are not allowed to search you without a reason (In theory. I heared that they might just say "I think I smelled cannabis" and then they have a reason.)
Disclaimer: IANAL, and maybe I got some details wrong.