Semi-bluffing your interview

Posted about 1 year back at Jay Fields Thoughts

Over the past two and a half years I've interviewed several ThoughtWorks candidates. These days I tend to put people into 3 categories when interviewing them: Gross Exaggerator, WYSIWYG, and the Semi-bluffer.

The Gross Exaggerator
Being a Gross exaggerator is never a good idea. Your resume is the first clue. I've yet to meet anyone who's an expert* with .net, Java, Ruby, Smalltalk, and Lisp. There's just not enough hours in the day to actually be an expert in each language. Anyone with several buzzwords on their resume signals two things to me: They likely have no idea what they don't know, and they aren't picky enough about technologies they are willing to work with.

I took C in college also, but one semester of Data Structures does not an expert make. I did Java at my first job, but I have no desire to program in it now, so what's the point of listing it as one of my skills? I'm not saying that my resume doesn't contain the word Java. In fact, it does state in my first job description that we used Java, but my skills list is not a summary of what I've done in my past. My skills list is the list of skills that I've kept up with and am interested in continuing to keep up with. A bloated skills list indicates that you think you know more than you do, or you haven't spent the time to be and expert in anything; both situations look bad.

Being a Gross Exaggerator in an interview is painful. You generally have a bit of knowledge of several things, but almost no in depth knowledge of anything. Most questions quickly expose this. Gross Exaggerators are fairly easy to spot, and I always pass on hiring them.

WYSIWYG (What You See Is What You Get)
It's very easy to be a WYSIWYG candidate, because you are very clear about what you know and what you don't. A WYSIWYG candidate never gives a partial explanation; they either tell you every painful detail, or claim to know little or nothing about the topic.

Hiring a WYSIWYG is an easy choice, but I don't think being a WYSIWYG is the best option. The problem with being a WYSIWYG is that there are several Gross Exaggerators and some Semi-bluffers that will be competing with you. Someone who claims to have the knowledge you do, plus more, will always be an attractive choice for a potential employer.

The Semi-bluffer

In [poker] games with multiple betting rounds, to bluff on one round with an inferior or drawing hand that might improve in a later round is called a semi-bluff. A player making a semi-bluff can win the pot two different ways: by all opponents folding immediately or by catching a card to improve the player's hand. --Wikipedia
Semi-bluff is a term that I picked up playing poker. A few of the things I love about poker is that you don't know what the competition has, you don't know what will be needed in the end to win, and you probably don't know if you are currently winning or losing. Of course, each of those things can be said about almost any interview.

I think Semi-bluffing interviewees generally do the best because they demonstrate what they know, suggest that they know more, but admit what they don't know when directly challenged. In fact, I believe the above quote could be rewritten as the following to describe Semi-bluffing in an interview.
Almost all interviews involve a series of questions, to give a vague answer to one question when you don't know enough details can be called a semi-bluff. An interviewee making a semi-bluff can pass that round of questioning two different ways: if the interviewer doesn't request more information or if the follow up question happens to hit one aspect where you do understand the details. A semi-bluff can also be a success if the interviewee admits to not knowing the answer at the moment, but later in the interview process demonstrates that the desired knowledge has been acquired.

An example of a Semi-bluff could be demonstrated as the following.
Interviewer: Do you have experience with deploying Rails applications.
Interviewee: On my current project we use Capistrano and deploy to RHEL. The Webserver is Nginx fronting a Mongrel cluster.

Notice that the interviewee hasn't stated that he did any of that work, instead he's simply listed his current project's deployment plan. The questions may end right there, but if they don't you can easily follow up with: Truthfully, I've been focused on other parts of the application so I only have a high level view of our deployment. However, I believe that it would be very easy for me to get into the details of your specific deployment if I am hired. Following the interview, the interviewee should then dig into the details of their current deployment and send answers via email to the interviewer. Obviously, the faster the email is sent, the better.
A Semi-bluff in poker, and while interviewing, takes a great deal of finesse. Coming off as a WYSIWYG while Semi-bluffing is safe, but coming off as a Gross Exaggerator can cost you a job. Therefore, it's obvious which way you should lean if you find Semi-bluffing isn't working out for you.

Try Semi-bluffing a question in your next interview. It can be a great rush, but be sure to admit when you don't know something. Also be careful about choosing which question to Semi-bluff. A direct and detailed question isn't a good candidate for a Semi-bluff. When someone knows they have "the nuts" a bluff is an (often embarrassing) waste.

* I define expert as someone who is knowledgeable concerning: syntax, development environment, advanced language features, how and what to test, framework choices, details of several frameworks of the language, debugging, performance optimization, deployment strategies, and pattern implementation specific to the language.

