字节跳动前端日常实习一二三面面经(offer还愿)

脑洞前端

共 8971字,需浏览 18分钟

 · 2021-07-09

作者:Jieunsi

https://www.nowcoder.com/discuss/670720?from=kaifazhe0630

时间线

5.19投递简历

5.20hr约一面

5.24一面

5.25中午一面通过,hr约二面时间。本来约的是6月1号,但面试官临时请假,改到了3号

6.3二面

6.4下午二面通过,hr约三面时间

6.8三面

6.9中午三面通过,hr约10号三面

有些问题可能不是面试官的本意,还有一些问题没听懂,从场景题提取问题出来还是挺难的 其实15号中午的时候就offer了,现在来添加面经答案,答案只是我的见解哈,有些部分也没给出来,如果有错误欢迎指出

一面(牛客50mins)

  1. 怎么判断两个网站是否同域

浏览器从一个域向另一个域的服务器发送请求来访问其资源。浏览器的同源策略:协议、域名、端口号一致。

  1. 保持登录状态能够使用什么实现

cookie,token

  1. externals是怎么实现的
  2. 你这些外部的资源是存在公共的CDN上,还是有现成可以直接用的托管CDN

回答了公共的CDN

  1. 是哪种类型的CDN呢,具体是哪些域名
  2. 为什么CDN能够加速用户访问一个网站,它的原理是什么

最简单的CDN网络由一个DNS服务器和几台缓存服务器组成:

i. 当用户点击网站页面上的内容URL,经过本地DNS系统解析,DNS系统会最终将域名的解析权交给CNAME指向的CDN专用DNS服务器。

ii. CDN的DNS服务器将CDN的全局负载均衡设备IP地址返回给用户


iii. 用户向CDN的全局负载均衡设备发起内容URL访问请求


iv. CDN全局负载均衡设备根据用户IP地址,以及用户请求的内容URL,选择一台用户所属区域的区域负载均衡设备,告诉用户向这台设备发起请求


v. 区域负载均衡设备会为用户选择一台合适的缓存服务器提供服务,选择的依据包括:根据用户IP地址,判断哪一台服务器距用户最近;根据用户所请求的URL中携带的内容名称,判断哪一台服务器上有用户所需内容;查询各个服务器当前的负载情况,判断哪一台服务器尚有服务能力。基于以上这些条件的综合分析之后,区域负载均衡设备会向全局负载均衡设备返回一台缓存服务器的IP地址


vi. 全局负载均衡设备把服务器的IP地址返回给用户


vii. 用户向缓存服务器发起请求,缓存服务器响应用户请求,将用户所需内容传送到用户终端。如果这台缓存服务器上并没有用户想要的内容,而区域均衡设备依然将它分配给了用户,那么这台服务器就要向它的上一级缓存服务器请求内容,直至追溯到网站的源服务器将内容拉到本地

  1. 怎么确定哪个CDN节点离用户最近呢

上个问题答案的第4.5点

  1. 假设同样的资源,我用域名去访问,访问到哪个服务器取决于什么?

DNS

  1. DNS解析过程

简单的来说,浏览器先检查自身有没有缓存,如果没有就检查操作系统有没有缓存,如果还是没有就会向本地域名服务器发起一个请求来解析这个域名;如果本地域名服务器还是没有,则会从根域名服务器开始递归查找域名,直到找到为止。

  1. DNS解析过程中,某个DNS服务器的记录被篡改过,指向一个恶意网站,这种情况会对用户的访问造成安全风险,这么防范。怎么防范DNS污染(应该是这个问题)

感觉这个问题不是很重要

  1. DNS使用什么网络协议

DNS区域传输的时候使用TCP协议:

1.辅域名服务器会定时(一般3小时)向主域名服务器进行查询以便了解数据是否有变动。如有变动,会执行一次区域传送,进行数据同步。区域传送使用TCP而不是UDP,因为数据同步传送的数据量比一个请求应答的数据量要多得多。

