4

一次前端面经的解答

 3 years ago
source link: https://zhuanlan.zhihu.com/p/359350878
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

一次前端面经的解答



金三银四的前端社招面经​juejin.cn

目前前端招聘标准越来越高,上面分享的面经很具有代表性,但是只有题目没有答案,所以我就挑选了字节的1面2面,做了简单的回答,这是本人未经过加工的回答,肯定会存在纰漏,但是可供大家参考。后续会将正确的答案汇总,欢迎评论区讨论。

1、tcp 和 udp 的区别和使用场景?

tcp具有面向连接,流量控制,拥塞控制,重传机制。tcp传输过程是安全的,具有丢包重传等性质,也存在队头阻塞,每次链接需要3次握手等耗时问题,适合注重安全稳定性的场景,比如web应用。

udp不是面向连接的,因为不具备内容完整性校验和重传机制等功能,所以丢包率比tcp高,但是协议更加简单,无需多次握手,更快速,适合音视频等场景。

2、 quic 基于 udp 怎么保证可靠性?

上面说了udp不是面向链接的,而且udp传输的时候,不携带源端IP和源端口号,无法重试。需要添加源IP和端口号,并且增加序列,保证内容完整性。

3、 讲一下同源策略和跨域方案?CORS 的几个头部是什么?

浏览器为了保证资源的安全性,实施了同源策略,包括协议,域名,端口一致。

jsonp,通过script标签,src天然跨域。cors,浏览器和服务端同时设置支持跨域,cross origin resource sharing,也可以设置为单独域名,也可以设置为*。

4、 讲一下 react fiber?

fiber是纤维的意思,它是react里的一种数据结构,链表。存储了当前组件的所有信息,每一个虚拟DOM都对应一个fiber,每一个fiber通过链表相连。react进行虚拟Dom对比时,就是从根fiber开始对比。

5、 vue 双向绑定原理?

本质是一个发布订阅模式,通过Object.defineProperty或Proxy实现中间存储的转发功能。拦截数据的getter,setter操作,绑定数据,并在触发变更时触发更新。

6、 redux 和 mobx 的区别和使用场景?

它们都是状态管理框架,redux是一种流式管理框架,通过dispatch,action,reducer流程,保证状态可观测。并且只能在reducer修改数据,保证数据只在一个地方可变更。而mobx是响应式,有点像vuex,底层也是通过Proxy实现。两者都使用高阶组件的方式,改变外层的props,触发子组件的render。当然也在shouldComponentUpdate里做了一层浅比较。

7、 typeof null?null instanceof Object?

"object",true。typeof null就是js的一个错误设计

8、typeof 可以判断哪些类型?instanceof 做了什么?

基础数据类型,除了null。基础引用类型,Object,Array,Function。自定义的类或者Date,RegExp等不支持。

instanceof检测当前对象是否属于后面的对象,通过原型链判断。判断原型链上的type属性?

9、 实现一个 bind 函数

是否可以使用apply,不能用apply就只能用eval

function bind(obj,ctx){
return (...args)=> {
  	obj.apply(ctx,args);
} 
}

10、 求数组里面最大连续项的和

[1, -2, 3, 4, -1, 5];

=> 11

function getMaxSum(arr) {
  let dp = new Array(arr.length).fill(0);

  dp[0] = arr[0];
  
  let maxSum = 0

  for (let i = 1; i < arr.length; i++) {

    dp[i] = Math.max(arr[i], dp[i -1] + arr[i]);

    if (dp[i] > maxSum) {
      maxSum = dp[i];
    }
  }

  return maxSum;
}

console.log(getMaxSum([1, -2, 3, 4, -1, 5]));

11、 event loop

event loop不同的宿主环境有不同的表现。

在浏览器里,event loop分为macro task和micro task,loop从一个宏任务开始,不断循环。如果没有异步任务,就同步执行。如果有微任务就插入当前宏任务的队尾,如果有宏任务,就插入维护宏任务的队列中。

宏任务有,脚本执行,setTimeout等函数,用户交互等,ajax,I/O。微任务有,promise,await async。mutation,intersectionObserver,postMessage等。

在node中,为了保证时间函数到点执行,每一个event loop都会先检测setTimeout,interval是否到期。以及新增nextTrick,再当前eventLoop结束时执行的回调,而当前注册的setImmdeiate事件将在下次event loop执行。

Node中执行的优先级

timers

check阶段,setImmediate回调

nextTrick执行阶段。