What's New in Edge Rails: Better Exception Handling

Posted about 1 year back at Ryan's Scraps

It’s a common pattern to redirect the user to, or render specific pages for different types of exceptions that are thrown in your application. Prior to this changeset this usually involved overloading the rescue_action_in_public method of your controllers:

1
2
3
4
5
6
7
8
9
class PostsController < ApplicationController
  def rescue_action_in_public(exception)
    case(exception)
      when ActiveRecord::RecordNotFound then render :file => '/bad_record'
      when NoMethodError then render :file => '/no_method'
      else render :file => '/error'
    end
  end
end

It’s easy to see that this can quickly grow to be an ugly mass of a case or if/else statement.

Now we’ve got a much cleaner way to map exceptions to handlers with the new rescue_from support. rescue_from maps an exception type directly to a handler method name for a very concise and direct way of dealing with exceptions:

1
2
3
4
5
6
7
8
9
10
class PostsController < ApplicationController

  # Declare exception to handler methods
  rescue_from ActiveRecord::RecordNotFound, :with => :bad_record
  rescue_from NoMethodError, :with => :show_error

  def bad_record; render :file => '/bad_record'; end
  def show_error(exception); render :text => exception.message; end

end

Note that the exception handler methods can be either no-arg methods or take the exception in question as an argument (as in show_error above).

tags: ruby, rubyonrails

What's New in Edge Rails: Better Exception Handling

Posted about 1 year back at Ryan's Scraps

It’s a common pattern to redirect the user to, or render specific pages for different types of exceptions that are thrown in your application. Prior to this changeset this usually involved overloading the rescue_action_in_public method of your controllers:

1
2
3
4
5
6
7
8
9
class PostsController < ApplicationController
  def rescue_action_in_public(exception)
    case(exception)
      when ActiveRecord::RecordNotFound then render :file => '/bad_record'
      when NoMethodError then render :file => '/no_method'
      else render :file => '/error'
    end
  end
end

It’s easy to see that this can quickly grow to be an ugly mass of a case or if/else statement.

Now we’ve got a much cleaner way to map exceptions to handlers with the new rescue_from support. rescue_from maps an exception type directly to a handler method name for a very concise and direct way of dealing with exceptions:

1
2
3
4
5
6
7
8
9
10
class PostsController < ApplicationController

  # Declare exception to handler methods
  rescue_from ActiveRecord::RecordNotFound, :with => :bad_record
  rescue_from NoMethodError, :with => :show_error

  def bad_record; render :file => '/bad_record'; end
  def show_error(exception); render :text => exception.message; end

end

Note that the exception handler methods can be either no-arg methods or take the exception in question as an argument (as in show_error above).

You can also use a block or proc to specify exception handling in rescue_from:

1
2
3
4
5
6
7
class PostsController < ApplicationController

  # Declare exception to handler methods
  rescue_from(ActiveRecord::RecordNotFound) { |e| render :file => '/bad_record' }
  rescue_from NoMethodError, :with => proc { |e| render :text => e.message }

end

tags: ruby, rubyonrails

What's New in Edge Rails: Better Exception Handling

Posted about 1 year back at Ryan's Scraps

It’s a common pattern to redirect the user to, or render specific pages for different types of exceptions that are thrown in your application. Prior to this changeset this usually involved overloading the rescue_action_in_public method of your controllers:

1
2
3
4
5
6
7
8
9
class PostsController < ApplicationController
  def rescue_action_in_public(exception)
    case(exception)
      when ActiveRecord::RecordNotFound then render :file => '/bad_record'
      when NoMethodError then render :file => '/no_method'
      else render :file => '/error'
    end
  end
end

It’s easy to see that this can quickly grow to be an ugly mass of a case or if/else statement.

Now we’ve got a much cleaner way to map exceptions to handlers with the new rescue_from support. rescue_from maps an exception type directly to a handler method name for a very concise and direct way of dealing with exceptions:

1
2
3
4
5
6
7
8
9
10
class PostsController < ApplicationController

  # Declare exception to handler methods
  rescue_from ActiveRecord::RecordNotFound, :with => :bad_record
  rescue_from NoMethodError, :with => :show_error

  def bad_record; render :file => '/bad_record'; end
  def show_error(exception); render :text => exception.message; end

end

Note that the exception handler methods can be either no-arg methods or take the exception in question as an argument (as in show_error above).

tags: ruby, rubyonrails

What's New in Edge Rails: Specify Plugin Load Ordering

Posted about 1 year back at Ryan's Scraps

