前端面试:操作系统&计组&数据结构基础

117 阅读3分钟

1.进程的三种状态:

  • 就绪:进程已分配到除CPU以外的所有必要资源,只要获得处理机便可立即执行。
  • 执行:进程已获得处理机,其程序正在处理机上执行。
  • 阻塞:正在执行的程序,由于等待某个事件发生而无法执行时,便放弃处理机而处于阻塞状态。引起进程阻塞的原因可能是等待I/O完成、申请缓冲区不能满足、等待信号等。

2.进程调度算法:

  • 先来先服务调度算法。
  • 最短作业优先调度算法。
  • 高响应比优先调度算法。
  • 时间片轮转调度算法。
  • 最高优先级调度算法。
  • 多级反馈队列调度算法。

3.产生死锁的四个必要条件:

  • 互斥:一个资源每次只能被一个进程使用。
  • 请求和保持:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
  • 不剥夺:进程已获得的资源在未使用完之前不能强行剥夺。
  • 循环等待:若干进程之间形成一种头尾相接的循环等待资源关系。

4.解锁死锁的办法:

资源有序分配法。银行家算法。

5.进程间通信方式:

  • 管道。(单向)
  • 消息队列。(保存在内核中的消息链表)
  • 共享内存。(虚拟地址)
  • 信号量。(实现进程间互斥访问共享内存)
  • 信号。(通知接受进程有某种事件发生)
  • socket。(跨网络与不同主机通信)

6.进程和线程的区别:

  • 进程是资源分配的最小单位,线程是CPU调度的最小单位。
  • 一个进程可以有多个线程,各个线程之间可以并发执行。
  • 进程有自己的内存和资源。一个进程中的线程会共享这些内存和资源。
  • 线程的性能开销比进程小。
  • 进程间不会相互影响,而子线程可以影响父线程。

7.常见的锁:

  • 互斥锁:互斥锁加锁失败后,线程会释放CPU,给其他线程。
  • 自旋锁:自旋锁加锁失败后,线程会忙等待,直到它拿到锁。
  • 读写锁:读写锁既是独占锁又是共享锁。read模式是共享的,write模式是互斥的
  • 悲观锁:访问共享资源前要先上锁。
  • 乐观锁:先改完共享资源,再验证这段时间内有没有发生冲突。

8.为什么0.1+0.2不等于0.3?

截屏2023-12-14 18.01.12.png

计算机是通过二进制存储数据的。0.1和0.2的二进制都是无限循环的数,计算机只能采用近似数的方式保存,两个近似数相加得到的必然也是一个近似数。

怎么解决:

通过toFixed

function add(a, b) {
  return parseFloat((a + b).toFixed(2))
}
console.log(add(0.1, 0.2) === 0.3) //true

使用ES6提供的Number.EPSILON,它的值是2**-52。

function add(a, b){ 
  return Math.abs(a-b)<Number.EPSILON;
} 
console.log(add(0.1 + 0.2, 0.3));  //true

先乘后除

function add(a, b) {
    const num1 = (a.toString().split('.')[1] || '').length;
    const num2 = (b.toString().split('.')[1] || '').length;
    const base = Math.pow(10, Math.max(num1, num2));
    return (a * base + b * base) / base;
}
console.log(add(0.1, 0.2) === 0.3) //true

9.大数相加

JS 在存放整数的时候是有一个安全范围的,一旦数字超过这个范围便会损失精度。

function bigSum(a, b) {
    const n = Math.max(a.length, b.length);
    // 补0
    a = a.padStart(n, 0);
    b = b.padStart(n, 0);

    // 判断是否进位
    let c = 0;
    // 结果
    let res = '';
    let t = 0;
    // 倒序加
    for(let i=n-1; i>=0; i--) {
        t = parseInt(a[i]) + parseInt(b[i]) + c;
        // 判断进位
        c = Math.floor(t/10);
        // 保留余数
        t = t%10;
        res = t + res;
    }
    if(c === 1) {
        res = '1' + res;
    }
    return res;
}

10.排序算法

截屏2023-12-15 13.03.21.png

快排实现

function quickSort(arr) {
    if(arr.length <= 1) return arr;
    const num = arr[0];
    let left = [], right = [];
    for(let i = 1; i < arr.length; i++) {
        if(arr[i] < num) left.push(arr[i]);
        else right.push(arr[i]);
    }
    return quickSort(left).concat([num], quickSort(right))
}