五年前端高级开发,不得不吐槽的一些事

42,353 阅读9分钟

首先,先说一下,本人在实际开发中,已经有五年开发经验,但是开发中遇到的一些现象和一些事情,让我觉得不得不吐槽,看看大家是否一样有疑惑。欢迎一起来讨论!

直接开始吐槽

恨铁不成钢的菜鸟

首先,强调一下,我也是从小白一路打怪升级过来的,但是在工作中遇到了很多让我觉得非常痛心的小白。我一直认为,我们是前端工程师,不是一个画页面的

我们首先要是一个合格的工程师。

我在招聘的时候,会考察大概几个点,但是也不需要考察的非常严格,只需要你有一些了解即可。

  • 数据结构
  • 算法
  • 对象内存模型
  • JavaScript事件机制
  • 继承和封装
  • 耦合
  • HTTP协议
  • VCS:SVN或Git(这个点名批评Git,面试时候50%左右都说自己会,结果入职后,拉取代码第一关就不会了)
  • Ajax
  • 同步&异步的理解

但就是一些简单的问题,很多同学也是一头雾水,回答不上来。

例如: 有一个[1,2,3,4,4,5,5,6,6,6,7]数组,数组长度100以内,数组内部都是正整数,数组是有序的,数组不会出现空值,问: 如何将数组中重复的元素删除?

这么简单的一道数组去重,就有将近一半的同学答不上来


例如: Ajax和Axios分别是什么,他们有什么关系?

这很明显是一道迷惑题,大概就像是JavaScript和Java是什么关系,偏偏就有很多前端答不上来。

很多同学这时候肯定有的人会说,一定是你们公司招聘给的工资低,才会招到这些技术差的

这个没错,确实是我们现在工资低了点(不过我拍着良心说,算是这个城市里面,也到了做开发的平均数了),

但是我想表达的是,可以很明显的感觉到,1-3年的前端,尤其是非计算机相关专业的,真的太多菜鸟,而且由于没有完整的体系的培训,很多人也只是浮于表面,变成了vue工程师

很多Java的同学,自嘲自己是Spring工程师(意指:只会在Spring下进行开发的工程师)但更可悲的是,还有很多前端同学压根就意识不到自己是Vue工程师(没有路线和规划)

各种各样项目定制化

经常听到这样一句话:

这次这个项目,后端接口还是之前的那几个,但是由于客户XXX原因,我们需要换一套新的界面

工作多年,我最害怕的遇到这种情况,原因有很多种可能:

  1. 原本在PC的功能,现在要在微信公众号上实现(重新开发一次)
  2. 用户觉得之前的界面太丑了,我们这次需要换新的界面来实现(重新开发)
  3. XX系统之前的那个XX功能很好,可以移植过来吗?讲真的,我是Java出身,我知道Java移植一个新的微服务到当前的服务集群有多少工作量

后端接口设计不良好

我这里特意使用了一个不良好的词汇,后面我会详细说明。

举例1:

前端需要加载一个用户头像图片

正常情况: 打开首页的时候,获取用户信息,在返回的JSON数据中,存在一个节点,里面存放着与用户图片静态资源路径。加载到对应位置即可。

axios.get("/user/info").then(res=>{
    console.log(res.data.user.logo); 
})

实际情况:

  1. 你需要先调用A接口获取用户ID/system/info
  2. 你需要根据A接口返回的用户ID来获取一个信息/user/info
  3. 你需要根据信息来获取用户的图片路径/logo
axios.get("/system/info").then(res=>{
    axios.ge("/user/info").then(res=>{
        axios.get("/logo").then(res=>{
            console.log("终于获取到最终的图片路径");
        })
    })
})

有经验的开发者, 已经意识到这里面有什么问题了

  1. 接口与界面不匹配:一个界面的信息,不应该每一个功能点都去请求接口,这样做虽然是耦合降低了,但是也带来了大量的Ajax请求,进而影响性能,(这里面会涉及到后端追求的数据下沉和单一职责)
  2. 接口调用链过长,交互次数过多,最终时间上会变得很久;另外,若中间如果网络出错,调用链断掉,前端普遍的SPA,也会带来内存泄露的隐患。

所以,正常来说,在一个接口获取到用户信息是最合适的