You’ve always been able to specify exactly which plugins you want to be loaded up with your Rails app, instead of haphazardly loading everything in vendor/plugins with this little snippet that you may or may not see in your environment.rb file:

1
2
# Only load the plugins named here, by default all plugins in vendor/plugins are loaded 
config.plugins = %W( exception_notification ssl_requirement ) 

The problem with this is that while you can explicitly specify which plugins you want loaded and in what order, it becomes quite tedious to list out every plugin when you only care about the load order of a select few.

Well, this has been taken care of with the :all symbol you can now use in your config.plugin list to denote all other plugins not explicitly listed:


config.plugins = [ :exception_notification, :ssl_requirement, :all ] 

This gives you finer-grain control over your plugin load order. You can even use :all in the middle of your load order if you want to push some plugins to the back of the line:


config.plugins = [ :exception_notification, :all, :ssl_requirement ] 

tags: ruby, rubyonrails

What's New in Edge Rails: Specify Plugin Load Ordering

Posted about 1 year back at Ryan's Scraps

You’ve always been able to specify exactly which plugins you want to be loaded up with your Rails app, instead of haphazardly loading everything in vendor/plugins with this little snippet that you may or may not see in your environment.rb file:

1
2
# Only load the plugins named here, by default all plugins in vendor/plugins are loaded 
config.plugins = %W( exception_notification ssl_requirement ) 

The problem with this is that while you can explicitly specify which plugins you want loaded and in what order, it becomes quite tedious to list out every plugin when you only care about the load order of a select few.

Well, this has been taken care of with the :all symbol you can now use in your config.plugin list to denote all other plugins not explicitly listed:


config.plugins = [ :exception_notification, :ssl_requirement, :all ] 

This gives you finer-grain control over your plugin load order. You can even use :all in the middle of your load order if you want to push some plugins to the back of the line:


config.plugins = [ :exception_notification, :all, :ssl_requirement ] 

tags: ruby, rubyonrails

What's New in Edge Rails: Specify Plugin Load Ordering

Posted about 1 year back at Ryan's Scraps

You’ve always been able to specify exactly which plugins you want to be loaded up with your Rails app, instead of haphazardly loading everything in vendor/plugins with this little snippet that you may or may not see in your environment.rb file:

1
2
# Only load the plugins named here, by default all plugins in vendor/plugins are loaded 
config.plugins = %W( exception_notification ssl_requirement ) 

The problem with this is that while you can explicitly specify which plugins you want loaded and in what order, it becomes quite tedious to list out every plugin when you only care about the load order of a select few.

Well, this has been taken care of with the :all symbol you can now use in your config.plugin list to denote all other plugins not explicitly listed:


config.plugins = [ :exception_notification, :ssl_requirement, :all ] 

This gives you finer-grain control over your plugin load order. You can even use :all in the middle of your load order if you want to push some plugins to the back of the line:


config.plugins = [ :exception_notification, :all, :ssl_requirement ] 

tags: ruby, rubyonrails

Slides from Railsconf presentaion

Posted about 1 year back at The Hobo Blog

OK the slides are online. Unfortunately I haven’t added any notes as yet, so some of it will be a bit obscure. The theme of the talk was that while being very good for beginners wanting to create a web-app quickly and easily, Hobo is also well suited to more serious projects.

Enjoy!

After Railsconf

Posted about 1 year back at The Hobo Blog

So that was Railsconf. By far the biggest takeaway for me was very simple: Hobo needs docs! Of course we knew that already, but it was really hammered home by meeting a bunch of people who have tried Hobo and are now waiting in the wings for it to become easier to use.

The Hobo talk was fairly well attended, which was great — many thanks to everyone that showed up.

I really enjoyed David Black’s keynote — engineering is art. His quote from the famous “Mythical Man Month” by Fred Brooks is so wonderful I think I’ll add it here in more than full.

The programmer, like the poet, works only slightly removed from pure thought-stuff. He builds castles in the air, from air, creating by exertion of the imagination. Few media of creation are so flexible, so easy to polish and rework, so readily capable of realizing grand conceptual structures. Yet the program construct, unlike the poet’s words, is real in the sense that it moves and works, producing visible outputs separate from the construct itself. It prints results, draws pictures, produces sounds, moves arms. The magic of myth and legend has come true in our time. One types the correct incantation on a keyboard, and a display screen comes to life, showing things that never were nor could be.

Mongrel Timeout / Throttle Misnomer

Posted about 1 year back at igvita.com