1、怎么优化 h5 的加载速度?

工程和细节方向两个方向优化。

工程方向,打包内容,资源加载类型等

细节方向,熟悉浏览器特性,比如减少重绘重排。React框架,优化代码。渲染机制,懒加载(图片,资源等)。

2、离线包怎么更新?怎么知道需要打开哪个离线包?

每次进入一个新页面,异步检查配置文件,是否需要更新。

通过版本号。

3、js bridge 通信原理?

以Android为例。

js bridge充当中间者的作用,让js和Android可以双向通信。Android将事件注入到前端上下文window中,有两种事件,一种是回调事件,和React生命周期相似的事件;另一种是预留给前端主动调用Android的事件。这样前端既能主动调用Android,也能注册Android的某些事件,等待回调。因为两者只能通过Json String通信,所以前端调用Android之后的回调事件,是注册到Bridge的队列中,通过自增id标识,下一个回调事件是什么。

4、怎么实现 h5 页面秒开?

离线包,懒加载,service worker。

5、明明不是同一个语言,为什么 js 和 native 可以通信?

依赖于webview这个载体,webview是存在于native的上下文(在Android中它是一个组件),而js的上下文是存在于webview。

6、怎么实现 js bridge 跨多个 app 共用?

封装成sdk。把细节抽象。

7、grpc 相比 http 的优势?

grpc,跨远程调用,只是跨进程,最多需要将数据序列化和反序列化。而http需要走网络请求。

8、rpc 的调用流程?前端怎么调用 grpc 的?

进程A的应用调用进程B的应用。我记得在vscode里,可以有专门的包支持rpc,它内部应该封装了进程间调用的细节。

9、为什么要用 grpc?

更快,心智负担更小,像调本地函数一样调用

10、服务发现为什么用 ip,而不用域名?

域名需要DNS解析。域名本来就是方便用户记忆和美观的。

11、怎么做 DNS 预解析?

请求DNS支持解析的服务器。全球有专门做DNS解析的服务器,而每个国家,每个地方又会缓存一些常用的IP和域名的映射表。电脑和浏览器为了优化打开速度,也会缓存DNS结果,所以有时候DNS更新了,但是还是访问之前的网站。

12、怎么实现移动端的布局?

可以通过百分比,rem,vw,vh等自适应方式实现布局。

13、iOS 下软键盘输入框遮挡遇到过问题么?怎么解决顶不起来的问题?

低版本IOS会出现,键盘弹起,但是输入框被遮挡的问题,可以键盘弹起事件,自定义一个滚动事件,滚到输入框的位置。

14、实现两个大数相加

之前写过,我就直接粘贴了。可以不用转成数组,直接用字符串的charAt获取单个值,这个算法注意进位carry即可。

/**
 * @param {string} num1
 * @param {string} num2
 * @return {string}
 */
var addStrings = function(num1, num2) {
  const arr1 = num1.split('').reverse();
  const arr2 = num2.split('').reverse();
  let carry = 0;
  let index = 0;
  let result = [];

  while(index + 1 <= arr1.length || index + 1 <= arr2.length) {
      let a1 = 0;
      let a2 = 0;
      if (arr1[index]) {
          a1 = arr1[index];
      }

      if (arr2[index]) {
          a2 = arr2[index];
      }

      const total = Number(a1) + Number(a2) + carry;
      if (total >= 10) {
          result.push(total - 10);
          carry = 1;
      } else {
          result.push(total);
          carry = 0;
      }

      index++;
  }

  if (carry) {
      result.push(1);
  }

  return result.reverse().join('');
};

addStrings('0', '0')

15、求一个数组最大子项的和,要求这些子项在数组中的位置不是连续的

不懂什么意思?求全部的正数相加?

16、常用的 react hooks 方法

useState、useEffect、useMemo、useCallback、useReducer、useLayoutEffect、useRef、useContext。

17、useState 怎么做缓存的?

mount阶段将数据缓存到当前虚拟DOM的fiber上,update时,前比较两次的值。如果值未改变,还用缓存的值。这个回答好像有点问题。

18、react fiber 是什么?

1面回答过

19、怎么解决 useState 闭包的问题?

这个是问怎么解决useEffect闭包问题吧,传入依赖项即可。或者将state值赋值给useRef,这样每次useRef上的值都是最新的值。

20、useReducer 比 redux 好在哪里?

react内置支持。支持依赖项不更新,不触发useReducer的回调。更加轻量,无需引用框架,无需维护一个大的store树。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK