首页 > 其他分享 >前端面试套题系列(第一篇)

前端面试套题系列(第一篇)

时间:2023-02-03 23:34:57浏览次数:35  
标签:UDP 遍历 return 第一篇 TCP 面试 num treeList 套题

1、进程、线程和协程之间的区别与联系

进程:直观点说,保存在硬盘上的程序运行以后,会在内存空间里形成一个独立的内存体,这个内存体有自己独立的地址空间,有自己的堆,上级挂靠单位是操作系统。操作系统会以进程为单位,分配系统资源(CPU时间片、内存等资源),进程是资源分配的最小单位。

进程之间的通信方式有:无名管道( pipe )、高级管道(popen)、有名管道(named pipe)、消息队列( message queue )、信号量( semophore ) 、信号 ( sinal ) 、共享内存( shared memory ) 、套接字( socket )。

线程:称为轻量级进程(Lightweight Process,LWP),是操作系统调度(CPU调度)执行的最小单位。

【区别】:

调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位;

【联系】:

一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程;

协程:是一种比线程更加轻量级的存在,协程不是被操作系统内核所管理,而完全是由程序所控制(也就是在用户态执行)。

通常创建协程时,会从进程的堆中分配一段内存作为协程的栈。线程的栈有8MB,而协程栈的大小通常只有几十 KB。而且,C库内存池也不会为协程预分配内存,它感知不到协程的存在。这样,更低的内存占用空间为高并发提供了保证,毕竟十万并发请求,就意味着10万个协程。为了实现高性能,我们应该尽可能的减少异步线程。因为协程没有局部存储,相对来说空间成本就小很多,同时它又能满足需求。  

2、什么是 TCP,什么是UDP,两者之间的对比

TCP(Transmission Control Protocol):传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议。由IETF的RFC 793定义。
UDP(User Datagram Protocol):用户数据报协议,是一种面向无连接,不可靠、以数据报文段的形式传输的传输层通信协议。由RFC 768描述了UDP。

TCP、UDP区别
1、 连接
TCP面向连接(如打电话先拨号建立连接)
UDP无连接,即发送数据报前不用建立连接(古代写信,无法彼此建立连接,且无法保证信件是否会丢失)
2、安全
TCP提供可靠的服务,通过TCP连接发送的数据,无差错、不丢失、不重复按序到达。
UDP尽最大努力交付,不保证可靠的传输服务。
3、传输效率
TCP传输效率低、UDP传输效率高
4、连接数量
TCP连接只能一对一、点对点通信。
UDP连接支持一对一、一对多、多对一和多对多的交互通信。
5、首部
TCP报文首部20个字节,UDP报文首部8个字节
6、可靠
TCP的逻辑通信是全双工的可靠信道,UDP则是不可靠信道。
7、面向方式
TCP面向字节流,实际上是把TCP数据看成一串无结构的字节流,由于连接的问题,当网络出现波动时,连接可能出现波动问题。
UDP面向报文。UDP没有阻塞控制,因此网络出现拥堵不会使源主机的发送速率降低。

3、HTTPS 与 HTTP 的区别

HTTP协议以明文方式发送内容,不提供任何方式的数据加密。HTTP协议不适合传输一些敏感信息,比如:信用卡号、密码等支付信息。 HTTPS是具有安全性的ssl加密传输协议。 http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。并且https协议需要到ca申请证书。HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全。  HTTPS协议的主要作用可以分为两种: 1)建立一个信息安全通道,来保证数据传输的安全; 2)确认网站的真实性。HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。   Tips: 有效的证书需要由权威机构CA签名,CA会用自己的私钥来生成数字签名。  

4、什么是宏任务与微任务?

 Js 是单线程的,但是一些高耗时操作就带来了进程阻塞问题。为了解决这个问题,Js 有两种任务的执行模式:同步模式(Synchronous)和异步模式(Asynchronous)。 在异步模式下,创建异步任务主要分为:宏任务与微任务。宏任务是由宿主(浏览器、Node)发起的,而微任务由 JS 自身发起。