Earlier today I made an intriguing discovery while perusing through the Mongrel documentation. Perhaps an oversight on my part, but arguably also a real misnomer by Zed: the timeout (-t) config flag is exactly the last thing I would expect it to be - a throttle mechanism! I've gone around setting up my mongrel clusters and recommending mongrel configs to dozens of people not realizing the unintended behavior. Hence, while I can't claim that this has adversely affected the overall performance, it's definitely something to be cautious about.

Timeouts are really a throttle

Viewing the usual help flag on the command line for mongrel_cluster presented me with a nifty timeout (-t) option which I quickly adopted in all my configs. Intuitively, I expected the timeout flag to resemble the Apache config: kill threads and/or stale clients which reach the timeout time period threshold. Apparently, this is not so:

-t, timeout (:timeout)
Time to pause between accepting clients. Used as a throttle mechanism.
* Default: 0

The saving grace for most people is the fact that the throttle is defaulted to 0 (off). Having said that, I think you should be aware of this misnomer and I hope that Zed will address this issue in some future release.

Monitoring Mongrel: Monit makes Mongrel play nice!

Mongrel Timeout / Throttle Misnomer

Posted about 1 year back at igvita.com

Earlier today I made an intriguing discovery while perusing through the Mongrel documentation. Perhaps an oversight on my part, but arguably also a real misnomer by Zed: the timeout (-t) config flag is exactly the last thing I would expect it to be - a throttle mechanism! I've gone around setting up my mongrel clusters and recommending mongrel configs to dozens of people not realizing the unintended behavior. Hence, while I can't claim that this has adversely affected the overall performance, it's definitely something to be cautious about.

Timeouts are really a throttle

Viewing the usual help flag on the command line for mongrel_cluster presented me with a nifty timeout (-t) option which I quickly adopted in all my configs. Intuitively, I expected the timeout flag to resemble the Apache config: kill threads and/or stale clients which reach the timeout time period threshold. Apparently, this is not so:

-t, timeout (:timeout)
Time to pause between accepting clients. Used as a throttle mechanism.
* Default: 0

The saving grace for most people is the fact that the throttle is defaulted to 0 (off). Having said that, I think you should be aware of this misnomer and I hope that Zed will address this issue in some future release.

Monitoring Mongrel: Monit makes Mongrel play nice!

Mongrel Timeout / Throttle Misnomer

Posted about 1 year back at igvita.com

Earlier today I made an intriguing discovery while perusing through the Mongrel documentation. Perhaps an oversight on my part, but arguably also a real misnomer by Zed: the timeout (-t) config flag is exactly the last thing I would expect it to be - a throttle mechanism! I’ve gone around setting up my mongrel clusters and recommending mongrel configs to dozens of people not realizing the unintended behavior. Hence, while I can’t claim that this has adversely affected the overall performance, it’s definitely something to be cautious about.

Timeouts are really a throttle

Viewing the usual help flag on the command line for mongrel_cluster presented me with a nifty timeout (-t) option which I quickly adopted in all my configs. Intuitively, I expected the timeout flag to resemble the Apache config: kill threads and/or stale clients which reach the timeout time period threshold. Apparently, this is not so:

-t,—timeout (:timeout)
Time to pause between accepting clients. Used as a throttle mechanism.
* Default: 0

The saving grace for most people is the fact that the throttle is defaulted to 0 (off). Having said that, I think you should be aware of this misnomer and I hope that Zed will address this issue in some future release.

Monitoring Mongrel: Monit makes Mongrel play nice!

, , ,

Episode 72: Adding an Environment

Posted about 1 year back at Railscasts

Rails comes with three environments: development, test, and production. But, you aren't restricted to just these. You can add your own! See how in this episode.

Fun With the Y Combinator in Ruby

Posted about 1 year back at Blog Posts : Nex3

A while back, I was playing around with anonymous recursive functions. I ended up creating an anonymously recursive lambda function, which I called reclambda, in Ruby. At the time this blog was yet to be created, so Hampton Catlin wrote it up instead.

I didn’t really understand it, though. The code was mostly ported from a Scheme example I found somewhere. I always felt kinda bad about that.

Recently, I decided to remedy my ignorance. I bought and worked through The Little Schemer1.

Although the whole book is fascinating, What really made it for me was the chapter on the Y combinator. After reading that, I felt for the first time that I actually understood how it worked. Feeling renewed confidence, I set out to remake it – by hand – in Ruby.

Let me take a step back here and define what I’m talking about.

First of all, what’s this Y thing? The Y combinator is just a function. It takes as input a function, f, and returns a function, g, such that f.call(g) returns g.

That doesn’t seem possible. What about, say, x + 1?

Y { |x| x + 1 } #=> ???

Well, this actually breaks. Our friend Y only works on functions that expect functions. x will always be a function, so treating it as a number will just cause type errors. Alas.

