阿里云OSS前端开发暑期实习一面面经

半个月前师兄内推的简历,昨天下午一面。形式比较简洁,没有hr联系,直接是阿里云的工程师联系的我约的面试。也没有用视频会议,直接电话面试+在线IDE做题。基本上没有问什么八股文,主要是深挖简历,所以问的问题主要都跟简历内容相关。

面试内容

  1. 自我介绍

问:前端如何检测网络状况,弱网?(看简历里写了做了app弱网模块)

答:网络情况是客户端那边做的,他们判断设备网络波动大,再调我们弱网组件。

问:如果是前端来做,有什么方法?

答:可以设定网络请求最大次数,重复请求超限则判定为弱网。曾经查过navigator.onLine这个属性,但测试发现这个属性没有作用

下来自己查了一下,一般前端监测网络状况有以下几种方案:

(1)window.navigator.onLine属性(布尔值,脱机状态下为false),缺点是有时候结果不准确,会受到其他因素影响。换句话说,就是结果为true也不意味着浏览器能联网。可能电脑上安装的其他虚拟软件会影响这个属性值,如虚拟机,虚拟网卡。我自己测试发现始终都是true的原因在于我电脑上装了Zerotier(虚拟局域网),到控制面板里面禁用之后,navigator.onLine就是正常的值了

(2)window.addEventListener('online', cb),本质上和(1)一样

(3)window.navigator.connection可以拿到网络连接相关的属性,但存在兼容性问题,且测试发现结果相对固定,无法监测实时网络状况

(4)Ajax测速,本质和我的回答类似,使用一个已知大小的文件(可以是图片或者其他文件资源,不需要太大)作为测速源,用img标签的src属性引入,监听onload、onerror事件,或者根据原生ajax请求分别在不同阶段标记时间,用文件大小/时间差得到一个较为模糊的实时网速结果,效果类似于windows中的ping命令

综上所述,通常会采用多种方案组合以达到比较好的监测兼容性和准确性。

3.

问:省市区三级联动的数据是从哪里来的?(简历里写了做了城市相关的配置)

答:用的是npm库里面的element-china-area-data这个包。没有用后端的城市数据,因为结构太复杂了。

问:那意思是会打包到前端工程里咯,省市区三级联动数据量可不小呀

答:当时业务需要只用到了省市两级联动,所以中国600多个市也还好?(自己下来回顾了发现打包时element-china-area-data这个包包含了省市区三级联动的数据,官方给的一个简单的Vue示例打包后足足大小有6.25MB,看来省市区三级联动的数据量还是很大的)

问:好我理解了,客户端那边可能对于打包后的文件体积要求严格一些

4.

问:看你简历上写了微信支付的授权,讲以下微信授权的流程吧?

答:我做的微信的授权分为两类。一类是微信公众号/小程序的登录授权,这种授权很简单,客户端调用微信官方登录API拿到登录凭证code,再拿这个code去微信授权url请求openid就可以了;一类是微信支付的授权,微信支付的流程比较复杂,主要有以下步骤:①前端用户选择商品,商品编号和金额发给后端,后端生成订单告知微信支付系统,返回给前端时间戳、数字签名等支付信息,前端组装信息后拉起微信支付API,用户输入密码完成支付,微信支付系统返回支付状态,前端做对应处理。

5.

问:简历上写了动态计算rem实现多端适配,能讲讲怎么做的吗?

答:rem是相对单位,本质是相对于根元素字体大小。在Vue项目的App.vue中根据UI给出的设计稿尺寸进行动态计算,如当时我们UI给的设计稿一般是750px宽的,我们自己定义的倍率是100,那就是用设备的宽除以750,再乘以100作为根元素字体的大小。后续设计样式全部使用rem替代px。

问:有没有考虑过平板这种横屏的问题,如果都使用rem的话会把宽高都放大,但有些情况是只需要放大宽或者放大高的,这种情况怎么办?

答:我负责的部分好像都是平板竖着用的,至于平板横屏的适配当时是我师傅做的,我没有负责这一块,不好意思,我不太知道

下来自己查了一下,横屏适配一般有如下方法:

(1)媒体查询:

@media screen and (orientation: landscape) {
  /* 横屏布局样式 */
}

(2)viewport控制页面缩放:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, viewport-fit=cover" />

任何情况下都填满屏幕,且不允许缩放。只能起到初始缩放适配的作用,还需要配合其他方法做适配优化。

(3)js监听屏幕旋转orientationchange事件,再根据orientation状态做两套方案

想起来当时项目里师傅写的有portrait和landscape,猜想应该是对横屏和竖屏做了两套方案,原理应该就是(3)。有两种思路:1.根据高度来设计UI稿件,跟高度绑定后用vh作为单位;2.沿用竖屏的方案,计算当前宽高比和竖屏差多少,整体加一个transform: scale(可以在不同的方向定义不同的缩放值)