宏任务(Macrotask)微任务(Microtask)
setTimeout requestAnimationFrame(有争议)
setInterval MutationObserver(浏览器环境)
MessageChannel Promise.[ then/catch/finally ]
I/O,事件队列 process.nextTick(Node环境)
setImmediate(Node环境) queueMicrotask
script(整体代码块)  
 

 EventLoop事件循环的具体流程如下:

  1. 从宏任务队列中,按照入队顺序,找到第一个执行的宏任务,放入调用栈,开始执行;
  2. 执行完该宏任务下所有同步任务后,即调用栈清空后,该宏任务被推出宏任务队列,然后微任务队列开始按照入队顺序,依次执行其中的微任务,直至微任务队列清空为止
  3. 当微任务队列清空后,一个事件循环结束;
  4. 接着从宏任务队列中,找到下一个执行的宏任务,开始第二个事件循环,直至宏任务队列清空为止。

5、节流和防抖的区别 

防抖(debounce):触发高频率事件时n秒后只会执行一次,如果n秒内再次触发,则会重新计算。

简单概括:每次触发时都会取消之前的延时调用。

const debounce = (cb) => {
  let timeout;
  return function () {
    clearTimeout(timeout);
    timeout = setTimeout(() => cb.apply(this, arguments), 500);
  };
};

 

节流(throttle):高频事件触发,每次触发事件时设置一个延迟调用方法,并且取消之前延时调用的方法。

 简单概括:每次触发事件时都会判断是否等待执行的延时函数。

const throttle = (cb, delay = 500) => {
  let lastCalled = 0;
  return (...args) => {
    const now = new Date().getTime();
    if (now - lastCalled < delay) return;

    lastCalled = now;
    cb(...args);
  };
};

区别:函数防抖一定连续触发的事件,只在最后执行一次,而函数节流一段时间内只执行一次。

 

6、千位分隔符,有小数

实现方式一:
function format(str){
  if (isNaN(str)) return 'please input a number!';
  let num = str.split('.');
  let ret;
  if (num.length > 1){
    ret = addSplit(num[0])+'.' + addSplit(num[1]);
  }else{
    ret = addSplit(num[0]);
  }
  return ret; }
  function addSplit(str,flag){
    let arr = flag?str.split('').reverse():str.split('');
    arr.unshift(0);
    let ret = [];
    for (let i = 1; i < arr.length; i++){
      ret.push(arr[i]);
      if (i % 3 === 0){
        ret.push(',');
    } 
} return flag?ret.reverse().join(''):ret.join(''); } console.log(format('www.bbbbb')); console.log(format('5454323232.5453')); console.log(format('545454'));

实现方式2

function format(num) {
  var str = num+'';
  return str.split("").reverse().reduce((prev, next, index) => {
    // prev 累计器累计回调的返回值; 表示上一次调用回调时的返回值,或者初始值 init;
     // next 必需。表示当前正在处理的数组元素;
      // index 可选。表示当前正在处理的数组元素的索引,若提供 init 值,则起始索引为- 0,否则起始索引为1;
    return ((index % 3) ? next : (next + ',')) + prev;
  })
}
let num = 1234567890.4323; 
format(num); // '123,456,789,0.4,323'

金额的话,小数需要特殊处理下,小数点不加“,”。正则实现:

function formatThousand(money) {  
  let res = money.toString().replace(/\d+/, function(num){ // 先提取整数部分
    return num.replace(/(\d)(?=(\d{3})+$)/g, function($1){ // ?= 表示正向引用
      return $1+",";
    });
  })
  return res;
}
formatThousand(232323.4343343) // '232,323.43433'
 

7、二叉树的基础概念和遍历方式

  树是一种非线性的数据结构,由n(n>=0)个有限节点组成一个具有层次关系的集合,把他叫做树是因为它看起来像一颗倒挂的树,也就是说它是根朝上,叶朝下,子树是不能相交的,除了根节点外,每个节点有且仅有一个父节点,一棵N个节点的树有N-1条边,树是递归定义的。

二叉树就是树形结构(天然的查找语义),树形结构可以更加高效的进行查找和搜索。

1)遍历:
按照一定的顺序“访问(根据不同的场景,访问的需求是不同的,如打印节点值或是计算节点个数)”这个集合的所有元素,不重复,不遗漏。

2)四大遍历方式
对于二叉树这种非线性结构而言,遍历比线性结构就复杂得多,有四大遍历方式(对于二叉树来讲,遍历操作是其他操作的基础):前中后序遍历、层序遍历。