2.TCP是一种可靠连接,保证了数据的准确性。

域名解析时使用UDP协议:


客户端向DNS服务器查询域名,一般返回的内容都不超过512字节,用UDP传输即可。不用经过三次握手,这样DNS服务器负载更低,响应更快。理论上说,客户端也可以指定向DNS服务器查询时用TCP,但事实上,很多DNS服务器进行配置的时候,仅支持UDP查询

  1. 除了打包体积减小,还有哪些手段可以提升用户的访问速度

缓存,懒加载,代码优化,SSR...

  1. HTTP缓存怎么设置

通过设置Cache-Control/Pragma、Expires(过期时间)、Last-Modified/Etag。

  1. 确定协商缓存有效性的协商过程是怎么样的

在第一次请求服务器时,服务器会返回资源,并且返回一个资源的缓存标识,一起存到浏览器的缓存数据库。当第二次请求资源时,浏览器会首先将缓存标识发送给服务器,服务器拿到标识后判断标识是否匹配,如果不匹配,表示资源有更新,服务器会将新数据和新的缓存标识一起返回到浏览器;如果缓存标识匹配,表示资源没有更新,并且返回 304 状态码,浏览器就读取本地缓存服务器中的数据。

  1. 有些资源打开页面的时候不需要,需要的时候在加载

懒加载

  1. 不同类型的东西处理方式不一样,例如图片,js代码,他们分别怎么懒加载

js通过设置defer和async

  1. 建议图片懒加载多去看看实现方法
  2. 有没有更简单的方式去判断图片离浏览器顶部距离的方法

面试官建议:intersectionObserver?这个API,可以监控一个元素即将进入到窗口的范围

  1. 说一下Vue的工作原理(响应式原理)

Vue响应式底层实现方法是 Object.defineProperty() 方法,该方法中存在一个getter和setter的可选项,可以对属性值的获取和设置造成影响

1. 当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue将遍历此对象所property,并使用 Object.defineProperty 把这property 全部转为 getter/setter。


2. 这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在 property 被访问和修改时通知变更。


3. 每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。

  1. 我改变了一个Data中数据后,他怎么更新到实际页面的DOM,这个过程是怎样的
  2. 模板里面,对于一个字段的引用是怎么收集的
  3. 对于这个字段的依赖是在什么时候建立的呢,是怎么建立的呢
  4. 假设有A,B两个请求,希望在A请求完后拿到一个结果,之后将A的结果作为参数给B,B发起请求,这样的过程要怎么实现

异步操作

  1. 如果A,B没有依赖关系,希望两个都拿到结果之后,在执行一些操作,要怎么实现

Promise.all

  1. 你提到Promise.all,那假设浏览器没有这个东西,你给我整一个
