欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

字节跳动前端一面

程序员文章站 2024-01-29 14:30:22
...

问问题大概40分钟,期间面试官手动做记录,整个过程,面试官是可以看见你整个屏幕的,所以记得不要想着能百度,清一下你的标签页。问完问题就会让你写代码,想不出来面试官会引导你。虽然写的是40-60分钟一面,但是我面了一个半小时,然后挂了!哈哈哈!

网络和性能

1、TCP和UDP的区别

TCP是面向连接的可靠的协议,

UDP是面向非连接。不可靠的协议。

UDP在传输数据之前不建立连接,因为不建立连接,就不用维护连接状态。并且一台服务机可以向多个客户机发送消息。但是UDP不保证数据传输顺序,还可能丢包

2、用户输入URL之后发生了什么?

3、js放在头部,加载顺序和HTML中的图片加载顺序是怎么样的。

js加载完再请求图片。

这个问题其实涉及到了html、css、js文件加载顺序及执行情况。一起记录了吧。

  1. 浏览器载入html
  2. 碰到head中的link标签引用外部css文件,就向服务器发请求,获得css文件
  3. 浏览器继续载入body部分的代码,利用css文件,就开始渲染页面
  4. 如果发现<img>标签引用图片,就向服务器发请求。浏览器不会等图片下载完,而是直接渲染后面代码。图片下载完之后,由于图片占用一定面积,影响后面的排布,因此浏览器会重新回过头渲染这部分代码。
  5. 碰到<script>标签就运行js代码

1、按照html文档的顺序加载

2、CSS文件放在head中,为了后续渲染。但如果将所有js文件引用都放到中,意味着必须等到全部的JS代码都被下载解析和执行完毕后,才能开始呈现页面的内容(当浏览器遇到),这样会导致页面渲染和用户交互完全被阻塞,延迟期间的浏览器窗口将是一片空白。

3、js阻塞其他资源的加载的原因是:浏览器为了防止js修改DOM树,需要重新构建DOM树的情况出现;

<script src="script.js"></script>
没有 defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的读到就加载并执行。

<script async src="script.js"></script>async,加载和渲染后续文档元素的过程将和 script.js 加载与执行并行进行(异步)。

<script defer src="myscript.js"></script>
有 defer,加载后续文档元素的过程将和 script.js 的加载并行进行(异步)。
script.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。

defer和async的区别
1. 在网络读取(下载)这块儿是一样的,都是异步加载(相较于 HTML 解析)
2. 它俩的差别在于脚本下载完之后何时执行:
    defer是在页面加载完之后执行。
    async是加载之后立马执行。
3. defer是按照加载顺序执行脚本的。
    async 则是乱序执行的,只要它加载完了就会立刻执行,这样如果脚本之间有依赖的话,比如你写的js和jqury,
    你的js比较短,很快加载完了,然后马上执行,但是jqury并没加载完导致发生错误。

4、提高页面加载速度的办法

  1. 减小页面大小
页面的肥瘦是影响加载速度最重要的因素
- 去除不必要的空格、回车、注释。
- 将内联的 css 和 js 移到外部文件
- 页面压缩工具对页面进行压缩,比如:webpack集成的UglifyJS插件
  1. 减少文件数量
减少页面上引用的文件数量可以减少HTTP连接数。
许多JavaScript、CSS 文件可以合并最好合并成一个js 或者 css。
  1. 减少域名查询
DNS查询和解析域名也是消耗时间的,所以要减少对第三方JavaScript、
CSS、图片等资源的引用,不同域名的使用越少越好。

比如:
引用jqury的两种方式
1 下载代码文件至本地项目中,引入。
2 通过 CDN(内容分发网络) 引用它
其他的包最好用1方式下载,这样减少DNS解析域名的时间。
但jqury用使用CDN引用的一个好处:许多用户在访问其他站点时,已经从百度、又拍云、新浪、谷歌或微软加载过 jQuery。
所有结果是,当他们访问您的站点时,会从缓存中加载 jQuery,这样可以减少加载时间。
同时,大多数 CDN 都可以确保当用户向其请求文件时,会从离用户最近的服务器上返回响应,这样也可以提高加载速度。
  1. 缓存重用数据
对重复使用的数据进行缓存。
  1. 优化页面元素加载顺序
首先加载页面最初显示的内容和与之相关的JavaScript和CSS,然后加载HTML相关的东西,
像什么不是最初显示相关的图片、flash、视频等很肥的资源就最后加载。

js放在body的最后面,减少减少inline JavaScript的数量,浏览器parser会假设
inline JavaScript会改变页面结构,所以使用inline JavaScript开销较大。

6、指定图像和table的大小

a. 如果浏览器可以立即决定图像或table的大小,那么它就可以马上显示页面而不要重新做一些布局安排的工作。
b. 这不仅加快了页面的显示,也预防了页面完成加载后布局的一些不当的改变。
c. image使用height和width。

5、图片懒加载原理

1. 获取滚动区域的可视高度(element.clientHeight)
2. 获取目标元素到滚动区域顶部的距离(element.offsetTop)
3. 获取滚动区域滚动条滚动的距离(element.scrollTop)
4. 如果 offsetTop - scrollTop < clientHeight , 元素在可视区域内,可以加载图片,把图片的src属性设置为真实图片的地址

