某蚂蚁子公司,前端通关挑战中

前言

哈哈,我又来给云大佬们交代面试经验了,这里是懂一点项目管理和前端开发的狗子。

这次是属于我这里偏大的厂了,整体面试感觉没那么难,问项目的话我都能答出来,毕竟之前自称解决方案专家(手动狗头)。

背景

  1. 主要的技术栈是Vue + Vite。
  2. 主要的项目经验是重构了一个大型控制台、用G6开发过自定义的图形。
  3. 算法没咋刷(哭死)

以下很多内容和我的简历相关,写的不是特别细 ,毕竟不是面真大厂,大家看自己有用的哈,千人千面,我就都写了。

我们话不多说,进入正题。

一面

你是怎么预研这几个图标库,做技术选型的吗?

简历原文:预研到ECharts、Antv G6和GoJs等多个图表库后,我们决定采用Antv G6。

嘿嘿,聊这个,我当时专门做了设计文档,个人回答是:

  1. 公司内部是否有使用(优先)
  2. 性能:加载大数据量的能力
  3. 社区、文档是否全面
  4. 框架是否有持续更新
  5. 满足业务需求(重要)

原因

  1. 综合来看G6和Echarts的文档,社区比较多
  2. 公司内部用G6
  3. AntV G6基于Canvas,适合处理较大规模的图表,而ECharts则更适合一般规模的数据,当然GoJs也具备良好的性能

其他方向

其实呢,还有一些方向可以做技术选型:

  • 可定制性、可扩展性:也就是是否满足需求,如果你需要高度定制的图表,ECharts和AntV G6都提供了一定的可定制性。
  • UI风格和配色
  • 学习曲线

echarts的原理

啊?这,我不会,真不会。。。

简单聊了一下是canvas做的。

于是我搜了一下该如何答:

总的来说就是两点:

  • echarts.js负责图表的创建、初始化、主题、事件、动画、数据加载等功能。
  • zrender.js负责图表的绘制和交互处理,通过对HTML5 Canvas的封装实现图表绘制和动画效果

再往深处?不必要吧。。。

HTML5除了Canvas可以画图还有其他方法可以画图吗?

我答:D3.js 可以用svg来画图

当涉及在网页上绘制图形时,HTML5 提供了多种方法,除了使用 Canvas,还有其他选项:

  1. SVG(可缩放矢量图形)

    • SVG 是一种基于 XML 的图形语言,用于描述二维图形和动画。
    • Canvas 不同,SVG 是矢量图形,可以无损缩放而不失真。
    • 使用 <svg> 标签来创建 SVG 图形,然后通过属性和元素来定义形状、路径、文本等。
  2. CSS3

    • CSS3 可以用于创建一些简单的图形效果,例如渐变、阴影、圆角等。
    • 通过 CSS 属性,你可以对元素的样式进行控制,从而实现一些基本的图形效果。
  3. WebGL

    • WebGL 是一种基于 OpenGL 的图形库,用于在浏览器中创建复杂的3D图形和动画。
    • 它允许你直接操作图形硬件,以高效地渲染图形。

但最终还是以canvas和svg为主。

canvas和svg的区别

当涉及在网页上绘制图形时,CanvasSVG 是两种不同的技术,各自有其特点和用途:

  1. Canvas

    • Canvas 是一个HTML5元素,用于通过JavaScript绘制2D图形。
    • 图像在Canvas上以像素为单位绘制,类似于绘制位图。
    • 一旦图像绘制完成,浏览器不再关心它。如果位置发生变化,需要重新绘制。
    • 适合图像密集型的游戏,但需要频繁重绘。
  2. SVG(可缩放矢量图形)

    • SVG 是一种基于XML的图形语言,用于描述2D图形和动画。
    • SVG 绘制的图像是矢量图,可以无损缩放而不失真。
    • 支持事件处理器,可以为图形添加交互。
    • 文字独立于图像,可保留、编辑和搜索。
  3. 比较

    • Canvas 画的是位图,依赖于分辨率,放大会失真。
    • SVG 画的是矢量图,放大不会失真。
    • SVG 支持事件处理器,而Canvas不支持。
    • SVG 中的文字独立于图像,而Canvas的文本渲染能力较弱。
    • Canvas 适合图像密集型的游戏,而SVG适合做地图等矢量图形。

如果我渲染数据量比较大的时候,用哪个比较好?

哭死:这个问题我答的SVG更好渲染大数据量

因为之前渲染G6大数据量在1500个点左右时,就会出现卡顿效果。

实际是,canvas绘制大数据量会更加好

  • 优点:

    • 渲染速度快。
    • 可以直接操作像素,创建高质量、流畅的动画效果。
    • 适用于复杂的游戏和3D效果。
  • 缺点:

    • 只能绘制位图,如果需要绘制矢量图形,需要转换成像素图像。
    • 不支持事件处理器,无法为绘制的对象绑定事件。
    • 缩放比较困难,可能影响图像质量。

G6底层原理你了解吗?

说实话真不了解太多,之前只是为了去做优化,而看了一些源码,了解到它底层用的setTimeout来做渲染优化的。

这里简单介绍一下就不多说,没啥说的,得自己去看。

G6简介

G6 架构演进

它的底层是基于Canvas实现的,G6是一个基于图可视化的分析利器,提供了多种数据可视化工具。它的3.0架构图底层结合了Canvas和SVG,第二层体现了G6 3.0提供的一些能力,包括图形扩展、状态管理等,第三层则是图的基本构成要素。

说一下Vue的底层原理(开始聊八股文了)

