More Effective Studying

I spend a lot of my free time studying computer science.  For about a year and half, I spent about 20 hours/week.  Now I am down to only about 10 or 12.

Historically, I typically studied only one item at a time, whereas I had a friend who would do two or three.  I believe his approach to be better and have adopted it.

When you study a single technical book, all items are not equal.  The earlier items provide a required base for the later items; you have to fully understand and recall them in addition to the later material you are studying.  What helps with that fuller comprehension?  Removal and time.

If I read part A of a book and wait until the next day to read part B, my subconscious mind has a chance to process that material and master it.  Thus, coming back the next day makes reading and comprehending part B all that much easier.  It the same science that allows me to suddenly make connections on problems I have been working on when taking a shower.

Sometimes you may be aware of that processing.  For example, some nights I may recall having intense problem solving dreams around something I am studying as my brain forms new neural networks.  This also works for new video games.

Now, I am studying about five different subjects simultaneously.  Not only is the process less taxing and stressful, but I am mastering it more effectively.

Information Architecture – Part 2

I read about half of the “Information Architecture for the World Wide Web”, and then stopped at that.   Not because it is not a good book; I just don’t plan to become a professional Information Architect.  If I need to go deeper at some point, I’ll read the rest.  All in all, I definitely recommend the book.

Nonetheless, it is really interesting to think about information architecture, organization, structure and search as abstract concept independent of an actual application, as well as applying to the real world of grocery stores, department stores, libraries, etc.

A couple of things really stuck out for me in addition to what I learned in “Don’t Make Me Think”:

There are two main ways to organize based upon the needs of your users:

  • Exact organizational scheme. When the user knows exactly what they are looking for (e.g., white pages)
  • Ambiguous organizational scheme. When users don’t know what they are looking for.  Some types include organizing by task or topic, among other things

Hierarchical organizational structures can be tricky as many things do not neatly fit into a strict taxonomy.  A taxonomy that allows cross-listing is referred to as polyhierarchical.  However, if too much of this takes place, the value of the organization is reduced.

In addition, there is tension between the breadth and depth of the hierarchies.  It is generally better to go for greater breadth, particularly as your site grows.

My knowledge grew the most in the area of search.  I have a friend whose site needs search capability.  I had thought of plugging something in for him for the entire site, and until did not realize the complexities involved in matching the users needs to the search capabilities.

For one, your users may need recall or precision, but they can’t have simultaneously as these are mutually exclusive:

  • Recall. Recall is oriented toward finding a greater number of relevant matches (e.g., doing due dilligence on a company you are considering joining)
  • Precision. Precision is oriented toward finding just a few very high quality matches (e.g., instructions on deck staining)

You will need to configure or choose your search engine accordingly.  In addition, choosing to take advantage of automatic stemming (e.g., using thesauri) in your searching will result in greater recall at the expense of the precision.  Your users’ goals needs to play an important part in this configuration.

In addition, you can choose to index your entire site, or break it up different search zones.  Once again, the former increases recall, while the latter increases precision.

Finally, there are numerous ways and levels of details to provide around search results.  Once again, this will be based upon your users goals.

In the end, you need to really understand your users’ goals to be able to create the appropriate Information Architecture.

Information Architecture – Part 1

Taking a break from development and Agile activities, I have started reading “Information Architecture for the World Wide Web” by Peter Morville & Louis Rosenfeld.  This is part of my attempt to increase the user-oriented side of my skills in addition to more technical web development skills.

The book begins by using an analogy of physical building architecture, which builds nicely on the mental model I started to build up from Steve Krug’s “Don’t Make Me Think”.  Different building architectural styles serve different user purposes, labeling and classification enable users to navigate effectively, and the importance of search.  While there are also similarities with physical libraries, the multi-dimensionalities associated with the web present a different set of problems.

What I found interesting is their discussion on Information Needs and Information Seeking Behaviors.  They discussed four types of Information Needs:

  • The Perfect Catch. You know exactly what you are looking for – someone’s telephone number, a fact about the population of the state of Louisiana, etc.  Basically, you are looking for “the right answer”
  • Information Exploration. You might looking for the best apartment swapping services in Paris, or different investment options in your online 401K service (as I was recently).  There are multiple good matches.
  • Exhaustive Research. You might be doing research for your thesis, or conducting medical research about a disease a friend may have acquired.  You want to leave no stone unturned.
  • Refinding. This is where services like del.icio.us come in handy, or the “Favorites”  link in YouTube

The point is, how you design search capability and organize your site is going to differ vastly for these purposes, and an understanding of how your users will want to use your site will play a major role in your information architecture.  How you organize search, links, content and navigation will either enable or befuddle your users in their goals.  In other words, you want to set things up in such a way that your users do not need to think.

Another thing I found interesting (I am only through Part 1) is the Berry Picking Model by Dr. Marcia Bates of USC:

  1. Start with an information need
  2. Formulate an information request (query)
  3. Move through the site(s) in different ways
  4. Pick up important bits of information (berries)
  5. Refine your query based upon what you already found and repeat

