SDE面试技巧之一:OOA & OOD

OOA & OOD is also a big area in interview.

这里不讨论OOA和OOD的具体技术,这里只是讨论面试过程中如何问、如何答。在掌握了OOD的具体技术后,要想面试成功,还需要掌握面试技巧。OOD的面试的时要特别注意Clarify the ambiguity,以避免你的设计既可以满足需求,又不会over design。

下面这一段摘自:http://www.nomachetejuggling.com/2010/04/06/avoiding-the-big-design-interview-question/,我觉得作者写的挺好的。

How To Ask This Question
If you want to know how comfortable a candidate is with OO, ask them the question in a way that resembles real-life OOP a bit more closely. Start simple, by providing a single simple requirement. Though the candidate won’t be able to write and run tests, the requirement serves as a driver for the design.
A good indicator that the question is taking you and the candidate off-track is if the boxes he or she draws on the whiteboard lack method names. If there are no methods, there are no behaviors, which means the candidate is designing first, regardless of requirements. Steer the candidate back by asking them to write method names.
For example, ask the candidate to design the object model for a simple bookshelf. A bookshelf is so simple that there’s virtually no way to overcomplicate it, so you can say that you simply need to be able to add a book to the bookshelf, nothing else. Once they have done this, give the candidate another “test”, by adding a requirement. Now say that you want the bookshelf to be a “smart” bookshelf, where you can look up a book by title and get a reference to the book. The candidate will make some changes to their design. Continue adding requirements to the thing until you’re satisfied with the evolution of the candidate’s design.

  • Modify the design to allow me to search the bookshelf by Title, Author, or ISBN.
  • Allow me to use the bookshelf as an ad-hoc library, so I can “check out” a book, removing it from the bookshelf. Make it possible to look up books that have been “borrowed”.
  • Require a user provide their name when checking out a book. Give them a return date.
  • Make it so the bookshelf can generate a list of overdue books and who has them. Where does that method belong? Should it be on its own object that Bookshelf uses?Make the bookshelf more concrete, so that there is only a certain number of books that can fit on any given shelf in the overall bookshelf. Make it possible to ask which shelf a book is on. Make it possible to add a new shelf.

You can obviously pick your own model (Car, Elevator, Fridge, etc) and drive the direction the design should go using requirements. Have the candidate write method names (but not implementations) where appropriate. Keep asking if the method is on the right object, or it belongs on another one.
How To Answer This Question
Of course, not everyone reads this blog, so if you’re in an interview you may get the “design an object model for a x” question. If you find yourself in this situation, you essentially want to ask questions of your interviewer to pull requirements out of them. The reality is, they probably DO have a particular kind of system in mind when they ask the question, so you need to find out what that is.
If you’re supposed to design the Car class, ask if there are other types of vehicles in the system. If not, don’t make a Vehicle parent class, and explain that you see no need unless the system required additional vehicles. Before you draw a box named Tire, ask if the car needs to be able to support snow tires or some other kind of interchangeable tire. If not, why would you make a class or interface for them? Start as simply as you can and only draw a new box when you’ve extracted enough information from the interviewer to deem it warranted. If you jump up to the whiteboard and draw two or three boxes before asking any questions, you’re placing your interview at risk because the interviewer may be picturing a completely different usage of this system than you are.
Of course, it’s always possible that the interviewer will keep asking for the same information, arguing that you should show your OO skills off without requirements that drive that design out. If you want the job, your best bet there is to take a random stab at the appropriate level of complexity and hope that you strike somewhere near what the interviewer wants. In that situation, however, I’d imagine your interviewer doesn’t know much about designing good software, and their codebase might be an over-engineered mess, so you may not want that job.

总体而言,我觉得面试的时候,应该是根据面试官的要求进行设计,废话?不!!!根据我个人的理解,设计是服务于特定目标的,没有哪个设计是可以满足所有场景的需要,因此在设计一个类或者考虑要不要继承时,就需要知道设计目标和场景,而这是完全来源于面试官的要求。如果面试官没有说,你想到的可以问,但不能自己进行假设。因为OOD中最主要的考察点就是看应聘者能不能发现那些不明确的、模棱两可的地方,通过问面试官的方式进行clarify。所以OOD面试题中,最重要的就是:不要自己假设,在考虑应不应该使用某种设计时,问面试官以确定各种条件是否符合!

下面我们来点实在的吧:

设计类图来描述 deck of cards。首先搞清楚啥是deck of cards,是一张牌还是一副牌,不确定就问下吧,尤其在英文面试的时候,难免出现这种情况。OK,问过后我们知道是一副牌。一副牌由多个牌构成,先得把一张牌描述清楚了,下面是用C#的一个定义:

    public  class Card
    {
        public  enum Suit
        {
            CLUBS = 1, SPADES = 2, HEARTS = 3, DIAMONDS = 4
        };

        private  int card;
        private Suit suit;
        public Card( int r, Suit s)
        {
            card = r;
            suit = s;
        }

        public  int value() { return card; }
        public Suit Suit
        {
            get
            {
                return suit;
            }
        }
    }

为什么不把牌的点数也做成Enum呢?我觉得也可以,不过好处不大。在这里没有加比较的逻辑,因为这得由是什么游戏来决定。如果我们要在这个类基础上,表示BlackJack中用的牌,A可以当1也可以当11,那如何表达这个信息呢?可以实现一个子类来继承Card,并加上一些在BlackJack中使用的一些方法或者属性,比如加上一个方法判断牌是不是A,etc.

如果我们再设计一个类来表示游戏呢?比如BlackJack游戏,那游戏的规则就应该在游戏类中,游戏类可以持有游戏特定的一手牌,一手牌这个类持有对牌的引用,还有一个比较大小的方法,用来实现比较那一手牌更大。

你可能感兴趣的:(面试技巧)