一些 OO Design 面试题

设计 hash map

解决方案
Constraints and assumptions:

  • For simplicity, are the keys integers only? Yes
  • For collision resolution, can we use chaining? Yes
  • Do we have to worry about load factors? No
  • Can we assume inputs are valid or do we have to validate them? Assume they're valid
  • Can we assume this fits memory? Yes

具体实现比较简单,不赘述。

设计 LRU 缓存

解决方案
Constraints and assumptions:

  • What are we caching? We are cahing the results of web queries
  • Can we assume inputs are valid or do we have to validate them? Assume they're valid
  • Can we assume this fits memory? Yes
class Node {
    int key;
    int value;
    
    Node pre;
    Node next;

    public Node(int key, int value) {
        this.key = key;
        this.value = value;
    }
}

public class LRUCache {
    HashMap map;
    int capicity;
    int count;
    
    // 构成一个双向链表
    Node head, tail;
    
    public LRUCache(int capacity) {
        map = new HashMap<>();
        
        this.capicity = capacity;
        count = 0;
        
        head = new Node(0, 0);
        tail = new Node(0, 0);
        
        head.next = tail;
        head.pre = null;
        
        tail.pre = head;
        tail.next = null;
    }
    
    public void deleteNode(Node node) {
        node.pre.next = node.next;
        node.next.pre = node.pre;
    }
    
    public void addToHead(Node node) {
        node.next = head.next;
        node.next.pre = node;
        node.pre = head;
        head.next = node;
    }
    
    public int get(int key) {
        if (map.get(key) != null) {
            Node node = map.get(key);
            int result = node.value;
            
            // 从当前位置移除,放到头部
            deleteNode(node);
            addToHead(node);
            
            return result;
        }
        
        return -1;
    }
    
    public void put(int key, int value) {
        // 更新
        if (map.get(key) != null) {
            Node node = map.get(key);
            node.value = value;
            
            // 从当前位置移除,放到头部
            deleteNode(node);
            addToHead(node);
        }
        // 加入
        else {
            Node node = new Node(key, value);
            map.put(key, node);
            // 放到头部
            addToHead(node);
            
            // 没有达到capicity
            if (count < capicity) {
                count++;
            } else {
                // 移除队尾
                map.remove(tail.pre.key);
                deleteNode(tail.pre);
            }
        }
    }
}

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache obj = new LRUCache(capacity);
 * int param_1 = obj.get(key);
 * obj.put(key,value);
 */

设计一个呼叫中心

解决方案
Constraints and assumptions:

  • What levels of employees are in the call center?
    Operator, supervisor, director
  • Can we assume operators always get the initial calls?
    Yes
  • If there is no free operators or the operator can't handle the call, does the call go to the supervisors?
    Yes
  • If there is no free supervisors or the supervisor can't handle the call, does the call go to the directors?
    Yes
  • Can we assume the directors can handle all calls?
    Yes
  • What happens if nobody can answer the call?
    It gets queued
  • Do we need to handle 'VIP' calls where we put someone to the front of the line?
    No
  • Can we assume inputs are valid or do we have to validate them?
    Assume they're valid

设计一副牌

解决方案
Constraints and assumptions:

  • Is this a generic deck of cards for games like poker and black jack?
    Yes, design a generic deck then extend it to black jack
  • Can we assume the deck has 52 cards (2-10, Jack, Queen, King, Ace) and 4 suits?
    Yes
  • Can we assume inputs are valid or do we have to validate them?
    Assume they're valid

设计一个停车场

解决方案
Constraints and assumptions:

  • What types of vehicles should we support?
    Motorcycle, Car, Bus
  • Does each vehicle type take up a different amount of parking spots?
    Yes
    Motorcycle spot -> Motorcycle
    Compact spot -> Motorcycle, Car
    Large spot -> Motorcycle, Car
    Bus can park if we have 5 consecutive "large" spots
  • Does the parking lot have multiple levels?
    Yes

基本思想:

  • 定义一个枚举类型 VehicleSize 来标记不同的交通工具种类。
  • 定义一个抽象类 Vehicle 来表示交通工具,包括种类,车牌号等熟悉。
  • 依次定义 Vehicle 的实现类,并实现各自的 can_fit_in_spot 方法:
    • Motorcycle
    • Car
    • Bus
  • 定义停车场 ParkingLot,它包含很多层 self.levels = []。停车时,以此遍历每一层,停车。
  • 定义每一层 Level,它包含很多停车位 self.parking_spots = []
  • 定义每一个停车位 ParkingSpot,包含编号,尺寸,是否停有车辆等属性。

设计一个聊天服务

解决方案
Constraints and assumptions:

  • Text conversations only 只支持文本消息
  • Users 用户的管理
    • Add a user
    • Remove a user
    • Update a user
    • Add to a user's friends list
      • Add friend request
      • Approve friend request
      • Reject friend request
    • Remove from a user's friends list
  • Create a group chat 群聊
    • Invite friends to a group chat
    • Post a message to a group chat
  • Private 1-1 chat 单独聊
    • Invite a friend to a private chat
    • Post a meesage to a private chat
  • No need to worry about scaling initially

基本思想:

  • 定义一个用户类 User,包含:

    • 基本信息,例如用户名,密码
    • 好友信息 # key: friend id, value: User
    • 发送出去的添加好友请求 # key: friend id, value: AddRequest
    • 接受进来的添加好友请求 # key: friend id, value: AddRequest
    • 正在进行的单聊 # key: friend id, value: private chats
    • 正在进行的群聊 # key: chat id, value: GroupChat
  • 定义 UserService 来处理用户相关的操作,包括:

    • 添加及删除用户
    • 发送添加好友请求,批准请求,拒绝请求
  • 定义 AddRequest 来表示添加好友的请求,包括发送人,接收人,发送时间,状态等属性。

  • 定义 Message 来表示聊天消息,包括内容,发送时间,发送人等属性。

  • 定义抽象类 Chat 来表示聊天,包括:

    • 编号
    • 有哪些人 self.users = []
    • 聊天消息 self.messages = []
  • 定义 Chat 的两个具体实现:

    • PrivateChat
    • GroupChat

你可能感兴趣的:(一些 OO Design 面试题)