javascript

1、说说promise

2、说说promise和sync的区别

3、事件绑定三种方式,onclick和setEventListener设置多个会执行几次

onclick可以调用多个函数,
onclick="aa();bb();cc();"
如果对一个元素设置多个onclick,将只会执行最后一个,前面的被覆盖。

setEventListener设置几个就执行几个。

<div id="ele">123</div>
<script type="text/javascript">
var ele = document.getElementById('ele');
ele.onclick = (e) => {  console.log('onclick1');}
ele.onclick = (e) => {  console.log('onclick2');}

ele.addEventListener('click', (e) => {   console.log('addEventLisener1');})
ele.addEventListener('click', (e) => {   console.log('addEventLisener2');})
</script>

结果:
onclick2
addEventLisener1
addEventLisener2

4、如何阻止冒泡

w3c的方法是e.stopPropagation(),
IE则是使用e.cancelBubble = true;

什么是冒泡事件?
如在一个按钮是绑定一个”click”事件,那么”click”事件会依次在它的父级元素中被触发 。
stopPropagation就是阻止目标元素的事件冒泡到父级元素。
兼容写法:
window.event? window.event.cancelBubble = true : e.stopPropagation();

5、如何改变默认行为

preventDefault它是事件对象(Event)的一个方法,作用是取消一个目标元素的默认行为。

元素必须有默认行为才能被取消,如果元素本身就没有默认行为,调用当然就无效了。

什么元素有默认行为呢?

如链接<a>,总会跳到一个新页面,有时只是要执行js代码,并不用跳转,这时就要阻止默认行为。

提交按钮<input type=”submit”> 默认行为提交表单radio(checkBox点击(选中)之后出现对勾,这是它的默认行为)等表单元素的默认事件 。
当Event 对象的cancelable为false时,表示没有默认行为,这时即使有默认行为,调用preventDefault也是不会起作用的。

w3c的方法是e.preventDefault()IE则是使用e.returnValue = false;

e.preventDefault ? e.preventDefault() :   window.event.returnValue == false;

原生javascript的 return false只会阻止默认行为.
a.onclick = function(){
    return false;
};
用jQuery的话则既阻止默认行为又防止对象冒泡。
$("#testC").on('click',function(){
    return false;
});


//原生js阻止浏览器的默认行为 
function stopDefault( e ) { 
        //阻止默认浏览器动作(W3C) 
    if ( e && e.preventDefault ) {
         e.preventDefault(); 
    }else{
        //IE中阻止函数器默认动作的方式 
        window.event.returnValue = false;
    }
    return false; 
}
举例说明

<a>消除默认事件的方法

<a href="http://www.baidu.com" onclick="clickEle(this)">使用stopPropagation!</a>
<a href=http://www.baidu.com" οnclick="alert(123);return false">使用return false</a>
<a href="javascript:void(0);">void(0)使地址不发生跳转,不写void(0)也可以使返回为undefined!</a>
<a href="#">#会导致每次点击页面移到最顶部!</a>

function clickEle(e) {
    if (e && e.preventDefault) {
        console.log('阻止默认事件w3c');
        e.preventDefault();
    } else {
        //我用谷歌浏览器执行的是这个,e.preventDefault是undefined?
        console.log('阻止默认事件ie');
        window.event.returnValue = false;
    }
    return false;
}

数据结构

1、说一下你知道的排序算法,具体说一种说说思想。

本来想说冒泡排序,面试官说太简单了,然后我说了堆排序,但是大顶堆最后是从小到大排,我说反了,我想着每次交换到最后的时候,把最后那个数放入另一个数组。但其实不用开另一个数组。
但好像我思想说的也不是很清晰。

2、写代码

出了个题,把两个排好序的数组nums1,muns2合并成一个,数组nums1的长度为m+n,有效数字为m个,nums2的长度为n。

他会说你慢慢想,不要急,我说直接两个for循环对比,时间复杂度n^2,他说再想想,有没有更好的方法,我说合并两个数组再排序,这样就取决于排序的时间,用堆排序就是nlogn。

他就说再想想,然后引导你,因为两个数组是排好序的,如果从前面开始比较,最后的那个数字要移动很多次。然后我说从后向前比较,比如最后一位数字,较大的大的放到n+m-1,这里在写代码的时候,都是从0开始,就是(i+j+1),然后就写了下面的代码。

var merge = function(nums1, m, nums2, n) {

    var j = n - 1;
    var i = m - 1;
    while (i >= 0 || j >= 0) {
        //将最大值放到没排序的最后面
        if (nums1[i] > nums2[j]) {
            nums1[i + j + 1] = nums1[i];
            i--; //i向前移一位
        } else {
            nums1[i + j + 1] = nums2[j];
            j--; //j向前移一位
        }
    }
    console.log(nums1);
};
merge([1, 2, 3, 0, 0, 0], 3, [2, 5, 6], 3);

虽然出来了,但是面试官可能觉得时间太长,而且边界条件可能有些不满足,但时间太长了,面试时间已经一个半小时了。

然后等了5分钟,就收到挂了的消息,虽然一面都没过,但还是觉得面试官人很好,要接着努力呀!