针对这个问题,我特意开过一个会,去咨询每一个人的反应,结果让我很心痛:

  1. Java开发普遍反应:不做修改,没必要改;理由:接口都已经写好的了,为什么要再写一个新的接口,这样维护起来会很麻烦。
  2. 前端反应:???,领导为什么追着这个小细节在扣,我们有Promise,多写几次回调就够了啊我知道你们不怕累orz...但是意识不到问题才是最大的问题

上面例子,可以理解为设计的不合理,下面这个例子才是真的:意识不到问题,才是最大的问题。

举例2:

有一个奇葩的后端接口,接口负责下载excel,Java开发者为了节约工作量,做了一个这样的接口出来:

@Controller
public class DownloadController {
    // 下载接口
    @RequestMapping("/downloadExcel")
    public MultiFile downloadExcel(XXXX){
        return XXX;
    }
}

下载接口downloadExcel里面接收的参数,不是下载文件的参数(一般下载文件,会指定下载文件路径或者动态构造文件的一些参数,例如:搜索条件之类),而是文件内容。

也就是说,你需要下载的文件的内容,你要先准备好一个JSON,传给后端,他才能在接收到JSON的数据之后,转换成一个Excel下载给你...

这里面存在的问题:

  1. 下载数据量一旦特别大,就会很慢,很卡,甚至客户端崩溃
  2. 数据本身就是从后端查询出来的, 下载的时候传给后端会消耗大量的网络带宽和服务器内存。
  3. 大量数据由外界传递,会被恶意攻击(具体攻击方式很多了,这里不赘述)

有的同学可能会问了, 前端是分页的,那你要下载全部该怎么办呢?

其实,我被抓过来看到这个接口,最早就是因为报了一个BUG:用户点了一个下载全部按钮(生产环境,列表数据近百万级别),直接导致界面卡死,而分页其实是后端直接返回了所有数据,前端做的客户端分页。

我看到这个接口设计,跑过去问那个开发为什么要这么设计,他竟然跟我说:我们本地环境测试是好的呀!测试哪里也是好的!功能都做完了,当时也没测试出问题,一定是现场实施没部署好,让他重启一下就好了

时至今日,我都一直想不通,这种接口是如何被设计出来,如何被前端接受,并且开发出来的

后端的风险嫁接

风险嫁接是我自己发明出来的词语。

由于业务关系,我方经常对接第三方系统,也就是要调用别人的接口,来同步数据。

后端的Java开发,在面临第三方数据的时候,一直都是很小心谨慎,数据库使用MongoDB,数据结构大量使用List<map>,而在每次GetXX()都会使用checkUtil来进行空判断和optional操作。这点值得点赞!

但是后端不进行任何数据校验的情况下,把数据都存在了数据库里,前端在查询的时候,就变成了灾难

  • 数据字段偶尔缺失
  • 数据类型偶尔不对应
  • 数据偶尔为空 前端在一个接口返回的list<user>接口中,看到的数据往往是这样子的:
[
{name:"jack",age:10,address:""},
{name:"jack"},
{name:"jack",age:null,address:null},
{name:"jack",age:18,address:["A","B"]}
]

以上只是举一个栗子,十几种字段数量可能会有30+甚至50+, 这种数据结构,对于Vue工程师来说,简直就是灾难,至少在我目前来看是的, 随便一个v-for就炸了,动不动在循环的时候就出现一个Null异常,

当然,我知道以上所有的吐槽都有解决方案,不论是数据校验还是入参校验,又或者默认值,都可以处理。
但:还记得标题是什么?风险嫁接,后端对数据结构的宽松化,导致脏数据直接入库,进而直接影响到很多无意义的工作上,或者说这工作前端后端都可以做的,现在不得不前端来做

前端的深度和无法理解的需求

前端说不好听一点,其实就是画界面,总有人抬杠:

  • vscode 编辑器是前端做的,一点都不简单
  • 低代码平台 赋能实施,直接托拉拽,也不简单
  • 前端框架,Vue/react/angular等,这些轮子也都不简单

我很认同这个观点,不论是前端还是后端,只要一心往山上走,到最后都是顶峰。 但是有多少人是停留在山脚和山腰呢……难道他们的诉求和痛苦就不值得一提了么?

很多前端痛苦的点在于,你可以成为一个技术专家,但是你永远无法成为一个团队的核心骨干,永远在外面打酱油

作为一个全栈开发者,我的个人感觉,掌握了数据库,你就掌握了整个系统的核心,这句话其实一点都不假,在做后端的日子里,我对于业务的理解非常透彻,但是转到前端,就失去了对业务的掌握。