大家好,我是双越。wangEditor 作者,前百度 滴滴 资深前端工程师,慕课网精英讲师,PMP,前端面试派 作者。
我正致力于两个项目的开发和升级,感兴趣的可以私信我,加入项目小组。
本文分享我以一个前端开发人员的身份,学习 Java 和 Spring boot 的一些经历和感受。
开始
前段时间【智语】项目发布了以后,我休息了两天,然后就开始看关于 Java 和 Spring boot 的教程,花 2-3 天时间开发了一个 demo ,使用 docker 发布到我的服务器上去了。
Java 我上大学的时候就学过,毕业之后的前 2 年我一直用 C# 写代码,和 Java 很像。后来做了前端开发,我也一直写 nodejs 的服务端项目。我一直都不是一个纯前端,我是全栈开发,所以我才能如此快的去学习和实践 Java 和 Spring boot 。
今年下半年我打算全面进击 Java 全栈,出一个完整系列的教程,从前端的视角(非 0 基础)学习 Java 全栈开发,带领学员成为真正的 web 全栈工程师。
同时,我也计划用 Java + Vue3 把 划水AI 重构一遍。我的风格就是这样:不做 PPT 不做 demo ,做真实上线的项目,让你能真实使用和体验。
“真全栈”时代
2023 年春天第一次有人提“前端已死”。那会儿虽然没死成,但也发生了一点变化:开始关注全栈方向了。
2024 年春天我刚发布 划水AI 很快就有很多同学参与进来,因为大家都觉得全栈的时代要到了,纯前端是没有发展前途的。
不过当时还是以前端为主,外加 nodejs 扩展的服务端能力,全栈是前端的附加能力,加分项。
但 2 年之后的今天完全不一样了,无论是大环境原因,还是 AI 编程普及的原因,前端的生存空间几乎没有了。
之前是前端 + node ,现在要做“真全栈” ,在国内 java 就是最主流的 web 服务端技术栈。
当然,前端学 java 不是为了和 java 人员竞争,java 也很倦,而且人家多年经验了,你凭啥学2个月就和人家竞争?你也竞争不过他们。前端学 java 是要转型为全栈开发,前后端都能做,一个人干两个角色。
语言
Java 可能是最好理解的编程语言了。
Java 从一出生就是面向对象语言,设计是比较完整的。而 JS 从一开始就是一个简单的脚本,后来随着互联网的发展,慢慢才有了标准和 TS 语法。
所以 JS 一开始设计就没考虑全面,导致后面发展一只打补丁。
例如,对于异步的处理,Java 从一开始就是多线程的,可以创建多个 thread ,这很容易理解。而 JS 一开始只有 setTimeout ,后来互联网发展又设计了 Ajax ,后来嫌写法复杂又设计了 Promise ,再后来还嫌复杂又设计了 async ...
如果你是一名编程初学者,你会感觉 Java 比 JS 容易。所以 JS 你都学的会,Java 肯定也没问题。而且 JS 还参考了 Java 的语法,大概 90% 的语法的书写方式都是一样的。
另外,现在 AI 编程普及了,你根本不用关注语法细节,能看懂代码结构和执行逻辑就可以。
服务端思维
纯前端开发转型全栈最大的障碍不是语言、不是框架和工具,而是服务端思维。
前端开发的是页面,是客户端,加载到客户的浏览器运行的,每个客户都独享一份程序。
网页的数据结构设计,只考虑一个人的就行了,一般不会太多。至于网络上的“一次性加载10万条数据...” 这只是面试题,真实工作中几乎没有这种场景。
网页加载的快慢一般也不用自己操心,静态资源有 CDN 不会太慢,API 接口慢了直接找后端开发人员。至于那些网页渲染卡顿、内存泄漏等,一年也遇不到两次。
网页都是在浏览器这个环境下运行的,获取数据、提交数据,都是通过后端 API 接口。你获取的数据是怎么来的?你提交的数据要往哪儿去?这些你都不知道,跟你没关系。
服务端就不一样了,它要承接所有用户的流量和数据。流量大了如何处理?数据多了如何处理?万一遇到错误又该如何处理?这种思维方式和前端是完全不一样的。
所以,纯前端开发,在技术视野上、产品流程上,有很大的局限性。服务端思维就是要突破这种局限性,以全栈全流程的视野去看项目。
Spring 框架
Java 的 Spring 框架的设计和生态,应该是这个世界上最适合 web 开发的框架了,国内都普及了。
我这几天学习使用 Spring 我发现用它开发 web 服务端真的超级简单,你只需要按照它设计的规范来做即可。你能想到的它都有,你想不到的它也有。
但是,你如果直接上手学习 Spring 可能会比较吃力,尤其是你又刚接触 Java ,那就更吃力了。
我更建议大家通过 Nest.js 这个 Nodejs 框架来入手。注意是 nest.js 不是 next.js ,别搞混了。
因为 nest.js 就是模拟着 Java Spring 框架设计的,两者非常相似。而你又非常熟悉 JS 语法,那学起来肯定很快。
你花 1-2 周搞定 nest.js ,再去学习 Spring 就会感觉非常熟悉,哪怕你刚入门 Java 也很好上手。磨刀不误砍柴工。
反之,如果你求快,直接上手学 Java 和 Spring ,很可能因为学习成本太高而厌学,半途而废。
我们日常工作加班已经很累了,再业余学习,一定要找一个低成本的途径,才具有可行性。不要一时自我感动,自我亢奋,觉得自己一定能行的,然后三分钟热度,很快没劲儿了。
无论 Nest.js 还是 Spring ,它既然是服务端框架,那就是开发服务端 API 。你作为前端开发,每天接触最多的就是 API 。一个请求输出什么、输出什么、什么格式、是否需要 token ... 这是你最熟悉的。
所以以前端视角去学习 Java 框架并不是从 0 开始学,你已经有一部分基础了。通过正确的学习途径可以很快学会的。
包管理器
前端开发用 npm 管理,使用 pakcage.json 记录依赖,或者 pnpm yarn 等,每天都用。
Java 开发使用用 maven 管理,使用 pom.xml 记忆依赖,功能都是一样的。
前端使用 npm 命令
npm run dev
npm run build
npm run test
Java 使用 maven 命令,和 npm 命令作用是一样的
mvn spring-boot:run
mvn clean package
以前端视角学习 Java 很多东西都可以做对比的,一旦有了对比参照,就很快学会。
环境变量
前端是使用 .env 作为环境变量来存储一些常量、配置、密钥等,但 Spring 框架是使用 application.properties 文件来存储的。
但这个文件它是推荐提交到 GitHub 中的,因为有些配置是代码的一部分,要和团队共享。所以一些密钥不能放在这个文件中,要放在其他文件。
在本地开发环境下,使用 application-local.properties 存储密钥,不提交到 github
但运行的时候要加 local 标识,让 spring boot 去加载这个 local 文件
mvn spring-boot:run -Dspring-boot.run.profiles=local
如果是发布到生产环境 docker 容器化部署。使用 .env 文件存储密钥。docker 读取这个文件,并创建为环境变量,spring boot 会用到。
注意,spring boot 本地开发环境下是不会加载 .env 文件的,这一点和前端开发不一样。
其实如果你工作经验多、设计经验丰富的话,你仔细想一下,Spring boot 这种设计方式才是最合理的。.env 本来就是环境变量,就应该和项目配置区分开来,分开层次,不能混在一块。前端开发直接使用 .env 是有点太凑活事儿了。
数据库
前端开发用不到数据库,网页上有一点数据用 localStorage 存储就够了,浏览器内置的 indexedDB 几乎用不到。
后端开发必备的就是数据库,因为存储网站的数据、用户的数据,这是最基本的能力。
前端开发对数据库还是比较陌生的,没用过,也没写过 SQL 语句。
初步学习数据库,例如最常见的 mysql 关系型数据库,你就把它看成几个 excel 表格。例如一个 user 数据表,它就是一个表格,包括了:用户名、密码、邮箱等多列,可以添加很多行。
在绝大部分开发过程中,我们也不需要手写 SQL ,使用 Spring boot 自带的 ORM 工具,或者 Mybatis-plus 即可使用代码 API 操作数据的增删改查,就像你使用 localStorage 操作数据是一样的。基础的操作会很快入门。
掌握了基础的功能,在一个项目中实践好,然后再去进阶:连表查询、数据库优化、数据表拆分等等。
缓存
前端开发中有没有缓存?有很多。
例如 Vue 中的 keep-alive 缓存组件,React 中的 useMemo useCallback 都是数据,静态资源 HTTP 缓存 cache-control —— 这还都是面试八股文问题呢,肯定没少被背诵。
缓存的目的就是为了避免重复创建,使用之前的结果,增加效率,增加用户体验。
服务端的缓存也是一个道理。
例如一个博客网站的首页要获取热门文章列表,这不用每次都从数据库获取,尤其访问量比较大的时候,每次都从数据库获取会比较慢。组好的方法就是把当前结果缓存起来,设置 5 分钟的过期时间。5 分钟之内,所有用户都会从缓存中获取结果,速度会快很多。
服务端一般使用 redis 服务器做缓存,redis 会默认把数据存储在内存,这样读写都非常快。
虽然使用工具不一样,但其设计方式、解决的问题、达成的效果,都是一样的。不用从 0 学习。
消息队列
浏览器事件循环 Event Loop 的原理,大家都知道吧?典型的前端面试八股文。
Event Loop 就是用消息队列实现的,有了异步任务就去排队执行,通过一个 queue 来管理任务。
再有,如果让你开发一个多文件上传系统,选中多个大文件,排队上传到服务器,你也需要用到队列来实现。
服务端有更多的场景需要消息队列,例如一个接口请求之后,要发送一个消息、发送一个邮件、把数据提交到另外一个服务,这些不影响核心主流业务的,都要通过消息队列来实现。
如果没有消息队列,那主任务就要等待这个任务去执行,就会浪费很多时间。如果是多用户同时请求,那就有可能被卡住,造成更大的影响。
服务端的消息队列可以使用 RabbitMQ ,它还有可视化面板,可以清晰的看到任务的消费情况。
还没完
今天先写这么多吧,其实还有很多进阶内容,后续我继续分享,大家可以先关注我~
- Jenkins 自动化部署
- docker 容器化部署
- 日志 统计 报警
- k8s
- 微服务