上海酷量

# 上海酷量

一面(基础题)

  • 盒模型
  • Http 协议
  • 浏览器存储
  • Vue双向绑定
  • Vue生命周期
  • 数组去重
  • 数据类型(基础和引用), 栈内存和堆内存
  • 浅拷贝/深拷贝
  • 防抖和节流
  • 事件循环机制(异步任务分为宏任务和微任务)

二面(总监面)

  • TypeScript interface 有什么优势, 不用会有什么影响

面试中曲解了面试官的本意. 衰~~

这道题考察的是面试者对 interface 的理解

interface 简单来说就是一个接口所描述的是一个对象相关的属性和方法, 但并不提供具体的创建此对象实例的方法. 它的作用就是为类型命名和为代码或第三方代码定义一个约定

优势:

  1. 提供一种声明数据类型的方式, 可以让代码更清晰易懂
  2. 通过interface, 可以在开发过程中捕捉一些潜在的问题, 属性拼写错误/类型错误等
  3. 可以提高代码的可维护性和可扩展性

影响:

  1. 开发过程中可能会出现更多的类型错误和逻辑错误, 增加调试难度
  2. 代码不够清晰易懂, 维护和扩展困难
  3. 不容易发现潜在问题, 因此程序的稳定性和可靠性会受到影响
  • TypeScript双向链表, 手写

手写... 不过我就只定义了一个 Node 的类型. 心累:)

点击查看代码
interface DoubleLinkedListNode<T> {
  value: T;
  previous?: DoubleLinkedListNode<T>;
  next?: DoubleLinkedListNode<T>;
}

class DoubleLinkedList<T> {
  private head?: DoubleLinkedListNode<T>;
  private tail?: DoubleLinkedListNode<T>;

  public isEmpty(): boolean {
    return this.head === undefined;
  }

  public push(value: T): void {
    const node: DoubleLinkedListNode<T> = { value };
    if (this.isEmpty()) {
      this.head = node;
      this.tail = node;
    } else {
      node.previous = this.tail;
      this.tail!.next = node;
      this.tail = node;
    }
  }

  public pop(): T | undefined {
    if (this.isEmpty()) {
      return undefined;
    }

    const value = this.tail!.value;
    if (this.head === this.tail) {
      this.head = undefined; // List is now empty
      this.tail = undefined;
    } else {
      this.tail = this.tail!.previous;
      this.tail!.next = undefined;
    }

    return value;
  }

  public forEach(callback: (value: T, index: number) => void): void {
    let node = this.head;
    let i = 0;
    while (node !== undefined) {
      callback(node.value, i);
      node = node.next;
      i++;
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
  • 双向链表插入和查找的复杂度对比

插入: 在头尾插入时间复杂度为 O(1). 中间插入节点的时间复杂度为 O(n), n 为链表的长度

查找: 查找单个元素的时间复杂度为 O(n)

与单向链表相比, 双向链表具有更好的插入操作的时间复杂度. 它可以在常熟时间内在头部和尾部插入节点. 但是查找单个元素都需要 O(n) 的时间复杂度. 总之, 双向链表在插入操作较多, 搜索操作较少的情况下表现更好.

  • 数组的插入和查找复杂度

插入: 头部/中间插入节点时间复杂度为 O(n), 需要将插入点后的所有元素向后移动一位, 尾部插入时间复杂度为O(1), 其中 n 为数组的长度

查找: 常规情况下, 查找单个元素的时间复杂度为 O(n), 如果是有序数组, 可以通过二分查找将时间复杂度降为 O(logn)

总结, 数组适用于查找操作较多, 插入较少的情况下表现更好.