D8【问答格式】【精简版】每日一练前端

62 阅读6分钟

Q1. 多线程编程会有什么问题呢,怎么解决

  • 由于线程执行顺序的不确定性,如果没有有效的同步机制,对共享资源的读写操作可能会出现竞争,导致程序出现一些意料之外的错误结果。
  • 所以需要协调不同线程之间对共享资源的访问,也就是同步机制。可以通过互斥锁,信号量来解决。

Q2. 打开浏览器会有哪些进程和线程?

  • 新打开一个页面至少需要: 1个浏览器进程,1个GPU进程,1个网络进程,和1个渲染进程,一共4个进程;后续如果再打开新的标签页:浏览器进程,GPU进程,网络进程是共享的,不会重新启动,然后默认情况下会为每一个标签页配置一个渲染进程(浏览器内核)。
  • 渲染进程中的线程
    • GUI渲染线程
    • JS引擎线程
    • 事件触发线程
    • HTTP请求线程
    • 计时器线程

Q3. 浏览器垃圾回收机制

  • 标记清除
    • 当变量进入环境时,例如,在函数中声明一个变量,就将这个变量标记为“进入环境”。而当变量离开环境时,则将其标记为“离开环境”。
  • 引用计数

Q4. 死锁及其解决方法

  • 当两个线程为了保护两个不同的共享资源而使用了两个互斥锁,那么有可能会造成两个线程都在等待对方释放锁,在没有外力的作用下,这些线程会一直互相等待,就没办法继续运行,这种情况就是发生了死锁。
  • 死锁只有同时满足四个条件才会发生:
    • 互斥条件:多个线程不能同时使用同一个资源
    • 持有并等待条件:线程A在等待资源2的同时并不会释放自己已经持有的资源1
    • 不可剥夺条件:在自己使用完之前不能被其他线程获取
    • 环路等待条件:多个线程都在等待其他线程释放资源,就构成了环形链
  • 解决方法:
    • 破坏其中一个条件即可,最常用的方法就是使用资源有序分配法来破坏环路等待条件。最常见的并且可行的就是使用资源有序分配法,来破环环路等待条件。也就是线程A和线程B获取资源的顺序要一样。

Q5. 操作系统的调度算法有哪些?

  1. 非抢占式的先来先服务算法
    • 先来后到,每次从就绪队列选择最先进入队列的进程,然后一直运行,直到进程退出或被阻塞,才会继续从队列中选择第一个进程接着运行。
  2. 最短作业优先调度算法
    • 优先选择运行时间最短的进程来运行
  3. 高响应比优先调度算法
    • 每次进行进程调度时,先计算「响应比优先级」,然后把「响应比优先级」最高的进程投入运行,优先权 = (等待时间+要求服务时间)/要求服务时间
  4. 时间片轮转调度算法
    • 每个进程被分配一个时间段,称为时间片(Quantum),即允许该进程在该时间段中运行。
  5. 最高优先级调度算法
    • 从就绪队列中选择最高优先级的进程进行运行
    • 分为两种
      • 非抢占式:当就绪队列中出现优先级高的进程,运行完当前进程,再选择优先级高的进程。
      • 抢占式:当就绪队列中出现优先级高的进程,当前进程挂起,调度优先级高的进程运行。
  6. 多级反馈队列调度算法
    • 是时间片轮转和最高优先级的综合
    • 设置了多个队列,赋予每个队列不同的优先级,每个队列优先级从高到低,同时优先级越高时间片越短

Q6. TCP和UDP的区别,以及它们的应用场景

  • TCP能保证数据的可靠性传输,按顺序传输,而且能检测到丢包并且触发重传机制,保证数据的完整性,所以适用于需要可靠数据传输的应用,比如电子邮件,文件传输这些。UDP是一种不可靠的协议,他不能保证数据的完整性,数据包可能会丢失或者乱序,但是效率比TCP高,延迟也低,所以适用于一些实时性要求高,数据丢失不致命的应用,比如qq电话视频这些。
  • UDP是面向报文的协议,每个UDP报文就是一个用户信息,而TCP是面向字节流的协议,消息可能会被操作系统拆分为多个TCP报文,他并不是一个用户信息对应一个TCP报文。

Q7. 介绍一下关系型数据库和非关系型数据库

  • 关系型数据库采用表格形式的结构,比较适合存储结构化的数据,而非关系型数据库采用的是比如键值存储,文档存储等形式,比较适合半结构化或非结构化数据
  • 查询数据的时候,关系型数据库用的是sql语言,非关系型用的就是不同的查询语言。
  • 除此之外,关系型数据库强调事务的一致性,但是非关系型数据库就没有,从中读取到的可能还是处于一个中间态的数据。但是关系型数据库为了维护一致性所付出的代价就是并发读写性能比较差,如果是需要并发读写性能高的场景,就需要用非关系型数据库。

Q8. 进程间通信的方式?

  • 同一台主机之间的进程通信
    • 管道通信:就是操作系统在内核中开辟一段缓冲区,进程1可以将需要交互的数据拷贝到这个缓冲区里,进程2就可以读取了
    • 消息队列通信:消息队列就是用户可以添加和读取消息的列表,消息队列里提供了一种从一个进程向另一个进程发送数据块的方法,不过和管道通信一样每个数据块有最大长度限制
    • 共享内存通信:就是映射一段能被其他进程访问的内存,由一个进程创建,但多个进程都可以访问,共享进程最快的是IPC方式
    • 信号量通信:比如信号量初始值是1,进程1来访问一块内存的时候,就把信号量设为0,然后进程2也来访问的时候看到信号量为0,就知道有其他进程在访问了,就不访问了
  • 不同主机之间的进程通信
    • socket:比如发起http请求,服务器返回数据

Q9. 僵尸进程和孤儿进程

  • 孤儿进程:父进程退出了,而它的一个或多个进程还在运行,那么这些子进程都会成为孤儿进程。这些孤儿都将被init进程收养,并负责这些孤儿的以后。

  • 僵尸进程:就是子进程比父进程先结束,而父进程又没有释放子进程占用的资源,那么子进程的描述还留在系统中,这种进程就是僵尸进程。