某蚂蚁子公司,前端通关挑战中(面试完成)
前言
哈哈,我又来给云大佬们交代面试经验了,这里是懂一点项目管理和前端开发的狗子。
这次是属于我这里偏大的厂了,整体面试感觉没那么难,问项目的话我都能答出来,毕竟之前自称解决方案专家(手动狗头)。
背景
- 主要的技术栈是Vue + Vite。
- 主要的项目经验是重构了一个大型控制台、用G6开发过自定义的图形。
- 算法没咋刷(哭死)
以下很多内容和我的简历相关,写的不是特别细,毕竟不是面真大厂,大家看自己有用的哈,千人千面,我就都写了。
我们话不多说,进入正题。
一面
你是怎么预研这几个图标库,做技术选型的吗?
简历原文:预研到ECharts、Antv G6和GoJs等多个图表库后,我们决定采用Antv G6。
嘿嘿,聊这个,我当时专门做了设计文档,个人回答是:
- 公司内部是否有使用(优先)
- 性能:加载大数据量的能力
- 社区、文档是否全面
- 框架是否有持续更新
- 满足业务需求(重要)
原因
- 综合来看G6和Echarts的文档,社区比较多
- 公司内部用G6
- AntV G6基于Canvas,适合处理较大规模的图表,而ECharts则更适合一般规模的数据,当然GoJs也具备良好的性能
其他方向
其实呢,还有一些方向可以做技术选型:
- 可定制性、可扩展性:也就是是否满足需求,如果你需要高度定制的图表,ECharts和AntV G6都提供了一定的可定制性。
- UI风格和配色
- 学习曲线
echarts的原理
啊?这,我不会,真不会。。。
简单聊了一下是canvas做的。
于是我搜了一下该如何答:
总的来说就是两点:
echarts.js
负责图表的创建、初始化、主题、事件、动画、数据加载等功能。zrender.js
负责图表的绘制和交互处理,通过对HTML5 Canvas的封装实现图表绘制和动画效果
再往深处?不必要吧。。。
HTML5除了Canvas可以画图还有其他方法可以画图吗?
我答:D3.js 可以用svg来画图
当涉及在网页上绘制图形时,HTML5 提供了多种方法,除了使用 Canvas,还有其他选项:
-
SVG(可缩放矢量图形) :
- SVG 是一种基于 XML 的图形语言,用于描述二维图形和动画。
- 与 Canvas 不同,SVG 是矢量图形,可以无损缩放而不失真。
- 使用
<svg>
标签来创建 SVG 图形,然后通过属性和元素来定义形状、路径、文本等。
-
CSS3:
- CSS3 可以用于创建一些简单的图形效果,例如渐变、阴影、圆角等。
- 通过 CSS 属性,你可以对元素的样式进行控制,从而实现一些基本的图形效果。
-
WebGL:
- WebGL 是一种基于 OpenGL 的图形库,用于在浏览器中创建复杂的3D图形和动画。
- 它允许你直接操作图形硬件,以高效地渲染图形。
但最终还是以canvas和svg为主。
canvas和svg的区别
当涉及在网页上绘制图形时,Canvas 和 SVG 是两种不同的技术,各自有其特点和用途:
-
Canvas:
- Canvas 是一个HTML5元素,用于通过JavaScript绘制2D图形。
- 图像在Canvas上以像素为单位绘制,类似于绘制位图。
- 一旦图像绘制完成,浏览器不再关心它。如果位置发生变化,需要重新绘制。
- 适合图像密集型的游戏,但需要频繁重绘。
-
SVG(可缩放矢量图形) :
- SVG 是一种基于XML的图形语言,用于描述2D图形和动画。
- SVG 绘制的图像是矢量图,可以无损缩放而不失真。
- 支持事件处理器,可以为图形添加交互。
- 文字独立于图像,可保留、编辑和搜索。
-
比较:
- Canvas 画的是位图,依赖于分辨率,放大会失真。
- SVG 画的是矢量图,放大不会失真。
- SVG 支持事件处理器,而Canvas不支持。
- SVG 中的文字独立于图像,而Canvas的文本渲染能力较弱。
- Canvas 适合图像密集型的游戏,而SVG适合做地图等矢量图形。
如果我渲染数据量比较大的时候,用哪个比较好?
哭死:这个问题我答的SVG更好渲染大数据量
因为之前渲染G6大数据量在1500个点左右时,就会出现卡顿效果。
实际是,canvas绘制大数据量会更加好,
-
优点:
- 渲染速度快。
- 可以直接操作像素,创建高质量、流畅的动画效果。
- 适用于复杂的游戏和3D效果。
-
缺点:
- 只能绘制位图,如果需要绘制矢量图形,需要转换成像素图像。
- 不支持事件处理器,无法为绘制的对象绑定事件。
- 缩放比较困难,可能影响图像质量。
G6底层原理你了解吗?
说实话真不了解太多,之前只是为了去做优化,而看了一些源码,了解到它底层用的setTimeout来做渲染优化的。
这里简单介绍一下就不多说,没啥说的,得自己去看。
它的底层是基于Canvas实现的,G6是一个基于图可视化的分析利器,提供了多种数据可视化工具。它的3.0架构图底层结合了Canvas和SVG,第二层体现了G6 3.0提供的一些能力,包括图形扩展、状态管理等,第三层则是图的基本构成要素。
说一下Vue的底层原理(开始聊八股文了)
响应式原理
diff算法
vue3的增加了TS
.....
vite是一个什么样的工具(vite和webpack的区别)
vite底层是由esbuild和rollup来实现的,属于上层(应用层)打包框架。
为什么强?
- esbuild底层用Go写的,多线程并发打包
- 启动用的HTML5中
<script type="module">
,直接加载ES Modules文件,不像webpack还得打包再加载(你懂什么叫项目run dev
之后,喝了个下午茶,聊了一会天,去买了包烟,回到工位,诶,还在打包呢?)。 - 依赖的预打包(详情看自己项目的
node_modules > .vite
文件夹里面) - 它的HMR(热重载)真的快呀,改哪换哪,webpack.....懂得都懂。
做个总结:
vite是上层应用打包框架,这是无法改变的事实,webpack是基础打包框架,所以vite很方便、很便捷,而webpack要配这配那,很麻烦。
css做div的垂直居中
老生常谈,大家简单过一下,能说几种说几种,flex是核心,说不完全面试官不在乎的。
- 使用
line-height
和height
属性(仅适用于单行文本或固定高度的div
):
div {
line-height: height; /* 或者固定值 */
height: 100px; /* 根据需要设置固定高度 */
}
- 使用
display: flex
和align-items: center
属性:
div {
display: flex;
align-items: center;
justify-content: center;
height: 100px; /* 或者根据需要设置固定高度 */
}
- 使用
display: table-cell
和vertical-align: middle
属性:
div {
display: table-cell;
vertical-align: middle;
}
- 使用
position: absolute
、top: 0
、bottom: 0
和margin: auto
属性:
div {
position: absolute;
top: 0;
bottom: 0;
margin: auto;
}
从左到右移动的动画,实现方案(CSS、js)
没啥好说的,都比较基础,回答时讲方案就行,网上的实现一大堆。
css
@keyframes move {
from {
transform: translateX(0);
}
to {
transform: translateX(400px);
}
}
div {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
top: 50px;
left: 0;
animation: move 3s infinite;
}
js
<!DOCTYPE html>
<html>
<head>
<title>JS 动画示例</title>
<style>
#box {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
top: 50px;
left: 0;
}
</style>
</head>
<body>
<div id="box"></div>
</body>
</html>
<script>
var box = document.getElementById("box");
// 分别用于记录`div`元素的左边距和移动方向
var left = 0;
var direction = 1;
function moveBox() {
//根据`direction`的值来增加或减少`left`的值
left += 5 * direction;
box.style.left = left + "px";
if (left >= 400) {
direction = -1;
} else if (left <= 0) {
direction = 1;
}
setTimeout(moveBox, 30);
}
moveBox();
</script>
css实现了从左到右移动的动画,如果非常卡顿,我们该如何解决?
这一块主要从几个方面去答:
- 减少重绘与回流
- 减少js中会产生重绘与回流的操作,例如获取某个元素的offsetTop等。
其实chrome官方专门给过一个例子,专门讲performance是怎么用的: googlechrome.github.io/devtools-sa…
二面
业务
这一块我主要说的是我简历上面的业务,如果有想了解的可以详细看,不想了解的跳着看。
重构的价值是什么
老代码重构就2点比较重要:
- 开发体验
- 页面好看了
具体价值肯定是公司的产品和友商的界面差距不会那么大,带来了销售价值。
为什么想去重构
其实这是一个非常好的问题,为什么要去重构呢,又不是不能用?
这一块主要是要从需求侧出发,我们在调研了客户、一线的看法之后,了解到产品有几点缺陷:
- 整体颜色加结构不符合现代化产品的审美,和其他友商比不了(毕竟是08年的产品了),其他友商说不上花里胡哨,起码也是Element-admin那种
- 开发人员培养难度高,上手难,ExtJs你知道吗?企业级框架呢,虽然用的3.2版本(现在好像已经更新到7了),就是不升级,诶,就是玩。
- 新增需求的代价较高,公共组件较少,纯靠cv。
- 不符合公司内、业内框架趋势、技术选型等。
那有什么方式达到需求呢?
如果只是为了完成需求,那就很简单了。
-
样式不好看,就做css的大改,去覆盖。
这个方案有些问题,它需要测试的地方非常多,很容易遗漏,开发体验依旧没有提升,总之,治标不治本。
-
重构的话,技术选型怎么办?
vue2?vue3?React?
重构带来的好处足够能压住坏处嘛?
- 开发体验肯定是大大提升,想都不用想,效率提升大大的。
- 开阔绩效空间。有了新框架,咱们想干啥干啥,埋点、性能、新技术、好看的图表全都上,最主要的是能够给小组带来更好的绩效。
- 需求做的更快。后台系统嘛,更多的是表格表单,之前写的慢,现在更新了之后写的飞快,总之就是效率提升300%。
大家都是为了钱,人员多(10人),时间多(1年),为啥不做?
说实话,确实有赌的成分,毕竟这是全面重构,我也是第一次接手管理,但是 优势在我。
最终的技术选型
- 和产线沟通,还是有兼容IE的想法,底层选Vue2(虽然后面微软说:谁爱玩谁玩,反正我不要IE了)
- 开发想用最新Vue3,使用composition-api(那时还在Vue2.6.x)
- 打包那还有啥说的,直接vite。
- 后续还想直接一键升级Vue3,选vue-demi。
- 国际化不能忘,内部有自研,i18n,总之和vue-i18n很像。
- 图表:Echarts
于是我们就开始了长达1年的开发之路(在此真佩服当时的决定),此处省略60w行代码。
如何将重构的项目推广出去的?
走灰度发布,先内测用户 > 小部分用户 > 大部分用户。
-
每次在推广部分用户后,收集用户评价,进一步的改善系统交互。
-
如果用户有额外需求,经过评估之后,走正常敏捷需求入口,下个迭代开始评估优先级。
然后重复上面的操作。
登录鉴权是如何做的
- 后端先会下发一个cookie
- 在用户输入完成后,前端会拿到cookie + 密码,并且做一个非对称加密。
- 登录成功的话,跳转到index.html时,cookie就会被后台更新(set-cookie)
- 失败的话,响应头里面没有set-cookie字段,cookie没更新,前端所有的请求都是异常的。
后续详细了解到这个cookie里面拿的是session id
如果不是session id的话,token也是可以的,token中的信息主要还是用户的一些加密信息,具体问你们的后端,我仅了解到这。
这个session id会在每个请求里面,所以能保证鉴权,这也是一个常规的方案
如何开发好一个Vue的组件
我回答的主要思路是:
- 扩展性
- 合适的文档
- 内部逻辑定义
详细的呢,可以考虑以下几点:
-
规划组件结构:在开始开发之前,先规划好组件的结构和功能。确定组件需要接收哪些属性、发出哪些事件,以及如何与其他组件进行交互。
-
单一职责原则:保持组件的单一职责,每个组件只负责一个独立的功能或视图。这样可以提高代码的可维护性和复用性。
-
合理使用组件属性:通过组件属性来传递数据和配置信息,使组件具有更大的灵活性。同时,注意属性的类型和校验,以确保组件的正确性
-
命名规范:遵循良好的命名规范,为组件、属性、方法等命名,使其具有清晰的意义,提高代码的可读性。
-
测试与调试:编写单元测试来验证组件的功能,使用开发工具进行调试,确保组件在各种情况下的正确性。
-
可复用性:尽量使组件具有通用性和可复用性,考虑将其设计为可配置的,以便在不同的场景中使用。
-
文档注释:为组件编写清晰的文档注释,描述组件的功能、使用方法和属性等,以便其他开发者更好地理解和使用。 通过遵循以上原则和最佳实践,可以开发出高质量、可维护和可复用的 Vue 组件。
当前项目代码是使用V5版本的组件库,现在客户想使用V4版本的组件库,该如何做?
这块我确实没有详细接触过,回答的很水,丢人哦。
现在才想起之前有过一个方案:
如果一定需要兼容的话,可以对每个组件做二次封装,这样确保即使组件变动也不会改动到业务代码的调用。
也不知道现在说能不能给我加分。。。
我小小的搜了一下,好像没什么比较好的方案,我觉得我这个方案得 +1分
当前项目改动了样式,引用了你项目的上游项目如何处理?
当前组件库改动导致上游吐槽,有一个很大的因素就是改动很大
-
我的第一个想法是和换肤功能差不多,既然你要做一个大的改动,那么上游项目又要更新,你就需要给上游项目提供一套原始css表,避免上游吐槽。
-
分场景加载css,也是多套皮肤,在不同场景用不同的css。
-
上游做封装,和上一个问题一致。
这一块我没有太好的想法,如果有想法的同学可以说说。
讲一下vue和react数据传递方式都有哪些?
- 属性传递(Vue):父组件可以将数据作为属性传递给子组件,子组件通过 props 来接收这些数据。
- 状态提升(React):在 React 中,可以使用状态提升来传递数据。将数据提升到父组件的状态中,然后通过 props 将数据传递给子组件。
- 事件派发(Vue 和 React):子组件可以触发事件,父组件通过监听事件并响应来获取数据(vue中的emit)。
- 上下文(React):在 React 中,可以使用上下文来在组件之间共享数据。通过创建上下文对象,将数据存储在上下文中,并使其可在组件树中访问。
- 插槽(Vue):在 Vue 中,可以使用插槽来传递数据。父组件可以通过插槽将数据传递给子组件,子组件在插槽中接收这些数据。
Vue中其余的方案在很多面试文章中都有讲到:
- event bus
- provide,inject
- vuex,pinia,react-redux
...
性能埋点,有哪些点需要获取?
- JavaScript 错误:捕获 JavaScript 运行时错误,例如语法错误、引用错误等。
- 网络错误:捕获网络请求失败的情况,例如 HTTP 状态码 404、500 等。
- 用户交互异常:捕获用户与页面交互时的异常情况,例如表单提交失败、按钮点击无响应等。
- 浏览器兼容性问题:捕获不同浏览器版本或设备上可能出现的兼容性问题。
- 资源加载异常:捕获图片、字体、样式表等资源加载失败的情况。
编码
这块我发了沸点,大家的答案我直接拿过来了,重要的是思路,其余的网上一搜就能跑,cv工程师嘛。
将某一串数字,转为财务格式,千分位加逗号。例如:2345.6 =》2,345.6
上一篇文章我讲的比较搓,这一篇文章我痛下决心,抄了别人的结果
replace(/\B(?=(\d{3})+(?!\d))/g, ',')
解析URL中的query信息,转为对象格式。
提供的URL:https://www.aa.com/ss?a=1&b=2&c#hash
- 暴力
const url = "https://www.aa.com/ss?a=1&b=2&c#hash";
// 这里可能为空,一定要注意
const urlHasHash = url.split('?')[1] ?? '';
const urlQueryList = urlHasHash.split("#")[0].split('&');
const paramsObject = {};
urlQueryList.forEach((item)=>{
const [key, value] = item.split('=');
paramsObject[key] = value ? value : '';
})
- URL对象
const url = 'https://www.aa.com/ss?a=1&b=2&c#hash';
Object.fromEntries((new URL(url)).searchParams.entries());
以上编码提特别感谢:
三面(TL)
业务
重构业务相关的内容我就不再写了,主要写不一样的。
重构中是如何赋能组员的
主要从生活上和工作上一起努力。
生活上
那当然是多关心关心别人,少加班就是最大的关心,哈哈
工作上
组长嘛,主要的就是解决问题,带来绩效。
组会:同步目标,了解困难,解决问题。
每周或每月分享:每隔一段时间,拿出一些新知识、有意思的事情、之前项目中需要同步了解的问题等,将这些事分享出来,大家都了解了,能力都提升了。
那你就越轻松,赋能是为了让团队成员有能力独当一面,而你去做提高小组绩效的事情。
项目基础建设
- eslint
- 业务代码规范
- 业务文档沉淀
如何平衡自己在管理上的时间和在开发上的时间?
说实话,我只做了一年的管理,确实没有平衡自己在两者之间的时间。
众所周知,公司里面都是时间紧,任务重,资源不平衡的一个情况,很多忙不过来的TL会亲自下场撸两个模块,这就造成一个很有意思的效果:背猴子
我目前没有说服大家的能力,那就看一下业内大佬们怎么说吧。
借鉴文章
总结
总体而言,如果只问项目的话,其实还好,没有那么复杂,怕就怕一进门3页八股文摆在那,然后一道一道往下过。
还有一家公司更恐怖,每一条问题支线都能问到最终需要用哪个函数实现,emmm,咋说呢,就两字:难搞。
转载自:https://juejin.cn/post/7343278605156220943