Now what about anonymous recursive functions? What are these? Well, we all know what a recursive function is. It’s a function that calls itself. The classic example is factorial:

def factorial(n)
  if n == 0
    1
  else
    n * factorial(n - 1)
  end
end

We also know what an anonymous function is. It’s a function that we create “on the fly,” so to speak. They’re used all the time in Ruby. Every block is an anonymous function that gets called when the method yields values. You can also create anonymous functions with proc or lambda:

fun = lambda { |x| x + 1 }
fun.call(1) #=> 2

An anonymous function is just a function without a name. So what’s the big deal about anonymous recursive functions? In order to recurse, it looks like you need to give the function a name. But anonymous functions have no names. Yeep.

Does that mean that anonymity and recursivity are mutually exclusive? Thanks to the Y combinator, no, it does not!

Let’s think this through. What’s preventing us from recursing? We don’t have a reference to our function.

Let’s supposed that we were to be passed such a reference. Then we could make a function that would take the reference and return a new function that used it to recurse:

lambda { |this| lambda { |n| n  0 ? 1 : n * this.call(n - 1) } }

Now think about what would happen if you passed this to Y. It returns a function that, if passed as this in the above expression, returns itself. What function could this be? It must be the inner function:

lambda { |n| n  0 ? 1 : n * this.call(n - 1) }

And now we actually have a this. Moreover, it’s the same function that we’re running right now. In short: we have achieved anonymous recursion. Sweet.

So, um, what is this super-magical Y function? How is it defined? Let’s try see if we can build it ourselves.

We’ll build it around the function we eventually want to pass to Y. Here it is in a more expanded form than before:

lambda do |this|
  lambda do |n|
    if n  0
      1
    else
      n * this.call(n - 1)
    end
  end
end

For a first try, let's try just passing this to itself. We're going for functions having references to themselves, so that seems like a reasonable place to start. We can do so by calling the self-application function:

lambda { |f| f.call(f) }

This just calls a function with itself as an argument. It's a little mind-bendy, but think about it for a sec and it should make sense. Using it on our old function:

lambda { |f| f.call(f) }.call(
  lambda do |this|
    lambda do |n|
      if n  0
        1
      else
        n * this.call(n - 1)
      end
    end
  end)

Unfortunately, this doesn’t quite work. this isn’t the inner function, it’s the wrapper function. Thus, this.call(n - 1) doesn’t work, because it’s expecting a function, not an integer.

So what if we call the wrapper function first? We’d want to pass it itself, because that’s what it’ll now be expecting:

lambda { |f| f.call(f) }.call(
  lambda do |this|
    lambda do |n|
      if n  0
        1
      else
        n * this.call(this).call(n - 1)
      end
    end
  end)

And this works! Calling it on 3 produces 6, calling it on 4 produces 24. That wasn't so hard, was it?

The code isn't really what we were going for, though. We had to modify the body of the factorial function to make it work.

But what if we move the whole this.call(this) bit into its own function? Is that possible?

It is if we wrap the wrapper function in yet another function. This allows us to get a reference to what used to be this, which we’ll now call g. We can then pass lambda { g.call(g) } as this:

lambda { |f| f.call(f) }.call(
  lambda do |g|
    lambda do |this|
      lambda do |n|
        if n  0
          1
        else
          n * this.call.call(n - 1)
        end
      end
    end.call(lambda { g.call(g) })
  end)

The recursion line is still ugly. Do we have to do this.call.call? No, we don’t! We can have this handle the call to the resulting function as well:

lambda { |f| f.call(f) }.call(
  lambda do |g|
    lambda do |this|
      lambda do |n|
        if n  0
          1
        else
          n * this.call(n - 1)
        end
      end
    end.call(lambda { |n| g.call(g).call(n) })
  end)

And now what we have inside is just what we had before. In fact, we can make this a function and take that chunk as a block:

def Y
  lambda { |f| f.call(f) }.call(
    lambda do |g|
      yield(lambda { |<strong>n| g.call(g).call(</strong>n) })
    end)
end

And that's the Y combinator. Let's see it in action:

Y { |this| lambda { |n| n  0 ? 1 : n * this.call(n - 1) } }.call(12) #=> 479001600

Huzzah!

1 The Little Schemer, by Daniel P. Friedman and Matthais Felleisen, is a classic introduction to the wonderful things you can do with recursion and first-class functions.

Episode 72: Adding an Environment

Posted about 1 year back at Railscasts

Rails comes with three environments: development, test, and production. But, you aren't restricted to just these. You can add your own! See how in this episode.


1 ... 520 521 522 523 524 ... 634