This stuck out because I was just doing this this morning before reading this:

  1. Searching for help on using a particular technique
  2. Finding some helpful articles (and either adding to del.icio.us or Evernote) while browsing then rejecting unhelpful ones
  3. Altering the search query in the hopes that it would offer more links that better fit my need

Finally, even though the product I work on a web-based application as opposed to a site, an understanding of Information Architecture can also be helpful in terms of how we present information and work with user requests.

Talent is Overrated and Deliberate Practice

Recently on the This Week in Tech podcast, I listened to Jason Calicanis extol the book Talent is Overrated.  I picked it up on Audible and listened to it back and forth from work for the past two weeks.

The major premise of the book is that we often grow up with the myth that people either have a talent or they don’t, and that that is what their determines their successful (or its corollary – you must have a great inborn talent and practice).   It vigorously tears down this myth in regard to Mozart, and then Tiger Woods.  In a nutshell, sustained practice is what determines your level of success.  And not just any practice – deliberate practice, which is often not very fun.

It reminded me of “Asians are intrinsically better a math” myth that is debunked in Malcolm Gladwell’s Outliers.  A hard work culture that results in lots of hard work and practice in math, a discipline that requires a lot of practice.  I have shared this with my daughter many times vis-a-vis math as she studies to get into college and become a doctor.  But have I shared it with myself enough?

How many times have you worked with a programming wonderboy and attributed it to a natural talent that very few people have?  How often have you let yourself off the hook due to this?

This last year has been an intense year of deliberate practice for me.  Outside of work, I spend 15-20 hours a week studying computer science – learning new languages, mastering old ones, new OS’s, techniques, technologies, etc.  It has been a lot of deliberate practice, and my skills are far superior to what they were a year ago.

I have also noticed that the more I study, the easier it is to pick up new concepts I come across.

In addition, I have developed an absolute passion for programming that I had not experienced in a while.  All of this is leading to more deliberate practice and greater proficiency, as well as widening of the areas I am interested in and studying.

My latest thing is going through the Ruby Quizzes from Pragmatic Programmers.  I am not doing it to learn Ruby, but to write better Ruby.  The exercise in writing the best Ruby code I can, comparing it to example, and making changes it making me a much better Ruby developer.  I am learning about my strengths and weaknesses as a developer, and focusing on improving those weaknesses instead of doing the same old thing over and over.

Clean Code

I listened to “Uncle Bob” Robert Martin talk about Software Craftsmanship on either the Software Engineering Radio or Pragmatic Programmer podcast.  It got me thinking.  I have been studying a lot of programming languages and technologies lately, but when was the last time I focused on pure coding itself?  I was a like a painter learning about oils, acrylics and water colors – but it was time to focus on the cross-cutting techniques of painting applicable in any medium.

So I picked up his book – Clean Code, and summarized the contents to be able to repeatedly refer back it.  A number of the things he covered I already knew from an earlier study group on Martin Fowler’s Refactoring book.

Understanding it intellectually was not going to be enough so I picked out one of the quizzes from the Ruby Quiz (Pragmatic Programmers) and tried to apply it.  At the same time, I also decided to do full “Orthodox TDD”, where I did not do any development until I had a failing test.  I worked through some design alternatives up front, and then proceeded with the one I liked.

It was slow going.  I tried to be as true to the book as possible, and then meant a lot of refactoring as I thought of new ways to create cleaner code based upon the book.  As much as I like Ruby, Java is definitely an easier language to refactor (but thank heavens for all the unit tests – a necessity in Ruby).  I have seen a book out there on Refactoring in Ruby, and I may pick that one up.

But slow going is okay.  When you study martial arts, you are supposed to go slow as you apply the techniques.  With practice, speed comes later on top of perfect technique.  In this practice scenario, I was doing just that.  This was the major reason I was doing this on a home project as opposed to work, where speed is obviously more important.

More challenging than I expected was creating extremely well named entities – a lot of rename refactoring took place.  Nonetheless, the number of comments I had in my code was extremely small – it was unnecessary as the naming told the story.  I tried to follow his newspaper model of letting my code tell the story in various levels of detail – this worked out well in the end.  Plus, the lack of comments that were not there that typically were “because they are supposed to be” made the code much easier to understand.  It was better, and liberating.

I did struggle with some things.  The breaking down of all the methods into small methods ended up with a lot of lower level methods.  While the methods were extremely cohesive, there were a lot of them.  A good signal to me that I had broken them down into too many sub-methods was the extreme difficulty I had in creating names for them to show their intent without using any type of synonyms.  Based upon that, I recombined some of the methods.

I also struggled with his advice on not using return codes or error codes.  In his statement, if your method performs a state change on the object and returns a return code, it is doing both a state change and a query, violating the cohesiveness of the method.  By throwing an exception instead, the method is more cohesive and the consumer can write less complex code.  Plus, if you refactor complex methods into multiple more cohesive methods, having to check for return codes permeates through each invocation, increasing code bloat.

Nonetheless, this seemed to run against Joshua Bloch’s advice in Effective Java on using Exceptions only for exceptional conditions as well as the overhead associated with them.  I also did not like having to create a new Exception class as this seemed to increase the necessary mental model for code.

