我的2023:几乎没写 Java 代码的一年,如何偿还技术债

2023-12-07 01:59:10 浏览数 (2)

封面封面

这一年的工作内容

元旦前后

去年11月末,疫情全面开放,几乎在那12月里,公司所有人都感染了。我也不例外,3天假期躺了3天。当时的我正在另一个部门支援做Xamarin

Xamarin是一个基于.NET开发的跨平台解决方案,当时的任务主要是Android端和IOS端

Xamarin技术架构Xamarin技术架构

这是我第一次解开移动端跨平台开发的神秘面纱。前期在调查的时候,就感觉这东西属于前端+后端,但做几个画面之后发现,这还是属于前端,因为真正的数据,还是保留在另一个服务器上。

整体上,有保留页面和逻辑,页面是HTML的变种,除了一些特定的标签,属性。就连文件类型都叫XAML。(以下代码来自官方教程,非实际业务代码)

代码语言:html复制
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Notes.Views.NoteEntryPage"
             Title="Note Entry">
    <!-- Layout children vertically -->
    <StackLayout Margin="20">
        <Editor Placeholder="Enter your note"
                Text="{Binding Text}"
                HeightRequest="100" />
        <!-- Layout children in two columns -->
        <Grid ColumnDefinitions="*,*">
            <Button Text="Save"
                    Clicked="OnSaveButtonClicked" />
            <Button Grid.Column="1"
                    Text="Delete"
                    Clicked="OnDeleteButtonClicked"/>
        </Grid>
    </StackLayout>
</ContentPage>

再看“后台”的代码,使用的主要是C#,写起来和Java比较相似。不过是因为移动端,常常需要去考虑同步异步的代码。还由特别吐槽的一点,左大括号要换行!

代码语言:c#复制
async void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (e.CurrentSelection != null)
    {
        // Navigate to the NoteEntryPage, passing the filename as a query parameter.
        Note note = (Note)e.CurrentSelection.FirstOrDefault();
        await Shell.Current.GoToAsync($"{nameof(NoteEntryPage)}?{nameof(NoteEntryPage.ItemId)}={note.Filename}");
    }
}

在运行与调试上,主要使用编辑器(Visual Studio)的模拟器。因为经验不足,并没有像以往控制台调试前端那样快捷的定位画面问题。也没有保留像开发桌面软件那样的拖拽组件开发功能。

拟真设备拟真设备

年初

记得没错的话,回到本组的时候还是居家办公,这回是写Java代码了,但又不完全写。

大概是一个项目开发完,修改部分内容CV成5个!全部都是体力活。

因为比较接近开发末期,所以我的任务主要是用Windows自带的Winmerge软件去差分对比,修改部分。这下真成CV工程师了!

高端程序员高端程序员

大概在复工后,回到公司,开始测试工作了。没错,虽然我是Java后端开发,但哪里需要哪里搬。

这个项目测试完,到下一个还是测试工作。这样眨眼间来到了年中。

年中

好消息:终于可以开发了

坏消息:写React

一句去另一个部门做支援,又是六个月。

唯一给我的嘱咐就是看一看ES6 React TypeScript

ES6 或者叫ECMAScript2015,简单来说就是JavaScript的一个版本/规范,就像JDK21,JDK8那样。这个时候的Js工程已经很有后端的感觉了。

开发体验下来,最大感受就是,在工程化的前端里,var已经不见了,取而代之的是可变的let和不可变的const。出现的原因就是诟病的变量作用域问题。

TypeScript 是Js的超集,为什么用到这个技术呢?如下:

代码语言:javascript复制
var s = "1";
typeof s // 'string'
s = 1
typeof s // 'number'

以上在控制测试台结果如下

js存在的问题js存在的问题

因为js是弱类型语言,所以在某些情况下不进行类型校验会出现意料之外的问题。当然,js也做出了一些尝试来简化类型的判断,比如:

代码语言:javascript复制
var x = 1;
var y ="1";
x == y // true
x === y //false
"三等号"示例"三等号"示例

而React,作为前端三大框架之一,在代码中你会发现:All in JavaScript。

年末

六个月的前端时光眨眼就过去了,回到自己组内,终于在23年最后一个月才开始”本职“工作。

虽然只是旧系统的重构,但熟悉的Java还是会让自己感到安心。

在工作中学

元旦前后

看起来和Java开发毫无关系,怎样能在工作中学到Java呢?

在CRUD的过程中发现,每一套的起初三个文件的创建几乎一摸一样,感觉可以做一个快捷创建向导,像开发Java EE时Eclipse创建Servlet,会自带一堆方法一样。因为微软的一套都比较偏国外,英文薄弱的我最后查询无果。

