tag:blogger.com,1999:blog-28885621668675723812023-11-15T09:31:26.129-08:00CommentariesStaring reality in the face without flinching.Howard Fearhttp://www.blogger.com/profile/03273633740035650194noreply@blogger.comBlogger19125tag:blogger.com,1999:blog-2888562166867572381.post-70773409530824442252015-04-27T19:59:00.000-07:002020-05-12T07:10:32.007-07:00On Missing PeopleThere are many people throughout the course of my life who I have lost touch with and who have never popped up anywhere I can find on the internet. I am curious about what happened to you in life. So, if you are one of the following people and you run across this please feel free to drop a line.<br />
<br />
(If it seems there are more girls than boys, that's probably true. It seems like I've been much more successful at staying in touch with my friends than my girlfriends let alone those who I just had crushes on.)<br />
<br />
<h4>
</h4>
<h4>
Kilmer / Sullivan</h4>
<div>
<i>Howard Joseph</i> - my best friend throughout my Kilmer years. Last we spoke, you were in the military in Georgia I think.</div>
<div>
<br /></div>
<div>
<i>Ned Trifunovich</i> - my best friend in 8th and 9th grade. Your brother emailed me years ago but somehow I never ended up connecting with you.</div>
<div>
<br /></div>
<div>
<i>Patty Murphy</i> - Oh, did I have a crush on you in 7th & 8th grade. You may not even remember me. But somewhere I have a picture of us dancing in our 7th grade dance lessons that Miss Abdel put in my graduation card from 8th grade.</div>
<div>
<br /></div>
<div>
<i>Ana Eppelbaum</i> - My 9th grade crush whom I was too shy to talk to until after I'd moved to Denver. But we had a great mail correspondence.<br />
<br /></div>
<h4>
</h4>
<h4>
Camp Yehuda</h4>
<div>
<i>Karen Ellis</i> - my first camp girlfriend. You came to my Bar Mitzvah and you introduced yourself to everyone as my girlfriend which all the adults thought was adorable. (Wow, you connected with me on Facebook. Glad you did! Sooner or later, I'll dig out a picture of you at my Bar Mitzvah!)</div>
<div>
<br /></div>
<div>
<i>Aliza Shuster</i> - the other of my big camp girlfriends. You may have been a twin, but I thought you were one of a kind.</div>
<div>
<br /></div>
<div>
<i>Merle Kahn</i> - you were a good friend to me, better than I was to you but I appreciated your friendship.<br />
<br /></div>
<h4>
</h4>
<h4>
George Washington</h4>
<div>
<i>Grant Huff </i>- my best friend through high school. You dropped out and moved to Capital Hill and we lost touch. I am afraid that you died in Dallas in the 80s.</div>
<div>
<br /></div>
<div>
<i>David Arnold</i> - You moved in as Grant was moving out. Some months I remember your last name, some months I forget. Forgive me, I am bad with names. But I will never forget driving around all the alleys in Denver in your VW bug.</div>
<div>
<br /></div>
<div>
<i>Julie Field</i> - another crush who never knew. We took honors classes together over the years and Field usually followed Fear in the alphabetic list of students so...<br />
<br /></div>
<h4>
</h4>
<h4>
BBYO</h4>
<div>
<i>Teri Goldman</i> - My 11th grade girlfriend. I'm still in touch with people who are still in touch with you. I understand you don't do the technology thing. But if you ever do, you can find me here.</div>
<div>
<br /></div>
<div>
<i>Debbie Roth</i> - Although you were from Columbus Ohio, we met at the D2 district convention in Denver.</div>
<div>
<br /></div>
<div>
<i>Megan Ovitz </i>-We dated briefly and, if I had been smart, we would have dated more. You lived in a great house and loved Paul McCartney and were much cooler than me.</div>
<div>
<br /></div>
<div>
<i>Chipper Libber</i> - On reflection, I suspect that I misheard and that its really Chipper Lippur. It wasn't really Chipper. It was really Tziporah and your parent called you Tzippah. Which to your friends became Chipper. Was it ILTC or Kallah? Or perhaps both.<br />
<br /></div>
<h4>
College</h4>
<div>
<i>Jon Washington</i> - Hey Jon, where are you. Did you get that CS degree? I know, I hope I wasn't too bad an influence.</div>
<div>
<br /></div>
<div>
<i>David Bernstein</i> - Last I heard, you have transferred to UT in Austin. Do you know how unlikely it is to find a specific David Bernstein from Chicago?<br />
<br />
<i>Tammi Baker</i> - A girl in my Group Dynamics course my final semester at CU.<br />
<br /></div>
<h4>
</h4>
<h4>
Bell Labs</h4>
<div>
<i>Sonja Husby</i> - We dated briefly but you became a really good friend. Good enough that you came to our wedding. I really can't imagine that you didn't get on the internet somewhere.</div>
<div>
<br /></div>
<div>
<i>Mildred Nabbe</i> - You were my first mentor. And I suppose that you might have passed away in 25 years that have passed. But I hope not. I will never forget your candy jar. (Further research suggests that your maiden name was Mrazek and that you passed away in the late '80s. Too young.)<br />
<br /></div>
<h4>
</h4>
<h4>
StorageTek</h4>
<div>
<i>Peter Bliss</i> - You were my first manager as a manager and I learned a lot from you. Before STK, you had been a development manager at Lotus for the Agenda product - a product that was really ahead of its time.</div>
<div>
<br /></div>
<div>
<i>Joe Lovato</i> - Another of my second levels whom I really respected. I can't believe you aren't on the internet somewhere.</div>
<div>
<br /></div>
<div>
<i>Scott Allen</i> - You inherited me three different times, so I don't know what you did to piss off the Gods. I heard you left tech for the ministry. I would still love to hear your thoughts on this whole internet thing ;-)</div>
<div>
<br /></div>
<div>
Pretty much everyone else postdates the internet age so we haven't fallen out of touch (that I know of).</div>
<div>
<br /></div>
<div>
If you know me and your name isn't on this list, you have lots of good company. In 50+ years of life you will touch and be touched by lots of people. So do feel free to drop a line. </div>
<div>
<br /></div>
Howard Fearhttp://www.blogger.com/profile/03273633740035650194noreply@blogger.com2tag:blogger.com,1999:blog-2888562166867572381.post-91501805365138557042014-10-06T16:03:00.001-07:002014-10-06T16:32:35.153-07:00On JavaOne 2014<div class="p1">
Conference Summary</div>
<div class="p2">
<br /></div>
<div class="p3">
I mostly went to 5 kinds of sessions:</div>
<ul class="ul1">
<li class="li3">java 8 features (streams, lambdas)</li>
<li class="li3">java mechanics (garbage collecting, classloading)</li>
<li class="li3">groovy (traits, groovy & java 8, groovy futures)</li>
<li class="li3">code quality (DDD, code reviews, coding culture)</li>
<li class="li3">client server (websockets, rest)</li>
</ul>
<div class="p3">
The big takeaways included:</div>
<ul class="ul1">
<li class="li3">java 8 is really about enabling parallel execution. Streams was the driving feature. Lambda expressions exist to support streams (and are incomplete) and type inferencing is required to support lambda expressions. Interface default methods exist to extend existing collections to support streams. Method references are there to support streams. Yes, the result is that you can do functional things in java 8, but the goal is parallelism not functional programming. So there are gaps as well.</li>
</ul>
<ul class="ul1">
<li class="li3">Groovy seems to be stuck. They don’t seem to have finalized what they want to do about java 8 features. And, since they already have many similar but not quite compatible features, they seem to be caught in a paradox. Should they continue to try to make java programs compile mostly as-is in groovy? Should they make their existing features work like the java 8 counterparts and potentially break backward compatibility? Should they try to make both work and complicate the language semantics? There doesn’t seem to be an easy answer. And they didn’t have a compelling story around why you should continue to use groovy in the face of java 8.</li>
</ul>
<ul class="ul1">
<li class="li3">I found that even though I knew about lambda expressions and streams, doing the tutorials really helped make all the blocks fit for me. You may want to see if anyone is doing similar overviews at your jug back home.</li>
</ul>
<ul class="ul1">
<li class="li3">The ability to mixin small bits of behavoir in the form of capabilities is an increasingly important design technique for object oriented systems. </li>
</ul>
<h3>
<span style="font-size: large;">
Session Summaries (TL;DR)</span></h3>
<h3>
</h3>
<h3>
<br /></h3>
<h3>
Collection and Reduction in the Steams API (Tutorial)</h3>
<div class="p3">
Stream: an abstraction representing zero or more values. Streams can be sequential or parallel. Elements in a sequential stream will be provided in sequence. Elements in a parallel stream may be provided across different threads and different processors and will not appear in sequence. [This actually came from a subsequent presentation.)</div>
<div class="p2">
<br /></div>
<div class="p3">
Stream is organized as a pipeline</div>
<ul class="ul1">
<li class="li3">source</li>
<li class="li3">intermediate operations (return streams)</li>
<ul class="ul2">
<li class="li3">map, filter, sort</li>
</ul>
<li class="li3">terminal operations (return to the non-stream world)</li>
<ul class="ul2">
<li class="li3">collectors - returns collections</li>
<li class="li3">reducers - returns values</li>
</ul>
</ul>
<div class="p3">
Really designed to parallel-ize work</div>
<div class="p2">
<br /></div>
<div class="p3">
There are are large number of out-of-the box collectors such as toList(), joining(), toSet(), averaging(), toMap(), partitioningBy(), groupingBy(). (See java.util.stream.Collectors)</div>
<div class="p2">
<br /></div>
<div class="p3">
You can also write a custom collector. A custom collector requires four functions:</div>
<ul class="ul1">
<li class="li3">supplier() // returns function to create of a new result container</li>
<li class="li3">accumulator() // returns function to add a new element into the result container</li>
<li class="li3">combiner() // returns function to combine two result containers</li>
<li class="li3">finisher() // returns function an optional final transform on the container</li>
</ul>
<div class="p3">
If you were going to create a collector that put results into a google guava immutable set:</div>
<pre>public class ImmutableSetCollector<T> implements Collector<T, ImmutableSet.Builder<T>, ImmutableSet<T>>
@Override public Supplier<ImmutableSet.Builder<T>> supplier() {
return ImmutableSet::builder;
}
@Override public BiConsumer<ImmutableSet.Builder<T>, T> accumulator() {
return (builder, t) -> builder.add(t);
}
@Override public BinaryOperator<ImmutableSet.Builder<T>> combiner() {
return (left, right) -> {
left.addAll(right.build());
return left;
};
}
@Override public Function<ImmutableSet.Builder<T>, ImmutableSet<T>> finisher() {
return ImmutableSet.Builder::build;
}
@Override
public Set<Characteristics> characteristics() {
return EnumSet.of(Characteristics.UNORDERED);
}
</pre>
<br />
<div class="p2">
<i></i></div>
<div class="p3">
There is an accumulator and a combiner so that the stream can be parallelized.</div>
<h3>
</h3>
<h3>
<br /></h3>
<h3>
Rethinking API Design with Traits</h3>
<div class="p4">
<span class="s1"><a href="https://speakerdeck.com/melix/rethinking-api-design-with-traits-in-groovy">https://speakerdeck.com/melix/rethinking-api-design-with-traits-in-groovy</a></span></div>
<div class="p2">
<br /></div>
<div class="p3">
I had actually seen the slides before going to the presentation. But I still got a lot out of it.</div>
<div class="p2">
<br /></div>
<div class="p3">
Traits are a new feature in Groovy 2.3.</div>
<div class="p2">
<br /></div>
<div class="p3">
Solving the problem of how to create reusable bits of behavior that can be mixed in to objects/classes. The previous attempt (@Mixin) had too many limitations.</div>
<div class="p2">
<br /></div>
<div class="p3">
Java 8 solves the same problem with default methods in interfaces. Groovy traits can have state where interface default methods can’t.</div>
<pre>trait FlyingAbility {
String fly() { "I'm flying!" }
}
class Bird implements FlyingAbility {}
assert new Bird().fly() == "I'm flying!"</pre>
<div class="p3">
Think of traits as a way of expressing the capabilities of a class.</div>
<div class="p2">
<br /></div>
<div class="p3">
Can be mixed in at runtime.</div>
<div class="p2">
<br /></div>
<div class="p3">
Really pushing the idea of developing classes by having small bits of behavior that can be mixed together with some custom behavior into a class.</div>
<div class="p2">
<br /></div>
<div class="p3">
Some AST transformations are not trait compatible.</div>
<h3>
</h3>
<h3>
<br /></h3>
<h3>
Reactive Streams with Rx</h3>
<div class="p4">
<span class="s1"><a href="https://speakerdeck.com/benjchristensen/reactive-streams-with-rx-at-javaone-2014">https://speakerdeck.com/benjchristensen/reactive-streams-with-rx-at-javaone-2014</a></span></div>
<div class="p2">
<br /></div>
<div class="p3">
This presentation just blew past anything I was able to easily understand.</div>
<div class="p2">
<br /></div>
<div class="p3">
(And I took the coursera course Principles of Reactive Programming so I’ve actually used the scala version of Rx.)</div>
<div class="p2">
<br /></div>
<div class="p3">
After blowing though 8-10 hours of lecture material from Principles of Reactive Programming in the first 20 minutes or so, he discussed a variety of flow control mechanisms in the context of various netflix systems that had no meaning to me.</div>
<h3>
</h3>
<h3>
<br /></h3>
<h3>
Unlocking the Magic of Monads in Java 8</h3>
<div class="p4">
<span class="s1"><a href="https://speakerdeck.com/shelajev/unlocking-the-magic-of-monads-with-java-8-javaone-2014">https://speakerdeck.com/shelajev/unlocking-the-magic-of-monads-with-java-8-javaone-2014</a></span></div>
<div class="p2">
<br /></div>
<div class="p3">
At some point, somebody is going to figure out that the single worst way to describe monads is to start with the terminology that comes from Haskell. Explaining monads by writing pure (or return) and bind methods in java is insane.</div>
<div class="p2">
<br /></div>
<div class="p3">
I am always looking to deepen my understanding of monads and I am particularly interested how to use or implement the various common monads in Java 8. And I suspect that if I study the code, I will probably learn something from it. But you can’t actually do that in these sessions (more on that later), so I was disappointed.</div>
<h3>
</h3>
<h3>
<br /></h3>
<h3>
Gradle: Harder, Better, Stronger, Faster</h3>
<div class="p3">
This ended up being little more than a commercial for using gradle over maven. It was also live coded so I can’t refer back to tell you anything more about this presentation.</div>
<h3>
</h3>
<h3>
<br /></h3>
<h3>
Real-World RESTful Service Development Problems and Solutions (BoF)</h3>
<div class="p3">
Rolled through 44 slides in 45 minutes. ‘Nuff said.</div>
<div class="p2">
<br /></div>
<div class="p3">
I’m sure there is good stuff in the slides somewhere….</div>
<h3>
</h3>
<h3>
<br /></h3>
<h3>
JAX-RS REST Services and Angular.js: Tools for an Even Better Experience (BoF)</h3>
<div class="p3">
Kind of a throwaway for me. But it was the 8pm BoF so I didn’t think I was going to be too awake by then anyway. The last half was live coding a demo which, aside from technical difficulties, was pretty interesting.</div>
<div class="p2">
<br /></div>
<div class="p3">
Did recommend swagger (<a href="https://helloreverb.com/developers/swagger"><span class="s2">https://helloreverb.com/developers/swagger</span></a>) for rest api docs.</div>
<div class="p2">
<br /></div>
<div class="p3">
Also recommended using DTOs for the collecting REST data. He worked on a bean mapper project Dozer but recommended a different mapper Orika (<a href="http://orika-mapper.github.io/orika-docs/index.html"><span class="s2">http://orika-mapper.github.io/orika-docs/index.html</span></a>).</div>
<h3>
</h3>
<h3>
<br /></h3>
<h3>
Jump-Starting Lambda (Tutorial)</h3>
<div class="p3">
Lambda expressions mostly appear (but are not necessarily implemented as) syntactic sugar for anonymous inner classes. So, instead of<br />
<br /></div>
<pre>void robocallEligibleDrivers() {
robocallMatchingPersons(new PersonPredicate() {
boolean test(Person p) {
return p.getAge() >= 16;
}
}
}
</pre>
<div class="p3">
<br />
You can write:<br />
<br /></div>
<pre>void robocallEligibleDrivers() {
robocallMatchingPersons(p -> p.getAge() >= 16);
}
</pre>
<div class="p3">
<br />
In order to implement lambda expressions, they also had to implement type inferencing. (Which they’ve enabled elsewhere as well.)</div>
<div class="p2">
<br /></div>
<div class="p3">
The type that is inferred for a lambda is a @FunctionalInterface or Single Abstract Method (SAM) interfaces.</div>
<div class="p2">
<br /></div>
<div class="p3">
There are a set of standard interfaces so defining your own interfaces is rarely necessary. The standard interfaces are:</div>
<pre>interface Predicate<T> { boolean test(T t); }
interface Consumer<T> { void accept(T t); }
interface Function<T,R> {R apply(T t); }
</pre>
<div class="p3">
Additional interfaces include:</div>
<div class="p2">
<br /></div>
<div class="p3">
<i>Supplier<T> () </i>? T</div>
<div class="p3">
<i>UnaryOperator<T></i> T ? T</div>
<div class="p3">
<i>BinaryOperator<T></i> (T, T) ? T</div>
<div class="p3">
<i>BiFunction<T,U,R></i> (T, U) ? R</div>
<div class="p2">
<br /></div>
<div class="p3">
Note that when you write methods designed to be called with a lambda, you will use one of the types above as the parameter type:</div>
<div class="p2">
<br /></div>
<div class="p3">
So, for example, if you were going to write something like Jim’s withSession method in java 8, you would have a signature like:</div>
<div class="p2">
<br /></div>
<div class="p3">
<i>static void withSession(SlingRepository slingRepository, String user, Consumer<Session> lambda) </i></div>
<div class="p2">
<br /></div>
<div class="p3">
<i>() -> 42 // Need empty parens for a supplier</i></div>
<div class="p3">
<i>(int a) -> a + 1</i></div>
<div class="p3">
<i>int a -> a + 1 // Can omit parens for a single param </i></div>
<div class="p3">
<i>int a -> { println(a + 1); return a + 1; } // Surround multiple statements </i></div>
<div class="p3">
<i>a -> { println(a + 1); return a + 1; } // Types may be omitted if they can be inferred</i></div>
<div class="p3">
<i>(int a, int b) -> a + b // need parens with more than one param</i></div>
<div class="p2">
<br /></div>
<div class="p3">
Method references are shortcuts to use methods as lambda expressions: There are 4 kinds of method references:</div>
<div class="p2">
<br /></div>
<div class="p3">
<i>Integer::parseInt // Reference to a static method taking the correct number of parameters</i></div>
<div class="p3">
<i>aPerson::toString // Reference to an instance method of a particular object</i></div>
<div class="p3">
<i>Person::toString // Unbound reference which will be bound by the lambda</i></div>
<div class="p3">
<i>String::new // Constructor</i></div>
<div class="p2">
<br /></div>
<div class="p3">
Streams</div>
<div class="p2">
<br /></div>
<div class="p3">
<b>Sources</b> include stream() methods on collections, Stream.empty(), Stream.of(…). Arrays.stream(), Stream.generate(), Stream.iterate(), Stream.range(), various methods in File, String, Pattern. etc</div>
<div class="p3">
<b>Intermediate operations</b> include forEach, map, filter, substream, limit, sorted, distinct, flatMap</div>
<div class="p3">
<b>Terminal operations</b> include collect, toArray, count, anyMatch, findFirst</div>
<div class="p2">
<br /></div>
<div class="p3">
collect() takes a combining collector. Some common collectors are toList(), joining(), toSet(), averaging(), toMap(), partitioningBy(), groupingBy()</div>
<div class="p3">
<br /></div>
<div class="p3">
String result = list.parallelStream()</div>
<div class="p3">
.map(String::toUpperCase)</div>
<div class="p3">
.collect(joining(“, ")); // static import of Collections.*</div>
<div class="p2">
<br /></div>
<div class="p3">
Convert a sequential stream to parallel using .parallel().</div>
<div class="p2">
<br /></div>
<div class="p3">
Lambdas change the way you design libraries</div>
<div class="p3">
Streams change the way you write applications</div>
<div class="p2">
<br /></div>
<div class="p3">
Method References will take over the world because you can code streams like:</div>
<div class="p3">
String[] output = list.stream()</div>
<div class="p3">
.map(String::toUpperCase)</div>
<div class="p3">
.toArray(String[]::new);</div>
<div class="p3">
<br /></div>
<div class="p3">
A couple of specific notes from this presentation and other presentations:</div>
<ul class="ul1">
<li class="li3">Lambda expressions must not mutate source collection while stream executes</li>
<li class="li3">Lambda expressions do not have identity - you can’t use equals()</li>
<li class="li3">Lambda expressions are not closures. Java already had closures which restricted access to instance variables to final. Java 8 has a broader concept of effectively final but the bottom line is you can’t modify instance variables from inside the lambda expression</li>
<li class="li3">Lambda expressions can be chained:<br />
<i>Callable<Runnable> c = () -> () -> { System.out.println("hi"); };</i></li>
<li class="li3">There is no direct support for currying. (Some people would say currying is a better alternative to closures.)</li>
</ul>
<h3>
</h3>
<h3>
<br /></h3>
<h3>
WebSocket in Enterprise Applications</h3>
<div class="p4">
<span class="s1"><a href="http://www.slideshare.net/pavelbucek/con4962-web-socketenterprise-39817241">http://www.slideshare.net/pavelbucek/con4962-web-socketenterprise-39817241</a></span></div>
<div class="p2">
<br /></div>
<div class="p3">
Ended up being mostly about the Java API for WebSocket and its reference implementation.</div>
<h3>
</h3>
<h3>
<br /></h3>
<h3>
Groovy in the Light of Java 8</h3>
<div class="p4">
<span class="s1"><a href="https://speakerdeck.com/glaforge/groovy-in-the-light-of-java-8-javaone-2014">https://speakerdeck.com/glaforge/groovy-in-the-light-of-java-8-javaone-2014</a></span></div>
<div class="p2">
<br /></div>
<div class="p3">
Lots of minor reasons to continue to use groovy over Java 8 but it felt somewhat contrived:</div>
<ul class="ul1">
<li class="li3">closure parameter defaults</li>
<li class="li3">duck typing polymorphism</li>
<li class="li3">more elegant builder syntax</li>
<li class="li3">memoization</li>
<li class="li3">tail recursion</li>
<li class="li3">traits</li>
<li class="li3">compile time meta annotations</li>
<li class="li3">elvis operator</li>
<li class="li3">groovy on android</li>
<li class="li3">grails, ratpack, griffon, spock, geb, gradle, GPars, </li>
<li class="li3">json support</li>
</ul>
<div class="p3">
Hasn’t really come to terms with java 8 features.</div>
<h3>
</h3>
<h3>
<br /></h3>
<h3>
Coding Culture</h3>
<div class="p4">
<span class="s1"><a href="http://www.slideshare.net/svenpeters/coding-culture">http://www.slideshare.net/svenpeters/coding-culture</a></span></div>
<div class="p2">
<br /></div>
<div class="p3">
You know those annoyingly always upbeat and relentlessly positive people? Hire only those people and then apply a whole bunch of new age techniques that fly in the face of everything we know about human nature. When everybody is shiny and happy and all group hugging and refusing to do anything wrong in the “doacracy” then Peter Pan will sprinkle magic dust and miracles will happen.</div>
<h3>
</h3>
<h3>
<br /></h3>
<h3>
Getting Started with MongoDB and Java</h3>
<div class="p3">
Turned out to be a live coding session that was mostly mostly derailed by detailed questions only vaguely related to the what the speaker was trying to do.</div>
<h3>
</h3>
<h3>
<br /></h3>
<h3>
Using Type Annotations to Improve Code Quality</h3>
<div class="p3">
Mostly a discussion about how you could use the checker framework <a href="http://types.cs.washington.edu/checker-framework/"><span class="s2">http://types.cs.washington.edu/checker-framework/</span></a> with the java 8 annotation extensions. Some discussion about how it all might be incorporated into IDEs. He did a nice demonstration using the regex checker to validate regular expressions at compile time.</div>
<h3>
</h3>
<h3>
<br /></h3>
<h3>
Java Debugging</h3>
<div class="p4">
<span class="s1"><a href="http://www.slideshare.net/cnbailey/javaone-2014-java-debugging?qid=fe2cf1cf-7da1-4a77-a0d2-ab830afce777&v=default&b=&from_search=3">http://www.slideshare.net/cnbailey/javaone-2014-java-debugging?qid=fe2cf1cf-7da1-4a77-a0d2-ab830afce777&v=default&b=&from_search=3</a></span></div>
<div class="p2">
<br /></div>
<div class="p3">
Garbage Collection Monitoring</div>
<ul class="ul1">
<li class="li3">IBMs Garbage Collection and Memory Visualizer (GCMV) (works with sun JVMs as well and IBMs) - visualization of monitoring: <a href="http://www.ibm.com/developerworks/java/jdk/tools/gcmv/"><span class="s2">http://www.ibm.com/developerworks/java/jdk/tools/gcmv/</span></a>.</li>
<li class="li3">-XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:<name></li>
<li class="li4"><span class="s3">[Howard’s note: Java SE 6 Garbage Collection Tuning: <a href="http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html"><span class="s1">http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html</span></a>]</span></li>
</ul>
<div class="p4">
<span class="s3">Mission Control for realtime monitoring of JVMs <a href="http://www.oracle.com/technetwork/java/javaseproducts/mission-control/java-mission-control-1998576.html"><span class="s1">http://www.oracle.com/technetwork/java/javaseproducts/mission-control/java-mission-control-1998576.html</span></a></span></div>
<ul class="ul1">
<li class="li3">might need to pay to use on servers?</li>
<li class="li3">-XX:+UnlockCommercialFeatures -XX:+FlightRecorder</li>
</ul>
<div class="p3">
valgrind - OS level memory profiling</div>
<div class="p2">
<br /></div>
<div class="p3">
Heap Dump Analysis:</div>
<ul class="ul1">
<li class="li3">-xx:+HeapDumpOnOutOfMemoryError</li>
<li class="li3">jmap -dump:format=b</li>
<li class="li3">JConsole</li>
</ul>
<div class="p3">
IBM Memory Analyzer supports HotSpot dumps</div>
<h3>
</h3>
<h3>
<br /></h3>
<h3>
Understanding Java Garbage Collection</h3>
<div class="p3">
Best presentation hands down. Here is a version of the presentation of the same talk at a previous conference. <a href="http://www.infoq.com/presentations/Java-GC-Azul-C4"><span class="s2">http://www.infoq.com/presentations/Java-GC-Azul-C4</span></a></div>
<div class="p2">
<br /></div>
<div class="p3">
I don’t think I can summarize it in any way that would do it justice. A couple of notes though:</div>
<ul class="ul1">
<li class="li3">Garbage collection is better than you think it is. In particular, it really will find dead objects. Don’t try to help until you’ve proven the need to. "Trying to solve GC problems in application architecture is like throwing knives.”</li>
<li class="li3"><b>GC stops for ~1 sec for each live GB</b></li>
<li class="li3">“Mostly" is the way vm vendors weasel out of GC guarantees. Mostly means sometimes it isn’t (usually means a different fall back mechanism exists)</li>
<li class="li3">Generational Hypothesis: most objects die young<br />
(A consequence this is that most live objects in the system are actually not young)</li>
<ul class="ul2">
<li class="li3">Which means that you can optimize differently for young objects and old objects</li>
</ul>
</ul>
<ul class="ul1">
<li class="li3">The amount of empty memory in the heap is the dominant factor controlling the amount of GC work</li>
<ul class="ul2">
<li class="li3">Empty memory controls the frequency of pauses (if the collector performs any Stop-the-world operations)</li>
<li class="li3">Empty memory DOES NOT control pause times (only their frequency)</li>
<li class="li3">In Mark/Sweep/Compact collectors that pause for sweeping, more empty memory means less frequent but LARGER pauses</li>
</ul>
</ul>
<ul class="ul1">
<li class="li3">The Application Memory Wall - Application instances appear to be unable to make effective use of modern server memory capacities</li>
<ul class="ul2">
<li class="li3">Garbage Collection is a clear and dominant cause</li>
<li class="li3">[Virtually] All current commercial JVMs will exhibit a multi-second pause on a normally utilized 2-6GB heap.</li>
<ul class="ul3">
<li class="li3">It’s a question of “When” and “How often”, not “If”.</li>
<li class="li3">GC tuning only moves the “when” and the “how often” around</li>
</ul>
<li class="li3">Monolithic stop-the-world operations are the cause of the current Application Memory Wall. Even if they are done “only a few times a day”</li>
</ul>
</ul>
<h3>
</h3>
<h3>
<br /></h3>
<h3>
Think Async: Embrace and Get Addicted to the Asynchronicity of Java SE 8 and Java EE 7</h3>
<div class="p3">
Ended up being entirely J2EE focused. Lots of code examples without real problems to motivate them. Like why would I want an Asynchronous Servlet for example.</div>
<div class="p2">
<br /></div>
<div class="p3">
I think this topic slide pretty much summarizes the whole press:</div>
<ul class="ul1">
<li class="li3">Long present in JMS</li>
<ul class="ul2">
<li class="li3">To be used almost everywhere</li>
</ul>
<li class="li3">Servlet 3.0/ 3.1</li>
<ul class="ul2">
<li class="li3">Asynchronous Servlets</li>
<li class="li3">Non blocking IO</li>
</ul>
<li class="li3">JAX-RS 2.0</li>
<ul class="ul2">
<li class="li3">Server side</li>
<li class="li3">Client side</li>
</ul>
<li class="li3">Asynchronous Session Beans</li>
<ul class="ul2">
<li class="li3">Server side</li>
<li class="li3">Client side</li>
</ul>
</ul>
<div class="p3">
This was also the second presentation that mentioned but didn’t really describe Server-Sent Events which is a technology that could have some interesting uses on a site like timewarnercable.com</div>
<h3>
</h3>
<h3>
<br /></h3>
<h3>
Programmatic WebSocket</h3>
<div class="p2">
This was a walkthrough of a sample program that used java websockets on both client and server. The program built a custom document-oriented rpc on top of websockets using xdr encoding. As a result, so much of this was custom code that it was hard to get anything out of the presentation.</div>
<h3>
</h3>
<h3>
<br /></h3>
<h3>
DDD in a Rapidly Changing Organization</h3>
<div class="p3">
I wish I had the slides for this. After an intro of DDD and XP, he discussed some lessons learned in that environment.</div>
<div class="p2">
<br /></div>
<div class="p3">
There was some “DDD sales pitch” kind of stuff particularly about improving communication with the marketing team.</div>
<div class="p2">
<br /></div>
<div class="p3">
A lot of the lessons were around the problem that their marketing group changes terminology faster than they can change implementations. Essentially marketing changes terminology because changing the name changes the perception. This caused a number of technical problems. One example that that they had used mock heavy TDD, so making even simple changes to the model often required changing dozens of tests. They they resisted making model changes. </div>
<div class="p2">
<br /></div>
<div class="p3">
There was another lesson that they had been hurt by too strict adherence to DRY.</div>
<h3>
</h3>
<h3>
<br /></h3>
<h3>
Do You Really Get Class Loaders?</h3>
<div class="p3">
This is the same presentation by a different presenter (from the same company): <a href="http://www.slideshare.net/guestd56374/do-you-really-get-class-loaders"><span class="s2">http://www.slideshare.net/guestd56374/do-you-really-get-class-loaders</span></a>. (At least until you get to the end.)</div>
<div class="p2">
<br /></div>
<div class="p3">
Classloaders are organized hierarchically. And, unless you arrange differently (which OSGI does), classes are loaded from the highest classloader possible.</div>
<div class="p2">
<br /></div>
<div class="p3">
A class has an identity of three things: a name, a package, and a classloader.</div>
<div class="p2">
<br /></div>
<div class="p3">
A couple of debugging tricks:</div>
<ul class="ul1">
<li class="li3">You can always get the classloader for an object (or class):<br />
<i>Class klass = object.getClass();<br />
ClassLoader classloader = klass.getClassLoader()</i></li>
<li class="li3">You can cast a classloader to a URLClassLoader and use the getUrls method to get the paths in the classpath:<br />
<i>URL[] urls = ((URLClassLoader) classloader).getUrls();</i></li>
<li class="li3">You can find which file a class was loaded from:<br />
<i>URL url = klass.getResource(“/“ + klass.getName().replaceAll("\\.", "/") + ".class”);</i></li>
<li class="li3">Someone pointed out that you can also use the following:<br />
<i>klass.getProtectionDomain().getCodeSource().getLocation();</i></li>
</ul>
<div class="p3">
When you leak a classloader, you leak all the classes it has loaded.</div>
<h3>
</h3>
<h3>
<br /></h3>
<h3>
Groovy in 2014 and Beyond</h3>
<div class="p4">
<span class="s1"><a href="https://speakerdeck.com/glaforge/groovy-in-2014-and-beyond-javaone-2014">https://speakerdeck.com/glaforge/groovy-in-2014-and-beyond-javaone-2014</a></span></div>
<div class="p2">
<br /></div>
<div class="p3">
Covered a lot of changes already in 2.3.</div>
<div class="p2">
<br /></div>
<div class="p3">
Groovy 2.4</div>
<ul class="ul1">
<li class="li3">New groovy-lang.org website</li>
<li class="li3">Groovy on Android</li>
<li class="li3">Macro module (maybe)</li>
</ul>
<div class="p3">
Groovy 3.0</div>
<ul class="ul1">
<li class="li3">Rewritten Meta-Object protocol</li>
<li class="li3">New antlr grammar</li>
<li class="li3">Java 8 language support (definitely not solidified)</li>
<li class="li3">Can they continue to make valid Java syntax work in groovy?</li>
<li class="li3">lambdas</li>
<li class="li3">method references</li>
<li class="li3">interface default methods</li>
</ul>
<h3>
</h3>
<h3>
<br /></h3>
<h3>
Want Code Quality? Just —The Art of the Code Review</h3>
<div class="p3">
You should do code reviews. And if anyone doesn’t like it, you should manipulate them into liking it.</div>
<h3>
</h3>
<h3>
<br /></h3>
<h3>
Closing Keynote</h3>
<div class="p3">
Mostly and advertisement for Intel and various companies using Java. But the technical part of the opening keynote apparently had run too long so the last half was moved here as well. The interesting takeaway is that they are working on real value objects (<a href="http://openjdk.java.net/jeps/169"><span class="s2">http://openjdk.java.net/jeps/169</span></a>) for java 10 which apparently will be a big change. They are also redoing the module system (<a href="http://openjdk.java.net/projects/jigsaw/"><span class="s2">http://openjdk.java.net/projects/jigsaw/</span></a>) in java 9.</div>
<h2>
</h2>
<h3>
<span style="font-size: large;"><br /></span></h3>
<h3>
<span style="font-size: large;">
Conference Review (Really TL;DR)</span></h3>
<div class="p3">
JavaOne is the tale of The Good, The Bad, and The Ugly</div>
<div class="p2">
<br /></div>
<div class="p3">
<span class="s1"><u>The Good</u></span></div>
<div class="p2">
<br /></div>
<div class="p3">
Several of the presentations were outstanding. World class presentations by real experts. Even the presenters that weren’t great were certainly experts. All-in-all the content was good and where it wasn’t I could probably have done a better job of picking sessions. (Yes, I’d like to learn websockets. I’m not sure why I thought I would be able to here.)</div>
<div class="p2">
<br /></div>
<div class="p3">
<span class="s1"><u>The Bad</u></span></div>
<div class="p2">
<br /></div>
<div class="p3">
The conference is too big which effects everything. Long lines everywhere. Particularly for morning coffee and meals. </div>
<div class="p2">
<br /></div>
<div class="p3">
Full sessions which required pre-registration to get in. Which means that you couldn’t get interesting in something and just jump into further sessions on the topic. Nor could you bail on a session and expect to be able to walk into another one.</div>
<div class="p2">
<br /></div>
<div class="p3">
No meal breaks? Really? All meals to go? Really? Long lines to get meals with no actual meal breaks? Really? I’m not doing the late night drinks at Duke’s Cafe - particularly when sessions run until 8:45 pm. So meals are when I would expect to be able to meet my peers and swap stories. (Fortunately for me, it just gave me an excuse to run out to various take out places across various streets from the conference hotels which had shorter lines and better food. Definitely try the Filipino place across from the Hilton!)</div>
<div class="p2">
<br /></div>
<div class="p3">
The "appreciation event". I didn’t come to the conference to be appreciated. I came to learn things. I really just feel like I missed out on what could have been a couple more interesting presentations. </div>
<div class="p2">
<br /></div>
<div class="p3">
<span class="s1"><u>The Ugly</u></span></div>
<div class="p2">
<br /></div>
<div class="p3">
Some of the rooms were too small for the number of seats - and all the seats were full. Airplanes seats have more room. I had to leave the first tutorial at the half-way point because I was getting faint in the room. I had to organize the remainder of the conference to get to rooms when they opened entry to get aisle seats where I could make room.</div>
<div class="p2">
<br /></div>
<div class="p3">
No power. And no tables. I don’t know how they expect anyone to take any real kind of notes.</div>
<div class="p2">
<br /></div>
<div class="p3">
No slides. As you can tell from the summaries above, I found some presentations really hard to follow. If you are going to do a technical presentation, you need to provide slides so that I can glance back and forward to get my bearings when I start to get lost. (And all technical presentations have those moments where you start to get lost.) And none of these “no more than one word per slide” presentations that provide no information on the slides. If this is a technical presentation, I expect 4-10 bullets per slide or code examples. Otherwise, you’re just Steve Jobs putting on a show. And whoever came up with live-coding should be shot. And then burned. And maybe stabbed for good measure.</div>
<div class="p2">
<br /></div>
<div class="p3">
My Net Promoter Score - maybe a 5. Good content but, IMO, extremely poor logistics for a technical conference driven in part by the size of the conference.</div>
<div class="p2">
<br /></div>
Howard Fearhttp://www.blogger.com/profile/03273633740035650194noreply@blogger.com0tag:blogger.com,1999:blog-2888562166867572381.post-1918177188450662342012-06-22T20:37:00.001-07:002012-06-22T20:37:40.049-07:00On the Hubris of the Modern Software IndustryHere I sit at Uberconf. While this should be a fun three learning-filled days, I find myself growing increasingly frustrated and disappointed. I had not realized that my industry had become so filled with hubris, so blinded by the sparkle of the latest, so contemptuous of experience and expertise. <br />
<br />
I remember my early 30s, being a unix guy in a mainframe company. I remember that we certainly believed that we were on a better technology, one that was easier and more fun to use. What I don't remember was ever believing that we were better or smarter as programmers than the mainframe guys (and a few women) across the hall. Like us, they were a mixed bag. Some folks I really respected and some that I wouldn't have let check in code.<br />
<br />
So the disdain that our industry now holds for java programmers, or perhaps I should say "just" java programmers came as a complete surprise. After all, technology (language, tools, frameworks) has as much to do with programming skill as sneakers have to do with basketball. The hallmarks of great programmers, in my experience, are the ability to think deeply about problems, decompose solutions into pieces that fit neatly together, hold an abundance of detail in mind, and an obsession with the code being right. There is nothing there that is specific to scala or java or c or lisp.<br />
<br />
"But, But," I hear you say, we want programmers who want to "learn". As if the only thing to learn is the language de jour or the new fad platform. One of the worst programmers I've worked with was a great learner, an awesome technologist, always up on the latest thing. We used to say that his expertise ran a mile wide and an inch deep. The skill I want is not learning but mastery. I will take someone who has mastered a technology, really mastered it, over anyone content with merely chasing the latest technologies.<br />
<br />
Of course, that doesn't mean that any programmer should (or can) stay with a single technology for the bulk of their career. Technology does change and the languages of my youth are no longer in common use. But it is also true that new languages, new technologies become easier and easier to learn. Today's technologies all have their roots in the past and the lessons learned then still apply.<br />
<br />
So, really, I just want to say to today's programmers, get over yourselves. You are neither the best nor the worst nor is your experience unique. Its great to be obsessed by programming, in my experience all the great programmers are at some point in their careers. And don't be surprised when life presents other attractions and other challenges, when learning the next big thing takes a back seat to taking care of the little peep in the back seat. It won't make you any less excellent as a programmer, it just means the 30 somethings will think so.<br />
<br />
<br />
<br />
<br />
<br />
<br />Howard Fearhttp://www.blogger.com/profile/03273633740035650194noreply@blogger.com1tag:blogger.com,1999:blog-2888562166867572381.post-72617688145238962972012-03-03T12:35:00.000-08:002012-03-03T12:36:50.160-08:00On Azitra RestaurantA couple of weeks ago while we were driving around looking for El Tapatio (a restaurant to avoid), we discovered there was a new Indian restaurant across the street from Flatirons Mall. Azitra is clearly aiming at providing a more upscale Indian restaurant. The decor is elegant earth tones, no wall hangings with elephants here. The usual dishes are on the menu but usually with some twist. And there is no buffet. Overall, we enjoyed the dinner but we aren't quite sure about the restaurant so we will have to visit again before deciding whether to add it to our regular Asian night rotation.<br />
<br />
<b>The Good:</b> The Chatpata Murg appetizer was very good with the pan glaze adding a nice bit of sweetness to to heat of the dish. The little glaze that remained on the dish after the chicken was done made a nice condiment for the naan. My medium heat chicken curry was also nicely balanced. Northern Indian comfort food, the curry was thick, rich, with a nice hint of coconut milk.<br />
<br />
<b>The Bad:</b> Melissa had a mild heat Tandori Chicken Tikka. I don't know why Melissa gets mild dishes in Indian restaurants - she loves Mexican food and good Colorado green chili. Apparently mild at Azitra means flavorless. Our normal strategy at Indian restaurants is to split entrees. After the first bite of hers, I refused to have any more. <br />
<br />
<b>The Ugly:</b> Worst. Chai. Ever. I realize that chai isn't always served as richly spiced as we have become accustomed to in America. We learned that at our numerous means on Brick Lane in London. Still, the chai here tasted completely unspiced. Little more than black tea with cream. And much stronger than I take my team. If your taste in coffee runs to Turkish, you might enjoy the tea here.<br />
<br />
<b>The Scary:</b> Big room that never got full on a Friday night. They've been in this location for 4 or 5 months and I'm not sure whether they will survive or not. The location is not good for a restaurant. Its not actually on the flatirons ring road. Instead it is in the set of building behind near Benihana's. Flatirons is a regular shopping destination for us (and I've eaten at nearby Jason's Deli several times recently) and we had no idea this was here. This plus the fact that they are aiming at a more upscale experience and are correspondingly more expensive than the usual Indian restaurant, makes it likely this place is going to struggle. I hope they succeed because Melissa and I would really like to have more Indian options than just Jewel of India (which we like) and Yak and Yeti which we don't.Howard Fearhttp://www.blogger.com/profile/03273633740035650194noreply@blogger.com0tag:blogger.com,1999:blog-2888562166867572381.post-86198803559131258962012-02-05T12:18:00.000-08:002012-02-05T12:18:45.539-08:00On a Jew's View of Muslims in EuropeI have written about this in other forums, but now that I'm maintaining a blog, I thought I would add a post on the topic here. A friend recently forwarded an article that was purportedly published in a Spanish newspaper (although apparently not) with the thesis that European guilt over the Holocaust has led to a too lenient treatment of Muslim immigrants and that effectively trading Muslims for Jews has been a horrible choice.<br />
<br />
Here is my response (slightly modified).<br />
<br />
First, tripe about English schools not teaching the holocaust, is just that. It is well debunked and only dedicated racists are still using it.
<br />
<br />
Second. the description of the Jewish community that was destroyed in the Holocaust is simply wrong. Yes, there was a vibrant and cultured Jewish community in Germany and other Western European countries that was destroyed. They were educated at fine German universities and produced the kind of brilliant thinkers like Einstein and Freud that German universities of the era produced. And this was a tragedy. But they were a small minority of Jews killed in the Holocaust. Most were villagers from eastern Europe. There were more Jews from Poland killed in the Holocaust than Jews from the rest of Europe combined. These communities were not cultured, they did not produce brilliant thinkers. And their destruction was every bit as tragic. Because the murder of a poor subsistence farmer is every bit as tragic as the murder of brilliant scientist when done simply because the victim has a particular race or religion.<br />
<br />
Like all bigots, the Nazis rewrote history to justify their ideology. And that is just what this author does.<br />
<br />
Lumping of all Muslims into a single collective enemy who seeks the destruction of Europe is exactly what the Germans said. Oh wait, that was the Jews who were bent on the destruction of Europe. The Jews who were cultural poison. I won't claim to know much about Islamic immigrant communities in Europe, but I can speak to the ones here. They have been surveyed extensively and, survey says, they are much like other American immigrants. Hardworking, patriotic, grateful for the opportunities that America provides. Before 9/11 most were Republicans. The typical Muslim immigrant in America is no more extremist than my grandfather was.<br />
<br />
Are there Islamic extremists? Obviously. Saudi Arabia seems to have a national system of education to produce them. There are also Jewish extremists, or have you missed the growing communities of Haredi in Israel. There are Christian extremists too, think Randall Terry or Fred Phelps. To generalize from the small minority of crazy extremists to whole communities is the definition of bigotry.<br />
<br />
In all likelihood, it is true that the Islamic immigrant communities in Europe are poor and dirty. That describes immigrant communities throughout history and across the globe. It is not usually the rich and well educated in society who immigrate, it is the poor and uneducated. We idealize it now, but the lower east side was described in its time as hell on earth and the worst place in the world. And the Jews (and others) who populated were despised by the good citizens of the city. They were excoriated as anarchists and terrorists, as dirty and uneducated, as trash. Immigration laws were rewritten to keep them out. There is nothing said about Muslim immigrants in Europe today that was not said about my great grandparents and their generation in America.<br />
<br />
And if Muslim immigrants get help from the government, so to did the Jewish children of those times who escaped the horrors of the lower east side through the beneficence of a government that invested in public education not just for primary school but also the excellent system of higher education, the City Colleges of New York.<br />
<br />
It is quite simple, the author argues for racism and bigotry. The kind of racism and bigotry that has ostracized Jews in America and around the world and resulted in the murder of 6 million Jews in Europe. As a Jew, I find the use of the Jewish experience to justify bigotry (and, let's face it, racism) to be a particularly odious obscenity. It literally spits on the history of my people and my ancestors and I couldn't find it more offensive. Islam isn't the enemy, bigotry and extremism are.Howard Fearhttp://www.blogger.com/profile/03273633740035650194noreply@blogger.com0tag:blogger.com,1999:blog-2888562166867572381.post-24433484681239814742012-01-24T18:16:00.000-08:002012-01-24T18:16:22.854-08:00On Why Scala is The Perl of JVM LanguagesOne of my first technical jobs was to develop a system in <a href="http://en.wikipedia.org/wiki/APL_(programming_language)">APL</a>. There are two lessons I still carry from that experience: one, I can write any program with fewer characters and two, that doesn't make it a better program. The mark of a great programming language is not the number of characters you can write a program in (see: APL) but how well the language allows the program author communicate with program readers. Is the meaning of sentences and paragraphs of the language obvious or do I have to "work it out."<br />
<br />
Unfortunately, Scala (and most other modern JVM languages) seems to have learned all the wrong lessons from Perl. When I hear programmers make fun of Perl, I understand that they are really making fun of all those unreadable Perl programs they've had the misfortune to have to have read. You didn't have to write programs that way in Perl (and I didn't) but it sure seemed like there were too many $s, @s, bless this, and optional parameters that defaulted to $_ and just what did that evaluate to in the middle of a map.<br />
<br />
And Scala does all of that. Implicit conversions. Methods that use symbols for method names. A type system that used + and -, :< and >: to differentiate covariant and contravariant type and upper and lower type bounds and who even understands what those things are. Semicolons are optional except when they're not. Braces are optional except where they are not and sometimes they become parenthesis. And too many nifty ideas like case classes that don't work with the rest of the language. <br />
<br />
Look, we can all agree that Java suck. I learned object oriented programming in Smalltalk. Java really sucks. And collection classes require functional programming techniques to really work well. I am certain that you can write code in Scala that is more elegant and more expressive than Java. And I am equally certain that you can write code in Scala that makes the typical CPAN library seem like a beacon of clarity. Scala may be a better choice than Java, but that doesn't make it a good language.<br />
<br />
And I like programming in Perl.Howard Fearhttp://www.blogger.com/profile/03273633740035650194noreply@blogger.com0tag:blogger.com,1999:blog-2888562166867572381.post-66675070802139508482012-01-22T12:20:00.000-08:002012-02-05T11:15:25.669-08:00On Why is George Karl Still Coaching?The Nuggets won a close one last night in New York. Playing their fifth game in seven nights and having arrived at 4:00 am, the team was clearly exhausted in the fourth quarter and overtime. This was made worse by the short bench of Coach Karl, he played only seven players. In the back court, this was forced by injuries. But in the front court, this was a result of inexplicable decisions by the coach. While Timofay Mozgov had one of his better games, in what universe is he a better player than Chris Anderson who Karl is increasingly reluctant to play? Here are the per/48 stats:<br />
<br />
<table class="player-stats" style="background-color: #efefef; color: black; font-family: Arial; font-size: 16px; line-height: 20px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; width: 533px;"><tbody style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<tr class="header" style="background-color: #555555; color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><th colspan="11" style="-webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; background-color: #efefef; border-collapse: collapse; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 2px;">Raw Stats</th></tr>
<tr class="header" style="background-color: #555555; color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><td style="border-bottom-color: initial; border-bottom-style: none; border-bottom-width: initial; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px;"></td><td class="stat" style="border-bottom-color: initial; border-bottom-style: none; border-bottom-width: initial; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px; text-align: right; width: 50px;"><a href="http://www.thenbageek.com/players/compare?direction=desc&player_ids%5B%5D=66&player_ids%5B%5D=75&sort=minutes&utf8=%E2%9C%93" style="color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none;" title="Click to sort desc">Min</a></td><td class="stat" style="border-bottom-color: initial; border-bottom-style: none; border-bottom-width: initial; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px; text-align: right; width: 50px;"><a class="current desc" href="http://www.thenbageek.com/players/compare?direction=asc&player_ids%5B%5D=66&player_ids%5B%5D=75&sort=%22WP48%22&utf8=%E2%9C%93" style="background-image: url(http://www.thenbageek.com/assets/sort-arrow-down.png); background-position: 100% 50%; background-repeat: no-repeat no-repeat; color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 18px; padding-top: 0px; text-decoration: none;" title="Click to sort asc">WP48</a></td><td class="stat" style="border-bottom-color: initial; border-bottom-style: none; border-bottom-width: initial; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px; text-align: right; width: 50px;"><a href="http://www.thenbageek.com/players/compare?direction=desc&player_ids%5B%5D=66&player_ids%5B%5D=75&sort=wins_produced&utf8=%E2%9C%93" style="color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none;" title="Click to sort desc">Wins</a></td><td class="stat" style="border-bottom-color: initial; border-bottom-style: none; border-bottom-width: initial; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px; text-align: right; width: 50px;"><a href="http://www.thenbageek.com/players/compare?direction=desc&player_ids%5B%5D=66&player_ids%5B%5D=75&sort=per48_points&utf8=%E2%9C%93" style="color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none;" title="Click to sort desc">PTS</a></td><td class="stat" style="border-bottom-color: initial; border-bottom-style: none; border-bottom-width: initial; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px; text-align: right; width: 50px;"><a href="http://www.thenbageek.com/players/compare?direction=desc&player_ids%5B%5D=66&player_ids%5B%5D=75&sort=per48_defensive_rebounds&utf8=%E2%9C%93" style="color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none;" title="Click to sort desc">DRB</a></td><td class="stat" style="border-bottom-color: initial; border-bottom-style: none; border-bottom-width: initial; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px; text-align: right; width: 50px;"><a href="http://www.thenbageek.com/players/compare?direction=desc&player_ids%5B%5D=66&player_ids%5B%5D=75&sort=per48_offensive_rebounds&utf8=%E2%9C%93" style="color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none;" title="Click to sort desc">ORB</a></td><td class="stat" style="border-bottom-color: initial; border-bottom-style: none; border-bottom-width: initial; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px; text-align: right; width: 50px;"><a href="http://www.thenbageek.com/players/compare?direction=desc&player_ids%5B%5D=66&player_ids%5B%5D=75&sort=per48_rebounds&utf8=%E2%9C%93" style="color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none;" title="Click to sort desc">REB</a></td><td class="stat" style="border-bottom-color: initial; border-bottom-style: none; border-bottom-width: initial; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px; text-align: right; width: 50px;"><a href="http://www.thenbageek.com/players/compare?direction=desc&player_ids%5B%5D=66&player_ids%5B%5D=75&sort=per48_assists&utf8=%E2%9C%93" style="color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none;" title="Click to sort desc">AST</a></td><td class="stat" style="border-bottom-color: initial; border-bottom-style: none; border-bottom-width: initial; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px; text-align: right; width: 50px;"><a href="http://www.thenbageek.com/players/compare?direction=desc&player_ids%5B%5D=66&player_ids%5B%5D=75&sort=per48_turnovers&utf8=%E2%9C%93" style="color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none;" title="Click to sort desc">TO</a></td><td class="stat" style="border-bottom-color: initial; border-bottom-style: none; border-bottom-width: initial; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px; text-align: right; width: 50px;"><a href="http://www.thenbageek.com/players/compare?direction=desc&player_ids%5B%5D=66&player_ids%5B%5D=75&sort=per48_blocks&utf8=%E2%9C%93" style="color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none;" title="Click to sort desc">BLK</a></td><td class="stat" style="border-bottom-color: initial; border-bottom-style: none; border-bottom-width: initial; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px; text-align: right; width: 50px;"><a href="http://www.thenbageek.com/players/compare?direction=desc&player_ids%5B%5D=66&player_ids%5B%5D=75&sort=per48_steals&utf8=%E2%9C%93" style="color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none;" title="Click to sort desc">STL</a></td><td class="stat" style="border-bottom-color: initial; border-bottom-style: none; border-bottom-width: initial; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px; text-align: right; width: 50px;"><a href="http://www.thenbageek.com/players/compare?direction=desc&player_ids%5B%5D=66&player_ids%5B%5D=75&sort=per48_fouls&utf8=%E2%9C%93" style="color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none;" title="Click to sort desc">PF</a></td></tr>
<tr class="player-stats" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 50px;"><a href="http://www.thenbageek.com/players/66-chris-andersen" style="color: #2b60de; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none;">Andersen</a></td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">204</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">.236</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">1.0</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">16.0</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">9.9</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">4.5</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">14.4</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">0.2</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">1.2</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">3.5</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">2.4</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">6.4</td></tr>
<tr class="player-stats" style="background-color: #999999; color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 50px;"><a href="http://www.thenbageek.com/players/75-timofey-mozgov" style="color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none;">Mozgov</a></td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">284</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">.024</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">0.1</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">15.2</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">8.8</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">2.9</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">11.7</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">2.0</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">3.0</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">2.5</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">0.7</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">6.3</td></tr>
</tbody></table>
<br />
<br />
And here are the shooting efficiency stats:<br />
<br />
<table class="player-stats" style="background-color: #efefef; color: black; font-family: Arial; font-size: 16px; line-height: 20px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; width: 533px;"><tbody style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<tr class="header" style="background-color: #555555; color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><th colspan="10" style="-webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; background-color: #efefef; border-collapse: collapse; color: #333333; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 2px;">Shooting Efficiency</th></tr>
<tr class="header" style="background-color: #555555; color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><td class="stat" style="border-bottom-color: initial; border-bottom-style: none; border-bottom-width: initial; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px; text-align: right; width: 50px;"></td><td class="stat" style="border-bottom-color: initial; border-bottom-style: none; border-bottom-width: initial; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px; text-align: right; width: 50px;"><a href="http://www.thenbageek.com/players/compare?direction=desc&player_ids%5B%5D=66&player_ids%5B%5D=75&sort=field_goal_percentage&utf8=%E2%9C%93" style="color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none;" title="Click to sort desc">FG%</a></td><td class="stat" style="border-bottom-color: initial; border-bottom-style: none; border-bottom-width: initial; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px; text-align: right; width: 50px;"><a href="http://www.thenbageek.com/players/compare?direction=desc&player_ids%5B%5D=66&player_ids%5B%5D=75&sort=two_point_percentage&utf8=%E2%9C%93" style="color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none;" title="Click to sort desc">2FG%</a></td><td class="stat" style="border-bottom-color: initial; border-bottom-style: none; border-bottom-width: initial; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px; text-align: right; width: 50px;"><a href="http://www.thenbageek.com/players/compare?direction=desc&player_ids%5B%5D=66&player_ids%5B%5D=75&sort=three_point_percentage&utf8=%E2%9C%93" style="color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none;" title="Click to sort desc">3FG%</a></td><td class="stat" style="border-bottom-color: initial; border-bottom-style: none; border-bottom-width: initial; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px; text-align: right; width: 50px;"><a href="http://www.thenbageek.com/players/compare?direction=desc&player_ids%5B%5D=66&player_ids%5B%5D=75&sort=free_throw_percentage&utf8=%E2%9C%93" style="color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none;" title="Click to sort desc">FT%</a></td><td class="stat" style="border-bottom-color: initial; border-bottom-style: none; border-bottom-width: initial; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px; text-align: right; width: 50px;"><a href="http://www.thenbageek.com/players/compare?direction=desc&player_ids%5B%5D=66&player_ids%5B%5D=75&sort=e_field_goal_percentage&utf8=%E2%9C%93" style="color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none;" title="Click to sort desc">eFG%</a></td><td class="stat" style="border-bottom-color: initial; border-bottom-style: none; border-bottom-width: initial; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px; text-align: right; width: 50px;"><a href="http://www.thenbageek.com/players/compare?direction=desc&player_ids%5B%5D=66&player_ids%5B%5D=75&sort=true_shooting&utf8=%E2%9C%93" style="color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none;" title="Click to sort desc">TS%</a></td><td class="stat" style="border-bottom-color: initial; border-bottom-style: none; border-bottom-width: initial; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px; text-align: right; width: 50px;"><a href="http://www.thenbageek.com/players/compare?direction=desc&player_ids%5B%5D=66&player_ids%5B%5D=75&sort=per48_field_goal_attempts&utf8=%E2%9C%93" style="color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none;" title="Click to sort desc">FGA</a></td><td class="stat" style="border-bottom-color: initial; border-bottom-style: none; border-bottom-width: initial; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px; text-align: right; width: 50px;"><a href="http://www.thenbageek.com/players/compare?direction=desc&player_ids%5B%5D=66&player_ids%5B%5D=75&sort=per48_threes_attempted&utf8=%E2%9C%93" style="color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none;" title="Click to sort desc">3FGA</a></td><td class="stat" style="border-bottom-color: initial; border-bottom-style: none; border-bottom-width: initial; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px; text-align: right; width: 50px;">PPS</td><td class="stat" style="border-bottom-color: initial; border-bottom-style: none; border-bottom-width: initial; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px; text-align: right; width: 50px;"><a href="http://www.thenbageek.com/players/compare?direction=desc&player_ids%5B%5D=66&player_ids%5B%5D=75&sort=per48_free_throw_attempts&utf8=%E2%9C%93" style="color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none;" title="Click to sort desc">FTA</a></td></tr>
<tr class="player-stats" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><td style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left;"><a href="http://www.thenbageek.com/players/66-chris-andersen" style="color: #2b60de; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none;">Andersen</a></td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">51.2%</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">51.2%</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">0.0%</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">66.7%</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">51.2%</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">57.8%</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">10.1</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">0.0</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">1.58</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">8.5</td></tr>
<tr class="player-stats" style="background-color: #999999; color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><td style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left;"><a href="http://www.thenbageek.com/players/75-timofey-mozgov" style="color: white; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none;">Mozgov</a></td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">52.1%</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">52.1%</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">0.0%</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">73.7%</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">52.1%</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">55.3%</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">12.3</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">0.0</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">1.23</td><td class="stat" style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; width: 50px;">3.2</td></tr>
</tbody></table>
<br />
<br />
By the stats, Anderson is not just a better player, he is a MUCH better player. And he can't get off the bench in a game where the team is playing tired? A game where they were giving up second and third attempts because they were too tired to rebound. Really? <br />
<br />
The Nuggets are an interesting team this year, a team of a bunch of good but not great players. The only clearly bad player on the team is Mozgov who is a Doug Moe big stiff. He's 7'1" and can't rebound. This team will go only as far as George Karl's personal decisions allow, which is apparently not very far at all.Howard Fearhttp://www.blogger.com/profile/03273633740035650194noreply@blogger.com1tag:blogger.com,1999:blog-2888562166867572381.post-67720993728869929582011-12-06T19:54:00.001-08:002011-12-06T20:23:09.687-08:00On The Existence of Job CreatorsJob creators do not exist. Jobs result from a functioning employment market. Full employment simply means that the market is clearing. If your business goes out of business, another will form in its place and employ your displaced workers. When the market clears, there are no special people who can create more jobs and clearing is a function of the condition of the market.<br />
<div>
<br /></div>
<div>
There are systemic factors that may prevent the market from clearing. Conservatives would point to the minimum wage and business regulation. Liberals would look at aggregate demand. And both would consider the money supply. But markets never fail because there aren't enough people willing to try to make money by hiring others<br />
<div>
<br /></div>
<div>
At best, the people who claim to be job creators could be productivity enhancers. Companies succeed, at least in part, by improving the productivity of their employees. And, improving the productivity of employees makes their labor worth more which eventually results in rising wages. Judging by the trajectory of the wages of American workers over the past 20 years, it would appear unlikely that we are fostering many productivity enhancers these days either. </div>
</div>Howard Fearhttp://www.blogger.com/profile/03273633740035650194noreply@blogger.com1tag:blogger.com,1999:blog-2888562166867572381.post-59793525485446656872011-11-15T16:36:00.001-08:002011-12-06T20:24:13.960-08:00On Why Are We Testing AnywayThe paradox of testing is, if <a href="http://hsfear-commentaries.blogspot.com/2011/10/on-many-meanings-of-testing.html">testing</a> has <a href="http://hsfear-commentaries.blogspot.com/2011/11/on-limited-value-of-traditional.html">such limited value</a> why do companies that produce great software do so much of it? If testing <a href="http://hsfear-commentaries.blogspot.com/2011/11/on-testing-will-not-solve-your-quality.html">can't really improve quality</a> and doesn't really provide data to decision makers, why do we bother? What is the value of testing?<br />
<br />
In my experience, testing is best understood as a finishing activity, a polishing activity. It is the last few coats of clear paint that make a paint job shine. It is running your hand across the surface of a finished product to find any remaining small burrs that need to be sanded over. It is the attention to detail that differentiates value from junk.<br />
<br />
This understanding of the purpose of testing unlocks the current trends and debates in the test community. It explains why the traditional practice of testing as a planned, designed, and scripted activity is being replaced by rapid testing techniques. If you have lots of the kinds of bugs that are uncovered by traditional "systemic" testing techniques, then testing can do nothing for you. But, if you have done your development well, the kind of intelligent investigation that characterizes exploratory testing can uncover the problems you have missed. <br />
<br />
Is testing dead? If your business model does not require polished products, it may be. When Alberto Savoia or James Whittaker talk about how testing can be replaced by pretotyping, dogfooding, or beta testing, they are really just saying that Google's business model doesn't require polished products. For Google, it is more important to get customer feedback on the software's functionality than it is to get the software just right. And that may be true for some software on the web just as it is surely not for software that, for example, is embedded in a device. <br />
<br />
This does suggest that as companies begin to understand the real value of testing, they will have fewer but better testers. And this explains why outsourcing testing has not produced the expected benefits. If you are trying to replace an intelligent exploratory tester with a phalanx of testers for whom testing is the script and nothing but the script, you get little value from it.<br />
<br />
Testing, at least the kind of system level testing done by testers after development is "done," is part of the zen in the art of software development. It is the attention to detail that differentiates software that users love from software that merely meets needs.<br />
<br />
<br />
<br />Howard Fearhttp://www.blogger.com/profile/03273633740035650194noreply@blogger.com0tag:blogger.com,1999:blog-2888562166867572381.post-10262370999863720862011-11-04T09:03:00.000-07:002011-11-17T14:12:02.269-08:00On Testing Will Not Solve Your Quality ProblemsI remember a conversation that I had with my Linear Algebra professor when I was in college about his class. He said it was a classic example of a double humped class. For half the class, he could teach the material twice as fast and it wouldn't be a problem. For the other half of the class, however, he could spend twice the amount of time and they still wouldn't succeed.<br />
<br />
In economics, they refer to this as <a href="http://en.wikipedia.org/wiki/General_equilibrium_theory">multiple equilibria</a>. I believe that software quality has two equilibria. We have understood for a decades now the types of practices that are needed to develop working software. Whether it takes the form of code reviews, pair programming, or a gatekeeping committer, every line of code needs to be seen by multiple pairs of eyes. Whether by convention or test driven means, you need need comprehensive unit tests. Since code evolves, you need automated tests that cover the code to tell you when changes have had unexpected effects.<br />
<br />
Creating working software requires the disciplined and diligent use of these techniques. It requires both intention and effort. It is, as a result, subject to <a href="http://en.wikipedia.org/wiki/Broken_windows">Broken Windows</a> effects. When you start to loosen your practices, you send the message that quality is not a goal and create an environment where the number of quality problems begins to escalate.<br />
<br />
When managers try to solve quality problems by doing more testing, they are really trying to avoid the cost of reaching the "working software" equilibria. Unfortunately, the same lack of attention to quality that created the problems, sabotages our efforts to fix them as well. Trying to take the cheap way out reinforces the social norm that quality is not really that important for developers. We are simply unable realize a specific level of quality by dialing up or down our quality practices. And testing alone will not enable us to reach the working software equilibria.<br />
<br />
Testing will not solve your quality problems.<br />
<div>
<br /></div>
<br />
<br />Howard Fearhttp://www.blogger.com/profile/03273633740035650194noreply@blogger.com0tag:blogger.com,1999:blog-2888562166867572381.post-11949458299425853182011-11-02T05:47:00.000-07:002011-12-06T20:23:54.052-08:00On The Limited Value of Software Testing<span class="Apple-style-span" style="font-size: small; text-align: left;"><span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">In a recent </span><a href="http://www.developsense.com/blog/2011/09/testing-problems-are-test-results/"><span style="background-color: transparent; color: #000099; font-family: Arial; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">article</span></a><span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">, Michael Bolton discussed how testing problems like too few testers, too little time for testing, or unstable test builds are really test results. And, while I agree with him, this crystallized a question that I’ve been dancing around for some time now. I’ve been involved with software testing for almost 30 years and the problems </span></span><span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">Michael </span><span class="Apple-style-span" style="font-family: Arial; font-size: 15px; text-align: left; white-space: pre-wrap;">mentioned are the same ones we were complaining about 30 years ago. How can this be? Its not as if we don’t know how to do better. </span><br />
<div style="background-color: transparent;">
<div>
<span class="Apple-style-span" style="font-family: Arial; font-size: 15px; font-weight: normal; white-space: pre-wrap;"><br /></span></div>
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Unlike Dilbert, I can't simply lay all problems at the feet of pointy haired bosses. If the same result happens year after year, across companies, across industries, and across countries, there must be some deeper principle at work. Economics, another of my interests, suggests that that the answer lies in looking at how scarce resources are allocated to produce value. If we consistently fail to apply resources to an activity, perhaps it doesn't really have the value we think it does.</span><br />
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><br /></span><br />
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">What is the value of software testing? As I have previously discussed, <a href="http://hsfear-commentaries.blogspot.com/2011/10/on-many-meanings-of-testing.html">testing has many meanings</a>. </span><span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;"> </span><span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">While </span><span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">some of these are pretty thought provoking, I believe that the people who hire testers expect their primary</span><span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;"> value to come from executing the software with the goal of finding bugs. </span><span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> (T</span><span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">hat many of the alternate meanings appear to have been created by testers to convince management that they provide value in other ways </span><span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">may well prove my point.). A lot of testing is done by a lot of people but I'm talking about the kind of testing done by testers. Testing at the system level with the goal of finding bugs. Testing that is t</span><span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">raditionally done at the end of the release cycle although agile groups do a better job distributing it throughout the cycle. </span><br />
<span class="Apple-style-span" style="font-family: Arial;"><span class="Apple-style-span" style="font-size: 15px; white-space: pre-wrap;"><br /></span></span><br />
<span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">And what is the value of finding bugs? In theory, finding bugs should allow us to deliver better products to our customers or at least make better decisions about those products. In practice, however, we fail to accomplish these goals and even when we do, it is generally not using the bugs we find from testing.</span><span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;"> And if we don't really benefit from the effort spent finding bugs, perhaps managers are acting rationally, if not always consciously, by not investing more in testing.</span><br />
<span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;"><br /></span><br />
<span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">How is it that finding bugs fails to result in better products or better decisions? Here lies the heart of the issue.</span><br />
<span class="Apple-style-span" style="font-family: Arial;"><span class="Apple-style-span" style="font-size: 15px; white-space: pre-wrap;">
First, I hope that we all understand that you can't find all the bugs. There is simply no such thing as complete testing. We build complex systems that interact with complex environments. </span></span><span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">You can't even find all the interesting bugs. To believe otherwise is hubris. The resource constrained environments in which we work force us to make decisions about the testing that we won't do and the bugs that we won't find. If you are in the software business, you are, at least in part, in the business of delivering bugs to your customers.</span><br />
<span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;"><br /></span><br />
<span class="Apple-style-span" style="font-family: Arial;"><span class="Apple-style-span" style="font-size: 15px; white-space: pre-wrap;">Your ability to find bugs is even effected by the quality of the software you're testing . When the software is buggy, testing is hard. Builds fail. You start to explore one failure and get sidetracked on a completely different failure. The time spent investigating and reporting bugs eats into the time that was supposed to be spent testing. </span></span><span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">Even worse, software bugs have the strange property that the more bugs you find, the more bugs remain to be found.</span><span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;"> Buggy software ends up being tested less effectively simply because it it buggy software.</span><br />
<span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;"><br /></span><br />
<span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">Finding the bugs doesn't actually improve the software, you also have to fix them.</span><span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;"> And the kinds of teams that write buggy software are the kinds of teams that have problems fixing them. Finishing the functionality that didn't get completed on schedule takes precedence over fixing bugs. Deeper design and architectural problems are patched over because they would take too long to fix. As</span><span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;"> </span><span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">the release date nears and</span><span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;"> the number of bugs mounts</span><span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">, the time spent debugging gets condensed making fixes less likely to work. Eventually, the whole process comes to a halt as we give up and deliver the remaining bugs to our customers.</span><br />
<span class="Apple-style-span" style="font-family: Arial;"><span class="Apple-style-span" style="font-size: 15px; white-space: pre-wrap;">
</span></span><br />
<span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">You can't get working software by starting with buggy software and removing the bugs one by one.</span><br />
<span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;"> </span><br />
<span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">In the end, the quality of the software after testing is much the same as the quality of the software before testing started. Yes, some bugs get fixed before being found by customers and that is a good thing. This explains why we invest in testing at all. But software that was buggy when we started testing is still buggy. when we finish. Good software needs less testing and the testing finds fewer bugs that need to be fixed. For buggy software, testing is less effective and the kinds of teams that write buggy software are the kinds of teams that can't get the bugs fixed. Whether you find only a small number of bugs or you can't fix the ones you do, the value of finding bugs is limited.</span><br />
<span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;"><br /></span><br />
<span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">The lack of real improvement in the quality of software as a result testing was recognized long ago. So testers changed the goal. Instead of making the software better, testing would allow managers to make better decisions about whether and when the software would be released. Unfortunately, it turns out that decisions aren't really made this way. P</span><span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">ersonal and organizational considerations trump data in any complex corporate decision.</span><span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;"> Particularly for the types of organizations that produce software that should be shelved or substantially delayed because of quality problems.</span><br />
<span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;"><br /></span><br />
<span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">In the typical organization, testing happens near the end of the release cycle. By that time, expectations about the delivery of the software have been set. Managers are rewarded for meeting commitments and making dates. As the testing progresses, the cost to the decision maker of missing the date escalates. </span><span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;"> </span><a href="http://en.wikipedia.org/wiki/Sunk_cost_fallacy#Loss_aversion_and_the_sunk_cost_fallacy" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">Loss aversion and the sunk cost fallacy</a><span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;"> kick in. It becomes almost impossible to choose not to deliver the software at least not without significant personal risk. Even significant delay has a cost. The inertia of a release date makes it really hard to miss. Its easier to just make the date and plan the maintenance release. And there are significantly fewer consequences. </span><br />
<span class="Apple-style-span" style="font-family: Arial;"><span class="Apple-style-span" style="font-size: 15px; white-space: pre-wrap;"><br /></span></span><br />
<span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">The whole notion that testing can tell you when software is ready to be released is flawed. It depends on software improving through the testing process and, as a result, being able to project when it will reach some level of quality that we can release. However, software doesn’t really get better through the process of testing. Buggy software never reaches an improved level of quality. The question can’t be when software will reach the level of quality we want to release, but whether we are willing to release the software with the level of quality it has.</span><br />
<br />
<span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">We could increase the value of the bugs we find by using them to improve how we develop software. That is usually how teams learn to develop good software. This is one of the key advantages of effective agile teams. It is my experience, however, that the quality of the software directly reflects the well-being of the team that creates it. Teams that create lots of bugs turn out to be the kinds of teams that are unable to learn from them.</span><br />
<br />
<span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">In the final analysis, the value we get from finding bugs is limited. Teams that create good software get good value from the bugs they find by removing them and learning from them. But, since there are few bugs to be found, the cost of finding them is expensive and the value is limited. Teams that create buggy software face the opposite problem. Its easy (and cheap) to find bugs, but these kinds of teams are incapable of using them effectively. So the value is limited. </span><br />
<span class="Apple-style-span" style="font-family: Arial;"><span class="Apple-style-span" style="font-size: 15px; white-space: pre-wrap;"><br /></span></span><br />
<span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">Spending more money on testing won't change that. If you want to deliver good software, you have to write good software. Yes, testers contribute to the quality of the software in more ways than just finding bugs. But, it turns out that finding bugs has only a limited impact on quality. </span><span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">If I asked you to invest in improving the quality of your software, you would almost certainly get better results by improving how you write the software not how you test it.</span><br />
<span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;"><br /></span><br />
<span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;">Tom Gilb calls testing "as a last, desperate attempt to assure quality." Viewed this way, we can reconcile why organizations both invest and under-invest in testing. We can set expectations that are appropriate and can be met. And we can develop ourselves and our profession to best meet those expectations.</span><br />
<br />
<div style="font-family: 'Times New Roman'; font-size: medium; white-space: normal;">
<br /></div>
</div>Howard Fearhttp://www.blogger.com/profile/03273633740035650194noreply@blogger.com0tag:blogger.com,1999:blog-2888562166867572381.post-41069695259374040752011-10-25T13:03:00.000-07:002011-10-25T13:03:26.742-07:00On "Why didn't you find this bug?"The question "Why didn't you find this bug?" is an organizational smell. It reflects fundamental problems with way your organization thinks about testing and quality.<br />
<br />
First, as Dawn Haynes points out, this isn't a "you" question, it is a "we" question. The "you" divides the team. A team that is functioning well, has collective ownership for delivering code that works and for the techniques used to remove bugs. When you ask why "We didn't find this bug?", you open up the range of possible answers.<br />
<br />
The question is usually asked in the context of "Why didn't you (tester) find this bug (when doing the feature/system/acceptance testing of the software)? Notice the embedded assumption that regardless of how the software is written, by testing at the end, we should be able to remove all bugs. If you expect to remove all problems by testing, you will be sadly mistaken. Even when the test you planned should have caught the bug, the execution often does not go as planned because the software was delivered late or wasn't really ready to test. Its a classic case of an unrealistic expectation that we usually undermine anyway. <br />
<br />
But the real problem is that the question"Why didn't you find this bug?" is usually asked to avoid having to answer the question that really matters, "Why did we write the bug in the first place?" The answer to this question requires reflection and creates the responsibility to learn which is, perhaps, why organizations would choose to avoid it. Better to imply blame and make you-know-who get better.<br />
<br />
Until we really understand how we created the bug in the first place, we can't answer the question that really matters, "What is the cheapest thing we can do to prevent us from delivering software with this bug again?" Since testing is one of the most expensive and least reliable of the techniques we use to remove bugs, the answer often lies elsewhere. If you don't take steps to prevent the bug from being written in the future, you are giving permission to make it again. And since we shouldn't count on testing to find it in all its future occurrences, we are giving permission to deliver it again as well.Howard Fearhttp://www.blogger.com/profile/03273633740035650194noreply@blogger.com0tag:blogger.com,1999:blog-2888562166867572381.post-6747619604426007462011-10-14T21:26:00.000-07:002011-10-16T07:59:34.729-07:00On BugsAnother debate in the Test community is what the appropriate response should be to bugs found during testing. One camp believes that not all bugs should necessarily be fixed. As bugs are filed, some representative of the business (product owner, product manager, etc.) prioritizes them and determines which bugs should be fixed. In many organizations, this is accompanied by test exit criteria expressed in terms of bugs that remain open: no high priority bugs, and some number of of lower priority bugs. This is also often accompanied by a queue of bugs to be fixed due to the delay introduced to prioritizing them.<br />
<br />
A different school believes that all bugs should be fixed. Immediately. When a bug comes in, work on some new feature stops and a developer is assigned to fix the bug. In this way, software is ready to release when the functionality is done. This paragraph is shorter, because the rule is a simpler even though it usually produces the response that you can't possibly fix all your bugs when you develop software.<br />
<br />
Finally, the agilists seems to straddle both camps. Produce no bugs but let the business prioritize the ones you do.<br />
<br />
Personally, I believe that no bugs is the most responsible position. First, let me be clear, when I talk about bugs, I mean the kinds of issues where the software does not do what it is supposed to do or fails in ways that the user would consider an error - like going down or destroying data. Software has lots of other kinds of issues. Sometimes it does what is it supposed to do but what it is supposed to do is not actually useful. Sometimes, it does what it is supposed to do, but in too complicated a way. Bugs, however, are developer errors that should be fixed.<br />
<br />
When you hand over the responsibility for determining whether a bug gets fixed to the business, you assume that the incorrect behavior is the only reason to fix a but. Its not. One thing we know about bugs is that they cluster. Finding one increases the likelihood that there are others that we haven't found yet. And these other bugs may be worse than the one we found. Counting on further testing to find them? That's just playing Russian roulette. I've tried one chamber and its empty and then another and its empty, that must mean all the chambers are empty, right? You can't prioritize bugs by their symptoms, you need to understand their causes. Which means you need to do the hard bit anyway, you need to debug the bug. Every bug. <br />
<br />
Debugging bugs has another benefit, it teaches developers how to stop coding them. It is a strange property of software development that while we try to avoid coding the same solution twice, we use the same programming patterns over and over again. The consequence of this is that any mistake a programmer makes is likely to be repeated over and over again. We found this bug, won't testing find all those others? That's just another game of Russian roulette. You can't find all the bugs, you can't even find all the important ones. So you had better learn to stop creating them. <br />
<br />
Finally, a bug is a <a href="http://en.wikipedia.org/wiki/Broken_windows">broken window</a>. When you don't fix it, when you have other bugs that you also don't fix, you are creating a social norm that bugs aren't all that important. That working software is not all that important. And when you tell developers that working software is not important, you damage <a href="http://www.despair.com/med24x30prin.html">their morale and effectiveness as a team</a>. I do not believe that this is a choice that the business gets to make. Agile, at least Scrum and XP, make the distinction between decisions that the business gets to make and decisions that engineering gets to make. The business does not get to make decisions about the engineering process and question of whether or not to fix bugs is an engineering process decision. It makes no more sense to have the business choose which bugs to fix than it does to have the business choose whether to do test driven design or choose which code review issues to address,<br />
<br />
That's fine in theory, you may say, but it can't work in practice. Let me ask you this. I often hear the complaint that there aren't enough test resources. Most companies have one tester for every 3, 4, or more developers. How is it that one testers is finding more bugs than those 3, 4, or more developers can fix? Could it be because the software contains too many bugs that are too easily found? Not being able to fix all the bugs that testers find reflects deeper problems on the team. Prioritizing bugs won't fix those problems, although it may allow them to linger. It is a crutch that teams use to avoid having to improve.<br />
<br />
You may think that you can't commit to fixing all the bugs. Others in the industry would disagree. Jeff McKenna, one of the founders of Scrum discussed fixing all bugs in a recent <a href="http://vimeo.com/23608644">video interview</a>. Joel on Software discussed Microsoft adopting a zero defects methodology in his <a href="http://www.joelonsoftware.com/articles/fog0000000043.html">12 Steps to Better Code</a>. In "The Art of Agile Development," James Shore discusses several XP projects that adopted a no bugs philosophy. If these teams can do it, so can yours.<br />
<br />
<br />Howard Fearhttp://www.blogger.com/profile/03273633740035650194noreply@blogger.com2tag:blogger.com,1999:blog-2888562166867572381.post-28109394479877639672011-10-10T19:45:00.000-07:002011-11-02T14:37:56.772-07:00On The Many Meanings of TestingI have long been frustrated by the many different meanings that people have for the word testing. The past few days have added several more. These differences in understanding add to the adamance of our positions and occasional rancor of our discussions. So, for discussions on this blog at least, I wanted to set down the definition of testing that I use.<br />
<br />
One of the definitions of testing that I learned recently was that (and I'm paraphrasing here because I don't remember the exact wording) testing includes any inquiry that we make that gives us information about the product. For clarification, I asked "does that include code reviews." "Yes" was the answer. "OK, how about attending a staff meeting?" "If it tells you something about the product." While I appreciate the attention on larger quality issues, I think there is value in distinguishing between the act and impact of inquiring through the execution of the software and other forms of inquiry. The power of techniques like exploratory testing come from running the software and looking at and being effected by the results. <br />
<br />
If testing involves executing software, does that mean that any time you are executing software (before release at least) that you are testing? In one sense, certainly. But, again, I think this serves only to muddy the issue. Some characteristics of a system simply cannot be engineered without executing the system. All the modeling in the world won't identify all the bottlenecks in your system. Usability, too, can only be achieved through a process of trial and improvement. There are many organizations where these kinds of efforts are done by specialist engineers and not by those having the role of tester.<br />
<br />
The testing that we increasingly do to prevent errors falls into this category as well. Test Driven Design and Acceptance Test Driven design are great methods for engineering software (in the small and large) that does what it is supposed to do. But when you introduce these topics to testers, you meet a great deal of resistance. Certainly not because the methods don't improve quality. We can all agree that they do. It seems to me, that the more likely reason is because these methods simply don't accomplish the ends that testers believe they are responsible for. <br />
<br />
Enough already,The definition of testing I use is this: testing is the act of executing software in order to find bugs. This is the essentially the definition that Glen Myers gave us many years ago and is the definitions that I believe would find the greatest degree of acceptance among test practitioners. We test to find bugs and these bugs are a big part of our value.<br />
<br />
That's not do say that bugs are our only value. In a <a href="http://hsfear-commentaries.blogspot.com/2011/10/on-buts.html">previous post</a>, I discussed the notion of contrarianism. Every team needs a skeptic to puncture the generally optimistic group think that infects teams. We also provide additional perspective on the value of the functionality that is being implemented and the usability of that implementation. We make teams think about what they are doing before they rush headlong into implementation. We do all these things, but they are not the act of testing that defines us.<br />
<br />
I hope this helps to make sense of my ramblings and establishes a foundation for future conversations.Howard Fearhttp://www.blogger.com/profile/03273633740035650194noreply@blogger.com2tag:blogger.com,1999:blog-2888562166867572381.post-56631623505368480852011-10-09T15:57:00.000-07:002011-10-09T15:58:40.608-07:00On Buts<span class="Apple-style-span" style="background-color: white; color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 16px;"></span><br />
<div class="header" style="color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 2px; padding-left: 0px; padding-right: 0px; padding-top: 0px; word-wrap: break-word;">
<h2 class="me" style="color: black; display: inline; font-family: 'Arial Unicode MS', Arial, Helvetica, sans-serif; font-size: 18px; font-weight: bold; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
con·trar·i·an</h2>
<sup style="bottom: 1ex; color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; height: 0px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; position: relative; vertical-align: baseline;"></sup> <span class="pronset" style="color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><span class="show_spellpr" style="color: #333333; display: inline; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><span class="prondelim" style="color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">[</span><span class="pron" style="color: #333333; display: inline; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">k<span class="ital-inline" style="color: #333333; display: inline; font-family: Georgia, Verdana, Arial, Helvetica, sans-serif; font-size: 13px; font-style: italic; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">uh</span><img alt="" border="0" class="luna-Img quimby_search_image" src="http://sp.dictionary.com/dictstatic/dictionary/graphics/luna/thinsp.png" style="background-attachment: scroll; background-clip: initial; background-color: transparent; background-image: url(http://sp.dictionary.com/en/i/dictionary/newserp/Sprite_Serp.png); background-origin: initial; background-position: -491px -482px; background-repeat: repeat repeat; border-bottom-width: 0px; border-color: initial; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-style: initial; border-top-width: 0px; color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: text-top;" />n-<span class="boldface" style="color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; font-weight: 700; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">trair</span>-ee-<span class="ital-inline" style="color: #333333; display: inline; font-family: Georgia, Verdana, Arial, Helvetica, sans-serif; font-size: 13px; font-style: italic; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">uh</span><img alt="" border="0" class="luna-Img quimby_search_image" src="http://sp.dictionary.com/dictstatic/dictionary/graphics/luna/thinsp.png" style="background-attachment: scroll; background-clip: initial; background-color: transparent; background-image: url(http://sp.dictionary.com/en/i/dictionary/newserp/Sprite_Serp.png); background-origin: initial; background-position: -491px -482px; background-repeat: repeat repeat; border-bottom-width: 0px; border-color: initial; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-style: initial; border-top-width: 0px; color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: text-top;" />n</span><span class="prondelim" style="color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">]</span></span></span></div>
<div class="body" style="color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0em; margin-left: 0em; margin-right: 0px; margin-top: 0em; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div class="pbk" style="color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<span class="pg" style="color: #333333; display: inline; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; font-style: italic; font-weight: bold; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 3px; padding-top: 0px;"><span id="hotword" style="color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; position: static;"><span id="hotword" name="hotword" style="color: #333333; cursor: default; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; position: static;">noun</span></span></span><br />
<div class="luna-Ent" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; background-position: initial initial; background-repeat: initial initial; color: #333333; display: block; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 1em; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 5px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<span id="hotword" style="color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; position: static;"><span id="hotword" name="hotword" style="color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; position: static;">a</span> <span id="hotword" name="hotword" style="color: #333333; cursor: default; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; position: static;">person</span> <span id="hotword" name="hotword" style="color: #333333; cursor: default; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; position: static;">who</span> <span id="hotword" name="hotword" style="color: #333333; cursor: default; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; position: static;">takes</span> <span id="hotword" name="hotword" style="color: #333333; cursor: default; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; position: static;">an</span> <span id="hotword" name="hotword" style="color: #333333; cursor: default; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; position: static;">opposing</span> <span id="hotword" name="hotword" style="color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; position: static;">view,</span> <span id="hotword" name="hotword" style="color: #333333; cursor: default; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; position: static;">especially</span> <span id="hotword" name="hotword" style="color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; position: static;">one</span> <span id="hotword" name="hotword" style="color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; position: static;">who</span> <span id="hotword" name="hotword" style="color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; position: static;">rejects</span><span id="hotword" name="hotword" style="color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; position: static;">the</span> <span id="hotword" name="hotword" style="color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; position: static;">majority</span> <span id="hotword" name="hotword" style="color: #333333; cursor: default; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; position: static;">opinion</span></span><br />
<span style="color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; position: static;"><span name="hotword" style="color: #333333; cursor: default; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; position: static;">[<a href="http://dictionary.com/">dictionary.com</a>]</span></span></div>
<div class="luna-Ent" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; background-position: initial initial; background-repeat: initial initial; color: #333333; display: block; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 1em; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 5px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<span style="color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; position: static;"><span name="hotword" style="color: #333333; cursor: default; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; position: static;"><br /></span></span></div>
<div class="luna-Ent" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; background-position: initial initial; background-repeat: initial initial; color: #333333; display: block; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 1em; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 5px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
'But' is the contrarian word in the English language. No matter what has come before, you know that once you hear 'but', you are about to hear an opposing view. And that opposing view is even more important than the original view that it stands in opposition to.</div>
<div class="luna-Ent" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; background-position: initial initial; background-repeat: initial initial; color: #333333; display: block; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 1em; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 5px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<br /></div>
<div class="luna-Ent" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; background-position: initial initial; background-repeat: initial initial; color: #333333; display: block; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 1em; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 5px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
I recognize the power of 'but' because I have a wide streak of contrarianism. I don't accept ideas, I wrestle with them. If Jacob got a cool new name by wrestling with God, I always feel like I should get a cool new name when I wrestle with an idea. I recognize this streak in others as well. Have you ever had a discussion with someone where it seemed that no matter what you said, their response was to find some point to challenge or some nit to pick? Bingo, contrarian. Progress results from contrarians. They make ideas stronger, more resilient.</div>
<div class="luna-Ent" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; background-position: initial initial; background-repeat: initial initial; color: #333333; display: block; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 1em; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 5px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<br /></div>
<div class="luna-Ent" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; background-position: initial initial; background-repeat: initial initial; color: #333333; display: block; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 1em; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 5px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
Testers are contrarians. We get paid for it. When a developer says "this works," we say "but what about?" This process of applied contrarianism makes software better. It hardens the software, makes it more resilient. Without contrarians on the team, the software would never reach its full potential.</div>
<div class="luna-Ent" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; background-position: initial initial; background-repeat: initial initial; color: #333333; display: block; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 1em; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 5px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<br /></div>
<div class="luna-Ent" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; background-position: initial initial; background-repeat: initial initial; color: #333333; display: block; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 1em; line-height: 1.25em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 5px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
But (there's that word), if you love your children and want them to grow up happy and socially well adjusted, don't let them be contrarians. Teach them the word 'and' instead. 'And' is the ultimate social word. 'And' allows us to work together in harmony to construct a shared idea. So remember to teach your children, don't be a 'but' be an 'and' instead.</div>
</div>
</div>
Howard Fearhttp://www.blogger.com/profile/03273633740035650194noreply@blogger.com1tag:blogger.com,1999:blog-2888562166867572381.post-33288078111645378602011-10-09T10:09:00.001-07:002011-10-09T10:09:34.681-07:00On Risk Based TestingRisk based testing is one of the many testing methodologies that has not delivered promised returns. Its not really hard to understand why. Ordering risks requires knowing two things about each risk: the likelihood of the risk occurring and impact if it does. For software, neither of these is knowable.<br />
<br />
If bugs were distributed randomly, the likelihood of a risk occurring would simply reflect the usage model of the software. But we know that bugs are not distributed randomly. Instead they cluster. They cluster in the code of a particular developer. The cluster in a design that doesn't fully meet its need. They cluster in how an environmental issue is handled across different areas of the software. Bugs cluster for all sorts of reasons. And we can't identify where these clusters are until we have already tested and found the bugs.<br />
<br />
Difficult as the problem of likelihood is, predicting impact is much harder. The severity of a bug may well be random and this randomness thwarts us. The severity of the bug is not related to the importance of the functionality the code implements. Even bugs in remote byways of a system can cause it to crash or corrupt data. The honest answer to the question of what can take the system down is any line of code in it.<br />
<br />
Sure, we find bugs using risk based techniques. We find bugs using any testing technique. Does it really result, though, in the identification and removal of our riskiest bugs? The evidence strongly suggests not.Howard Fearhttp://www.blogger.com/profile/03273633740035650194noreply@blogger.com0tag:blogger.com,1999:blog-2888562166867572381.post-64812327477328718852011-10-08T22:48:00.001-07:002011-10-09T06:55:13.194-07:00On BloggingThe last post is a really good example of why I don't really do this whole blogging thing. Short as that essay is, it still took almost 5 hours of a Saturday to write and I had starting planning it in my head as early as last Tuesday. The people who blog in this industry must be smarter, write better, or have less of a life than even I do. It seems that four or five months after I escape a bad situation, I feel compelled to get my thoughts out on paper as it were. Perhaps it is my way to learn from the experience or just have a catharsis. So get ready for a flurry of activity.Howard Fearhttp://www.blogger.com/profile/03273633740035650194noreply@blogger.com1tag:blogger.com,1999:blog-2888562166867572381.post-14606554427728016542011-10-08T22:47:00.000-07:002011-10-09T06:55:25.215-07:00On STARWest 2011<p>"Agile" is everywhere. Agile, on the other hand, is continues to be adopted only fitfully. For many attendees, agile meant the addition of iterations and standups and not much else. Practitioners seem to understand that this is not actually working so sessions about making agile work were very popular.</p>
<p>The executives who presented during the leadership summit seemed to be really out of touch with agile. You really can't claim to be agile when you have weekly status reports delivered to a central PMO and you had better be making your weekly progress "or else". The contempt for agile by the next speaker was almost dripping. It should come as no surprise that executives are clueless... I mean out of step with the current state of practice.</p>
<p>Pockets of traditional development and test remain. There were several tutorials from SQE instructors that have probably not changed since the early 1990s. This was much less true in the sessions where there were only a couple of sessions from the Military/Industrial/SEI faction.</p>
<p>Acceptance Test Driven Development (ATDD) was a hot topic. I think its supporters fail to do it justice. ATDD changes how we do specification and provides a mechanism for demonstrating that the software has implemented the intended functionality. But fulfilling requirements is not the same as not having bugs. ATDD is a technique for preventing bugs not a technique for detecting them. Practitioners intuitively understand this which accounts for the resistance of many test professionals to ATDD. It is unfortunate because it is unnecessary.</p>
<p>Another source of resistance to ATDD is its often incorrect implementation. Done correctly, ATDD means specifying the story's tests, preferably in an executable framework, and then developing the code to make the tests run one by one. It is TDD in the large. You know what still needs to be completed on a story by the tests that are still failing. In fact, the percentage of passing acceptance tests may be a more accurate measure of progress during a sprint than the hours remaining in the sprint burndown. (I think it would be interesting to put both measures on a single, highly visible, graph.)</p>
<p>Exploratory testing was also popular. It seems fair to say that one theme of the conference is that test cases are out (or at least limited to the things that can be automated) and exploratory testing is in. It is not hard to understand why exploratory testing is so popular. It encourages testers to do more of the testing they most enjoy and best do. It also helps that the practice has charismatic champions and is amenable to easy demonstration. The various exploratory demonstrations in the test lab were surprisingly popular given the limited space and that attending meant missing prepared sessions. Practitioners resistant to ATDD should consider exploratory testing as a complementary practice.</p>
<p>Test automation is something that everyone seems to do but everyone also seems to be dissatisfied with the results and wonders whether they should do more. Tool vendors keep pushing the concept that we can make this easy enough for the business analysts to do so testers won't have to. (Why you would try to sell that message to a room full of testers is beyond me.) Perhaps they should get together with the ATDD folks since their pitches now seem more directed at demonstrating that the functionality was implemented rather than finding bugs. I suspect they spend too much time talking to CIOs. As the vendors work harder and harder to make test automation accessible to non-technical testers, technical testers like me will have more incentive to find other solutions.</p>
<p>I wonder if some of the uneasiness around automation reflects a recognition that we are simply not finding and fixing enough bugs with automated tests. Sure, we find regression issues but these are, or should be, only a small proportion of the bugs. For years, I have talked about the role serendipity plays in finding bugs. You are running a manual test and notice something wrong completely unrelated to the purpose of the test. Automated tests completely fail to find these kinds of problems. (To which the exploratory testing folks would reply, "Of course.")</p>
<p>Mobile devices and cloud computing are new software platforms that were also program topics. Cloud computing offers some real opportunities for testing. Building environments to support realistic performance testing has always been expensive and these environments usually end up underutilized. Cloud computing offers a solution. Environments that can be built to scale when needed and released when not. Cloud computing also presents unique testing challenges. Services built in the cloud use highly parallel architectures that are susceptible to all sorts of concurrency issues which are difficult to test. Testing software for mobile devices seems more familiar. Its really just a configuration problem but the rapid improvement of these platforms means that the number of configurations and the difference in their capabilities is larger than most of us are used to.</p>
<p>Controversy came in the form of James Whittaker's keynote "All That Testing Is Getting in the Way of Quality." In it, he claimed testing was dead. Or, in more subtle terms, that the practice of testing to find and fix bugs had not resulted in significant improvements in software and could, in any case, be done more effectively, thoroughly, and cheaply by crowd-sourcing it. I think we can safely say by the hisses that accompanied any further mention of google and the topics of table conversations over the rest of the week, that he struck some sort of nerve. Since I had entered the conference with that very point of view, it was fascinating to watch the reaction. On this, there will be much more in subsequent posts.</p>
<p>The other question that seemed to be on many minds is "what's new here?" The answer from my part of the world is not much. I believe that James Bach did his original presentation on good enough software and rapid testing in the mid 90's. Agile, too, has passed its 15th birthday. ATDD is new but (perhaps justifiably) is not fully accepted as a test technique by practitioners. The software platforms are new, but the testing challenges are not. </p>
<p>I last attended a STAR conference in 1993. The differences were striking. Sessions had an air of discovery about them. Concepts like risk based testing or model based testing were new and promising. The internet had not yet happened so new information traveled more slowly. Conferences were the conduits where concepts transitioned from IEEE and ACM papers to practitioners. There were more sessions given by researchers from either academic or industrial labs. (Do those kinds of labs even exist anymore - outside of google that is?) Everything was open to investigation. I remember attending one very interesting session on regression test selection. Now we just run 'em all. Another session suggested that we all needed to be doing mutation testing to prove our test sets. And another promised automated test generation from program analysis.</p>
<p>There is a deeper reality here too, one that Dr. Whittaker alluded to. The practice of testing hasn't really changed all that much since the mid-90s. Sure, we've repackaged some of the things that we all knew in, hopefully, more effective forms. Long before ATDD, testers understood that tests were a much better specification than the specs we usually got. I remember suggesting that we just write the specs as tests years ago. Exploratory testing? Have we ever actually not done exploratory testing whether we told our bosses or not? We use the same tools, models, strategies, The design strategies in Lee Copeland's tutorial "Key Test Design Techniques" are the same ones that I learned from Dr. Boris Beizer at STAR in 1992. And the simple fact is that the application of these techniques has not, on the whole, resulted in software that works all that much better. As Dr. Whittaker suggests, the drivers of whatever improvements we've had in software have not come from improvements in testing. They could not, since there haven't really been any improvements in testing. And I believe that the industry is (or should be) entering a period of evolution to diminish the dependence on testing to develop working software. And that is the jumping off point for the posts to come.
</p>Howard Fearhttp://www.blogger.com/profile/03273633740035650194noreply@blogger.com7tag:blogger.com,1999:blog-2888562166867572381.post-11511570081352121662011-10-05T21:25:00.000-07:002011-10-09T06:55:41.714-07:00On "All That Testing Is Getting in the Way of Quality"<p>Dr. James Whittaker's keynote has certainly been the hot topic of conversation at StarWest. Since I may be the only person here who agrees with him, let me share my take.</p>
<p>First, lets be clear that he was talking about "testing" as in the kind of testing done by testers in a testing department. He is not saying that no one will ever again run software to evaluate some characteristic of it. Just that it won't be done by testers as they exist today doing testing as we understand it today.</p>
<p>Second, the improvements in quality that have been made over the past decade do not involved testers testing software. He mentioned several improvements. Some, like better programming practices include using testing in new ways (like TDD). Some, like conformance to standards, involve testing not at all. But, the improvement in quality has not been due to testers using new testing practices. I last attended a STAR in the early 90s and the testing practices we had back then are by-and-large the same ones we use today. Even if they have new fangled names. </p>
<p>Third, he contends that the act executing software to find bugs can be done more cheaply and effectively through crowd-sourcing than by dedicated testers. Yes, I'm sure he knows that not all software is on the web and not all software testing can be replaced by crowd sourcing. But, to echo a comment in a previous session, if you have a software product and you don't think that someone, somewhere is trying to build something on the web to replace it, than you aren't paying attention. (Those are not the embedded systems you are looking for....) </p>
<p>As a result, if your only value comes from running tests to find bugs, you are on the path to obsolescence. Both because people are finding ways to build software that works well enough without doing that kind of testing and because even those companies that will continue to use that use finding and fixing bugs as a development strategy will find cheaper ways to let users do it. Sooner or later they will come take your job away.</p>
<p>The only place I differ is in the rate of change. Googlers tend to see the world changing at the speed of light. I look around and see the continued reliance on obsolete management practices, obsolete software systems and languages, and obsolete development practices, and come to the conclusion that inertia is much more resistent in the face of change that we think. Of course, that doesn't mean that I want to be trapped there.</p>Howard Fearhttp://www.blogger.com/profile/03273633740035650194noreply@blogger.com2