6.

问:你知道1px问题吗?

答:听说过,但目前没有遇到过。

问:可以去多了解一些。

对于1px问题,需要先了解几个概念:

  • 屏幕尺寸:指屏幕对角线的长度,常说的显示器尺寸24,27,32英寸指的就是对角线长度;
  • 分辨率:指宽度和高度上最多能显示的物理像素点个数,常说的显示器/图像/视频分辨率有720p(1280*720),1080p(1920*1080),2K(2560*1440),4K(3840*2160),所以1080p,2K,4K宽高像素点个数是\sqrt{2}倍的关系,总像素点个数是2倍的关系;
  • ppi:pixels per inch,屏幕像素密度,即每英寸聚集的像素点个数,这里的每英寸指的是对角线长度
  • dpi:dots per inch,每英寸像素点,用于描述印刷行业的墨点密度,类比ppi
  • *dpr:device pixel ratio,设备像素比,指设备物理像素和设备独立像素的比值,也可以理解成一个px的能显示的物理像素点的个数。PC端和早期手机的dpr都是1,即1逻辑像素对应1物理像素
  • 物理像素:屏幕显示的最小颗粒,是物理真实存在的,单位是pt
  • 逻辑像素:CSS样式代码中定义的像素,是为了使网络资源浏览起来更舒服,也就是让两个屏幕尺寸一样大的设备,呈现的同一个图片看起来差不多是一样大的而发明的

所谓的1px问题,本质就是如何解决不同屏幕上1逻辑像素对应不同比例的物理像素的问题。使用rem作为单位的话需要在初始化rem时就把dpr代入计算。使用vh,vw的百分比单位不会受到影响。

7.

问:看你写了一个OJ平台,在展示用户代码时,前端应该如何防范XSS攻击?如果提交恶意代码嵌入web内容中该怎么办?(OJ前端是React做的)

答:不好意思,我不太知道,可能是跟React的JSX语法有关系?

问:其实是React本身的特性帮助避免了XSS攻击,下来你去了解一下。

对于React中的XSS攻击问题,React的自动转义和JSX语法帮React规避了风险。

  • 自动转义:React在渲染HTML和DOM时会对"'&<>进行自动转义处理,如<会被转义成<
  • JSX语法:Babel在编译JSX时会把JSX转化成React.createElement,其中可以防范构造XSS攻击
  • ps:在React中使用dangerouslySetInnerHTML是有被XSS攻击的风险的,因为不会走上述流程检查

对于Vue中的XSS攻击,可以使用如下方法规避:

  • 使用{{ msg }}插值表达式:Vue像React一样会对其进行自动转义
  • 使用CSP:content scurity policy,内容安全策略,可以通过两种方式开启CSP:1.设置HTTP请求header中的Content-Security-Policy字段;2.设置meta标签<meta http-equiv="Content-Security-Policy">
    • 谨慎使用v-html属性:类比dangerouslySetInnerHTML

    8.

    应用题:

    计算localStorage中一个item能存储的最长的字符串长度(计算localStorage最大的存储大小),大致思路如下:

const solution = () => {
	for(let i=0;i<Number.MAX_VALUE;i+=10) {
		try {
			localStorage.setItem('test', new Array(i*1024).join('a')) // 一次性增加1KB的长度,少了浏览器会崩溃
		} catch(e) {
			return i
		}
	}
}
console.log(solution()) // 5120KB -> 5MB

二分查找优化:

const solution = (left, right) => {
	if(left>=right) return left
	const mid = left+Math.floor((right-left)/2)
	try {
		localStorage.setItem('test', new Array(mid).join('a'))
	} catch(e) {
		return solution(left, mid)
	}
 	return solution(mid+1, right)
}
console.log(solution(0, Number.MAX_VALUE)) // 5238439B -> 5.1MB

结论:localStorage中最多可以存5MB左右的数据。

第一次写面经,当作自己总结和进步的途径,互相勉励!

全部评论
校友厉害👍🏿
1 回复 分享
发布于 2023-03-04 09:53 北京
校友 冲
1 回复 分享
发布于 2023-03-05 08:27 湖北
点赞 回复 分享
发布于 2023-03-05 10:13 浙江
点赞 回复 分享
发布于 2023-03-06 20:45 江西
校友牛逼
点赞 回复 分享
发布于 2023-03-09 04:15 湖北

相关推荐

10-28 14:42
门头沟学院 Java
watermelon1124:因为嵌入式炸了
点赞 评论 收藏
分享
牛客618272644号:佬携程工作怎么样,强度大吗
点赞 评论 收藏
分享
Pandaileee:校友加油我现在也只有一个保底太难了
点赞 评论 收藏
分享
29 83 评论
分享
牛客网
牛客企业服务