Then, I thought on the pattern typically found in Enumerators – a cohesive querying hasNext() method along with a next() method that either returns the next entity or throws an exception if one is not found.  How many API’s had I seen lately where they had been modified to offer a similar query method, or offer variations of methods that either returned an error code or threw an exception.  I am seeing the value, but I am continuing to work through this.

Overall, this is an excellent book to study.  I will continue to apply it as I work with other technologies at home to improve my general coding abilities.

Clean Code and the 5S Principles

I recently listened to “Uncle ” Bob Martin giving a podcast on Software Craftsmanship on Software Engineering Radio, and decided to pick up his book Clean Code – A Handbook of Agile Software Craftsmanship.  I was struck by the forward by James O. Coplien of Denmark on the 5S Principles and how they tied to maintenance instead of production in Total Productive Maintenance (TPM).  Furthermore, these principles as applied to the maintenance floor apply equally well to software:

  • Seiri (organization). You need to be able to find things easily.  In software, proper naming helps you find things easily.
  • Seiton (tidiness; systematize). Everything has its appropriate place.  Code should be where it is expected to be, and if not, refactor to get it there.
  • Seiso (cleaning; shine). Keep the workplace clean for easier thinking (think grease, wires, etc.).  In code, leaving commented-out code and inappropriate comments increases mental clutter that has to be overcome.
  • Seiketso (standardization). The group agrees on how to keep the work place clean.  Consistent coding standards and patterns apply here.
  • Shutsuke (self-discipline). Having the internal discipline to follow the practices and to reflect on one’s work.

If you take a moment to really think about these parallels between the factory maintenance floor and the code we have to work in, these practices that reduce mental clutter on the factory floor apply equally well to developers working with code.  Less clutter means higher productivity and later mistakes.  For me, it was like a light bulb turned on.

One of his major points is that in coding, we spend 90% of our time reading, and only 10% of our time writing.  Thus, what we do to improve the efficiency of reading carries further weight.  Unfortunately, we are measured (subjectively or objectively) in terms of writing productivity, passing the costs on to fellow programmers later on.

It reminds me of what I wrote earlier while musing on Steve Krug’s Don’t Make Me Think as applied to web site design and usability.  By writing clean code, we require later developers to not have to think more deeply than necessary when reading and using our code by reducing misdirection and mental clutter.

I’m on page 21 of the book now, and looking forward to working through it in continuing to improve my own software craftsmanship.

Pragmatic Wetware and The Dreyfuss Model

I saw the Pragmatic Wetware book by Andy Hunt.  “Hmm”, I thought, “a book on the human brain and how it works.  Interesting, but I have too much else to read and study.” Wrong.

Apparently I had missed the pragmatic part of that title.  As I am averaging three to five technical books a month right now, an investment in becoming more efficient in my learning and study would surely pay off.  So, I got the book, and I am glad I did.

Just as you want to be an efficient coder, if you are doing a lot of studying, you want to be an efficient learner.  I will talk about a few of things I found over a few blogs, but I highly recommend purchasing this book and implementing it.

In the Dreyfuss model, there are five levels of progression of mastery in terms of problem solving and the mental models you form:

  • Novice.  They have little experience to rely on, but they can follow context-free rules (recipes) to guide them (think ISP help-desks and pre-canned scripts).
  • Advanced Beginner.  They can break away from context-free rules a little bit and try things on their own, but they do not have a big picture understanding.
  • Competent.  They have developed conceptual domain models and can work with them and solve problems.
  • Proficient.  They can reflect, improve, and learn from the experience of others.  They can apply maxims (as opposed to just recipes) to problems.
  • Expert.  They work from intuition instead of simply reason and are primary sources of information.

Becoming an expert is more than just collecting a body of skills and knowledge; it is about moving to intuition-based problem solving based upon those experiences.

We have a great cookbook that my wife and I pick out a new recipe from to try each week.  I take the recipe, and I follow it carefully (X amount of flour, Y amount of seasoning X, etc.).  A great chef (such as my grandmother) did not follow a recipe – it was based on intuition gained over experience (a pinch of this, adjust it this much because of the humidity, etc.).  I tried to ask my grandmother once how to make something, and she couldn’t really articulate her responses beyond “add a little bit of this” and “cook it until its ready but not too long”.  This is the typical mark of an expert.

What does this mean in terms of coding?  Well, it means becoming an expert is a little less about collecting skills and more about applying skills intuitively given a particular context.  Any fool can apply a parade of various design patterns (I recall being one of those fools 13 years ago), but an expert will intuitively apply the right pattern given a particular context.  That seriously shifted my paradigm when I read it.

Personally, I have a backlog of skills I am studying and investing in to increase my knowledge and skills portfolio.  However, I plan to spend a lot more time going forward on context.  One of the things I will soon be doing is personally reviewing my entire technical career to determine what I did and did not do right given the particular contexts I was working in.  Am I repeating any poor patterns, what should I continue, what should I drop?  I expect it to be a worthwhile exercise.