注意:在写前三种遍历方式时可以借用栈结构,保证做到不重不漏不出错,此时的“访问”就是输出结点的值

a.前序遍历:【preOrder】

先访问根节点,递归访问左子树,递归访问右子树,“根左右”,第一次访问根节点就可以输出节点值。

function treeFrontEach(treeList){
    if (!treeList || treeList.value === null) return null;
    console.log(treeList.value);
    treeFrontEach(treeList.left);
    treeFrontEach(treeList.right);
}

 

b.中序遍历:【inOrder】

先递归访问左子树,然后访问根节点,最后递归访问右子树,“左根右”。

function treeMiddleEach(treeList){
    if (!treeList || treeList.value === null) return null;
    treeMiddleEach(treeList.left);
    console.log(treeList.value);
    treeMiddleEach(treeList.right);
}

 

c.后序遍历:【postOrder】

先递归访问左子树,递归访问右子树,再访问根节点,"左右根"。

拓展:后序的转置输出恰好是前序遍历的镜像:根右左

 

function treeEndEach(treeList){
    if (!treeList || treeList.value === null) return null;
    treeEndEach(treeList.left);
    treeEndEach(treeList.right);
    console.log(treeList.value);
}

  

d.层序遍历:【levelOrder】

按照二叉树的层次一层层访问节点,先左再右。

标签:UDP,遍历,return,第一篇,TCP,面试,num,treeList,套题
From: https://www.cnblogs.com/cczlovexw/p/17090702.html

相关文章

  • 8个你可能不知道答案的常见JavaScript面试问题
    不管你喜不喜欢,棘手的问题仍然会被野外的面试官问到。 原因是,这些问题可以告诉你很多关于你对语言的核心理解,因此你是否适合这份工作。这些问题中涉及的常见概念包括......
  • 面试重点
    新生代Eden与两个Survivor区的解释为什么会有年轻代我们先来屡屡,为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC......
  • HTML面试知识点
    参考自CavsZhouyou/Front-End-Interview-NotebookHTML面试知识点目录目录HTML面试知识点目录DOCTYPE的作用HTML5为什么只需要写<!DOCTYPEHTML>,而不需要引入DTD?H5与H......
  • #技术人为什么写博客# MySQL事务--第一篇
    一、概念事务到底是什么东西呢?想必大家学习的时候也是对事务的概念很模糊的。接下来通过一个经典例子讲解事务。银行在两个账户之间转账,从​​A​​​账户转入B账户1000元,系......
  • #yyds干货盘点# LeetCode面试题:无重复字符的最长子串
    1.简述:给定一个字符串s,请你找出其中不含有重复字符的 最长子串 的长度。 示例 1:输入:s="abcabcbb"输出:3解释:因为无重复字符的最长子串是"abc",所以其长度为......
  • #yyds干货盘点# LeetCode程序员面试金典: 递归乘法
    题目:递归乘法。写一个递归函数,不使用*运算符,实现两个正整数的相乘。可以使用加号、减号、位移,但要吝啬一些。示例1:输入:A=1,B=10输出:10示例2:输入:A=3,B=4......
  • DevOps与CICD面试题
    DevOps术语和定义1. 什么是DevOps答:用最简单的术语来说,DevOps是产品开发过程中开发(Dev)和运营(Ops)团队之间的灰色区域。DevOps是一种在产品开发周期中强调沟通,集成......
  • Docker面试题
    常规题:1.  Docker 和虚拟机有啥不同?答:Docker 是轻量级的沙盒,在其中运行的只是应用,虚拟机里面还有额外的系统。2.    Docker安全么?答:Docker 利用了Lin......
  • C++开发面试题合集
    1.epoll的工作原理(【360实习】C++开发)epoll是一种I/O事件通知机制,是linux内核实现IO多路复用的一个实现。在一个操作里同时监听多个输入输出源,在其中一个或多个输入输出......
  • 常见Linux运维面试题,你答对了吗?
    学习完Linux技术之后,接下来我们就需要面临找工作的事情。谈到找工作,很多小伙伴肯定好奇,面试官会问些什么问题?本为为大家汇总了一些常见Linux运维面试题,希望能够给大家......