Servlet向导Servlet向导

天无绝人之路,在有一次用MyBatis逆向生成代码的时候,发现应该可以采取这种方式来实现向导。迅速查找资料,最后确定方案是使用Framework模板

JSP、Thymeleaf、Framework都是模板引擎,不过最后这个拿来生成代码的人比较多,所以选用这个。 部分生成模板代码(非真实业务代码)

代码语言:java复制
private void executeGenertor(Map<String,Object> dataModel,File file) throws Exception {
    //1.文件路径处理   (E:模板${path1}${path2}${path3}${ClassName}.java)
    //templatePath : E:模板
    String templateFileName = file.getAbsolutePath().replace(this.templatePath,"");
    String outFileName = processTemplateString(templateFileName,dataModel);
    //2.读取文件模板
    Template template = cfg.getTemplate(templateFileName);
    template.setOutputEncoding("utf-8");//指定生成文件的字符集编码
    //3.创建文件
    File file1 = FileUtils.mkdir(outPath, outFileName);
    //4.模板处理(文件生成)
    FileWriter fw = new FileWriter(file1);
    template.process(dataModel,fw);
    fw.close();
}

模板文件(默认启用了Lombok插件)

代码语言:java复制
@Entity
@Table(name = "${table.name}")
public class ${ClassName} implements Serializable {

    <#list table.columns as column>
    <#if column.columnKey??>
    @Id
    </#if>
    private ${column.columnType} ${column.columnName2};
    </#list>

    <#list table.columns as column>
    public void set${column.columnName2?cap_first}(${column.columnType} value) {
        this.${column.columnName2} = value;
    }
    public ${column.columnType} get${column.columnName2?cap_first}() {
       return this.${column.columnName2};
    }
    </#list>
}

✔实现原理

如果你用过其中一个模板框架,就会发现,这里面相当多的一部分可替代内容使用插值表达式来写

插值表达式:像${},#{},{{}}等

这样只要在入口处指定参数,那么就可以生成一份”预制代码“。

虽然开发和调研用了一点时间,但是最后使用所减少的时间无上限。

边际成本边际成本

年初

同样的CV场景,当然也有脚本替换人工的方法。

这次的目标是复制文件(因为多且位置不同,所以也加入自动化行列),再自动打开winmerge进行手动比较。前者复制文件在学习Java时应该都经历过,这次来说一说后者。

在Windows环境里,打开一个系统的应用可以使用win R,再键入应用名(英文/缩写/环境变量名)。

目前我自己再工作中常用的 calc 计算器 notepad 记事本 mspaint 画图

命令行执行命令行执行

如上图,这样就可以打开一个软件。

并且已知,执行时可以带参数,如下

winmerge E:/xxx.txt E:/m/xxx.txt 那么眼下需要解决的问题就变成了Java 执行命令行。

问一下混元助手吧!(当时自己百度来的)

混元助手混元助手

当同事还在干苦力,我已经10X效率在摸鱼了!

下班后开始新的一天

  • 元旦 前文说到,这主要是国外跨端开发的技术栈,所以下班后试着搜索国内的。 第一个结果就是:uniapp,同时还有Flutter,React。下班后都有按照工作的模型去换语言实现。
  • 年初 显然只是生成几个单一文件模板还是太Demo了,所以下班后尝试生成一整套”预制项目“ 大概长以下这样(某马机构的灵感)
代码生成器代码生成器
  • 年中 这时候是补前端技术栈的最好时机,基本就是补基础 找项目练习。
  • 年末 重构的这个时间段,差不多要横向对比两个新旧项目的技术栈,包括思考架构设计等。所以开始刷架构相关的文章。

硬技术之外?

阅读

我的书柜我的书柜

在2022年因为技术焦虑,买了一堆书。

但是吧,买书如山倒,看书如抽丝。所以在今年也尝试去还”书债“。

好消息:看了很多了,坏消息:又买了一堆,这个简易书柜已经放不下了。

写字

字帖字帖

提笔忘字的问题,老生常谈了。再加上自己的字很丑,再加上天热的时候很急。所以写字一方面练,一方面静

艺术

除了一些数字油画这种敷衍自己的东西外,也拼过立体书屋的积木。反正就是小东西拉高自己的成就感

书屋积木书屋积木

总结

这就是我的一年,高强度5G冲浪错峰睡觉摆烂全干工程师的平淡且充实的一年。

10块钱的月季10块钱的月季

0 人点赞