响应式原理

不想再说这个了,都烂了,详细的看其他博主文章或者我的这篇文章:juejin.cn/post/732726...

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是核心,说不完全面试官不在乎的。

  1. 使用line-heightheight属性(仅适用于单行文本或固定高度的div):
css 复制代码
div {
    line-height: height; /* 或者固定值 */
    height: 100px; /* 根据需要设置固定高度 */
}
  1. 使用display: flexalign-items: center属性:
css 复制代码
div {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100px; /* 或者根据需要设置固定高度 */
}
  1. 使用display: table-cellvertical-align: middle属性:
css 复制代码
div {
    display: table-cell;
    vertical-align: middle;
}
  1. 使用position: absolutetop: 0bottom: 0margin: auto属性:
css 复制代码
div {
    position: absolute;
    top: 0;
    bottom: 0;
    margin: auto;
}

从左到右移动的动画,实现方案(CSS、js)

没啥好说的,都比较基础,回答时讲方案就行,网上的实现一大堆。

css

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

html 复制代码
<!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>
js 复制代码
<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行代码。

如何将重构的项目推广出去的?

走灰度发布,先内测用户 > 小部分用户 > 大部分用户

  1. 每次在推广部分用户后,收集用户评价,进一步的改善系统交互。

  2. 如果用户有额外需求,经过评估之后,走正常敏捷需求入口,下个迭代开始评估优先级。

然后重复上面的操作。

登录鉴权是如何做的

  • 后端先会下发一个cookie
  • 在用户输入完成后,前端会拿到cookie + 密码,并且做一个非对称加密
  • 登录成功的话,跳转到index.html时,cookie就会被后台更新(set-cookie)
  • 失败的话,响应头里面没有set-cookie字段,cookie没更新,前端所有的请求都是异常的

后续详细了解到这个cookie里面拿的是session id

如果不是session id的话,token也是可以的,token中的信息主要还是用户的一些加密信息,具体问你们的后端,我仅了解到这。

这个session id会在每个请求里面,所以能保证鉴权,这也是一个常规的方案

如何开发好一个Vue的组件

我回答的主要思路是:

  1. 扩展性
  2. 合适的文档
  3. 内部逻辑定义

详细的呢,可以考虑以下几点:

  • 规划组件结构:在开始开发之前,先规划好组件的结构和功能。确定组件需要接收哪些属性、发出哪些事件,以及如何与其他组件进行交互。

  • 单一职责原则:保持组件的单一职责,每个组件只负责一个独立的功能或视图。这样可以提高代码的可维护性和复用性。

  • 合理使用组件属性:通过组件属性来传递数据和配置信息,使组件具有更大的灵活性。同时,注意属性的类型和校验,以确保组件的正确性

  • 命名规范:遵循良好的命名规范,为组件、属性、方法等命名,使其具有清晰的意义,提高代码的可读性。

  • 测试与调试:编写单元测试来验证组件的功能,使用开发工具进行调试,确保组件在各种情况下的正确性。

  • 可复用性:尽量使组件具有通用性和可复用性,考虑将其设计为可配置的,以便在不同的场景中使用。

  • 文档注释:为组件编写清晰的文档注释,描述组件的功能、使用方法和属性等,以便其他开发者更好地理解和使用。 通过遵循以上原则和最佳实践,可以开发出高质量、可维护和可复用的 Vue 组件。

当前项目代码是使用V5版本的组件库,现在客户想使用V4版本的组件库,该如何做?

这块我确实没有详细接触过,回答的很水,丢人哦。

现在才想起之前有过一个方案:

如果一定需要兼容的话,可以对每个组件做二次封装,这样确保即使组件变动也不会改动到业务代码的调用。

也不知道现在说能不能给我加分。。。

我小小的搜了一下,好像没什么比较好的方案,我觉得我这个方案得 +1分

当前项目改动了样式,引用了你项目的上游项目如何处理?

当前组件库改动导致上游吐槽,有一个很大的因素就是改动很大

  1. 我的第一个想法是和换肤功能差不多,既然你要做一个大的改动,那么上游项目又要更新,你就需要给上游项目提供一套原始css表,避免上游吐槽。

  2. 分场景加载css,也是多套皮肤,在不同场景用不同的css。

  3. 上游做封装,和上一个问题一致。

这一块我没有太好的想法,如果有想法的同学可以说说。

讲一下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

  • 暴力
js 复制代码
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对象
js 复制代码
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,咋说呢,就两字:难搞。

相关推荐
余生H14 分钟前
前端的全栈混合之路Meteor篇:关于前后端分离及与各框架的对比
前端·javascript·node.js·全栈
程序员-珍16 分钟前
使用openapi生成前端请求文件报错 ‘Token “Integer“ does not exist.‘
java·前端·spring boot·后端·restful·个人开发
axihaihai21 分钟前
网站开发的发展(后端路由/前后端分离/前端路由)
前端
流烟默33 分钟前
Vue中watch监听属性的一些应用总结
前端·javascript·vue.js·watch
2401_8572979143 分钟前
招联金融2025校招内推
java·前端·算法·金融·求职招聘
茶卡盐佑星_1 小时前
meta标签作用/SEO优化
前端·javascript·html
Ink1 小时前
从底层看 path.resolve 实现
前端·node.js
金灰1 小时前
HTML5--裸体回顾
java·开发语言·前端·javascript·html·html5
茶卡盐佑星_1 小时前
说说你对es6中promise的理解?
前端·ecmascript·es6
Promise5201 小时前
总结汇总小工具
前端·javascript