function myPromiseAll(promises{
  let results = [];
  let promiseCount = 0;
  let promisesLength = promises.length;
  return new Promise(function(resolve, reject{
    for(let i = 0; i < promises.length; i++){
      Promise.resolve(promises[i]).then(function(res{
        promiseCount++;
        results[i] = res;
        // 当所有函数都正确执行了,resolve输出所有返回结果。
        if (promiseCount === promisesLength) {
          return resolve(results);
        }
      }, function(err{
        return reject(err);
      });
    }
  });
};
  1. 反问

部门:交叉面试

建议:多实践

二面(牛客38mins)

  1. 简单问了下项目的东西
  2. 项目里有订单管理的功能,一般来说订单要考虑什么状态呢
  3. 如何实时拿到这些状态呢
  4. 最近在学什么呢
  5. vue框架有什么特点

数据驱动、组件化

  1. 手撕代码(写完说思路)
function bubbleSort(array){
    let length = array.length;
    for(let i = 0; i < length - 1; i++){
        for(let j = 0; j < length - i -1; j++){
            if(array[j] < array[j+1]){
                [array[j],array[j+1]] = [array[j+1],array[j]];
            }
        }
    }
}

let test = [6,8,4,5,1];
bubbleSort(test);
console.log(test);

function quickSort(array){
    if(array.length < 2return array;
    let leftArray = [];
    let rightArray = [];
    let base = array[0];
    array.forEach((element) => {
        if(element > base){
            leftArray.push(element);
        } else if(element < base){
            rightArray.push(element);
        }
    });
    return quickSort(leftArray).concat(base,quickSort(rightArray));
};

let test2 = [5,3,2,1,4];
let res = quickSort(test2);

console.log(res);

实现一个函数,把一个字符串数组(['zm', 'za', 'b', 'lm', 'ln', 'k'])格式化成一个对象 { 'b': ['b'], 'k': ['k'], 'l': ['lm', 'ln'], 'z': ['za', 'zm'] }

这道题没写完整,说了下思路用伪代码写了下。

  1. 近一两年的规划
  2. 为什么选择字节

三面6.8(牛客38mins)

  1. 聊了下之前的笔试
  2. 参与之前的面试下来,有什么感受,有没有总结出自己的长处与短板

提到了要深入学原理源码啥的

  1. 你打算怎么看源码
  2. 聊一下项目
  3. 为什么做这个项目
  4. 项目有没有你自己想的一些功能
  5. 怎样从零搭建项目

感觉就是看你是不是真的自己做了一遍

使用vue-cli初始化的步骤

  1. vue-cli主要帮你完成了哪些事情

1.ES6代码转换成ES5代码 2. scss/sass/less/stylus转css 3. .vue文件转换成js文件 4. 使用 jpg、png,font等资源文件 4. 自动添加css各浏览器产商的前缀 5. 代码热更新 6. 资源预加载 7. 每次构建代码清除之前生成的代码 8. 定义环境变量 9. 区分开发环境打包跟生产环境打包 ......

  1. 其中生成的那些文件,分别是干什么的
  2. packjson文件里有一些key,value。其中一个key叫dependencies和devDependencies,能说说作用吗

package.json:

主要用来定义项目中需要依赖的包


package-lock.json:


在 npm install时候生成一份文件,用以记录当前状态下实际安装的各个npm package的具体来源和版本号。


'^' :放在版本号之前,表示向后兼容依赖,说白了就是在大版本号不变的情况下,下载最新版的包


项目中引入的包版本号之前经常会加^号,每次在执行npm install之后,下载的包都会发生变化,为了系统的稳定性考虑,每次执行完npm install之后会对应生成package-lock文件,该文件记录了上一次安装的具体的版本号,相当于是提供了一个参考,在出现版本兼容性问题的时候,就可以参考这个文件来修改版本号即可。



i.“dependencies” 运行依赖,需引入页面使用


ii.“devDependencies” 开发依赖(生产环境使用),只是开发阶段需要

  1. babel.config.js的作用

Babel是一个JS编译器,主要作用是将ECMAScript 2015+ 版本的代码,转换为向后兼容的JS语法,以便能够运行当前和旧版本的浏览器或其它环境中。


Vue项目中普遍使用ES6语法,若要求兼容低版本浏览器,就需要引入Babel,将ES6转换为ES5。

  1. babel怎么把es6转成es5
  2. es6哪些特性你觉得比较常用或者好用
  3. let const var区别

变量提升方面:var声明的变量存在变量提升,即变量可以在声明之前调用,值为undefined。let和const不存在变量提升问题(注意这个‘问题’后缀,其实是有提升的,只不过是let和const具有一个暂时性死区的概念,即没有到其赋值时,之前就不能用),即它们所声明的变量一定要在声明后使用,否则报错。


块级作用域方面:var不存在块级作用域,let和const存在块级作用域


声明方面:var允许重复声明变量,let和const在同一作用域不允许重复声明变量。其中const声明一个只读的常量(因为如此,其声明时就一定要赋值,不然报错)。一旦声明,常量的值就不能改变。

  1. 回到项目,登录功能怎么实现的
  2. token怎么保持登录状态

当用户请求页面,输入用户信息,服务端经过验证后,会生成一个token安全令牌(随机字符串),并返回给客户端,当客户端发送下一次请求的时候,直接携带这个token,服务端识别后,就可以直接访问页面,不需要再次登录了

  1. sessionStorage有什么优势,token应该放在哪

sessionStorage的特点

+各个标签页的sessionStorage 是独立的 。+在a标签页写入修改删除sessionStorage ,不会影响到已经打开的标签页中的sessionStorage 。+通过a标签,window.open,window.location,windows.history ,右键复制 等方式在新标签页,本页,iframe ,新窗口中打开新页面,当前标签页的 sessionStorage 会传递到新页面。+通过按住 ctrl键打开新标签页,或者右键菜单打开新标签页,新窗口 ,当前标签页的 sessionStorage 是不会传递到新页面的 。+关闭某个标签页,该标签页的sessionStorage 会被销毁。不影响其他标签页或者窗口 。+在某个标签页即使跳出了当前站点,返回来的时候,sessionStorage 也还在的 。


鉴于它有以上特点 :1,可以用来做多账户登录 , sessionid 不用cookie存储,用 sessionStorage 来存储。spa应用比较适合 。

token存放位置参考

Cookie 的作用是与服务器进行交互,作为 HTTP 规范的一部分而存在 ,而 Web Storage 仅仅是为了在本地“存储”数据而生。而token的安全和性能都是中肯的,唯一的问题就是cookie的存储性能和提取安全性太低,而localstorage更安全而且能够跨会话实现身份鉴别,很明显token应该存在localstorage里。

  1. localStorage里可以存图片吗,怎么存

我们的想法是做到将已经当前页面中已缓存的图片保存到本地存储中。不过就像我们之前已经确定的,本地存储只支持字符串的存取,那么我们要做的就是将图片转换成 Data URI 。其中一种实现方式就是用canvas元素来加载图片。然后你可以以Data URI的形式从canvas中读取出当前展示的内容。

  1. token能放在cookie里吗

可以

  1. xss能不能取到sessionStorage里的数据

可以

  1. hash路由和history路由

  2. 除了这个项目还有别的项目吗

  3. 翻页功能怎么实现

  4. 数据是前端来分页还是后端来分页

  5. 能实现前端分页吗

  6. 怎么实现

  7. 数据存哪

  8. vuex有用过吗

  9. vuex的目的是什么

  10. 已经有sessionStorage这类的放数据的地方,为什么还要有vuex,有什么特别的价值吗

  11. 聊了下笔试

  12. 问了下是不是还没有开始复习算法和数据结构

  13. 说一个最近在复习的算法再说说对应的例题

说了道最大无重复子串,双指针

  1. 复杂度

  2. 动态规划一般解决什么样类型的问题

  3. 动态规划相比于回溯,有什么优势

  4. 异步组件的懒加载是你自己想的还是教程有的

  5. 怎么实现懒加载

  6. 优化效果有看过吗

  7. 看到面评,问实习是想积累经验还是想转正

  8. 反问

部门:技术中台

看重实习生哪些方面

碎碎念

字节的面试官是能够看到你之前投递的简历,参加过的笔试和面试结果,所以如果要投的话一定要认真对待面试和笔试吧。另外我看到牛客网也有前端的课程,笔试面试会涉及到的知识点里边基本都会涵盖,如果大家不知道从哪里开始学起的话可以报名这种课程。

爱心三连击

1.看到这里了就点个在看支持下吧,你的在看是我创作的动力。

2.关注公众号脑洞前端,获取更多前端硬核文章!加个星标,不错过每一条成长的机会。

3.如果你觉得本文的内容对你有帮助,就帮我转发一下吧。


浏览 38
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报