李迟2022年9月工作生活总结

81 阅读6分钟

本文为 2022 年 9 月工作生活总结。

研发编码

Java

调试时发现在 Java 函数体代码中途使用return返回,其后的代码会报错,提示:

java: 无法访问的语句

不知何故。只好用if (1 == 0) {...}这样的形式来达到目的。

Go

协程及同步相关

Go 中协程同步有很多方法,个人认为用 sync.WaitGroup 来实现比较简单明了,在协程内进行计数加减,在主函数中调用Wait等待。代码片段:

var g_wg = sync.WaitGroup{}
var g_count int

func add_num(time int) {
	g_wg.Add(1)

	g_count++
	com.Sleep(time)

	g_wg.Done()

}
func rout_test() {

	g_count = 0
	for i := 1; i < 11; i++ {
		go add_num(1000)
	}

	g_wg.Wait()
	fmt.Printf("at last: cnt: %v\n", g_count)
}

很久(2年)之前开始建立整理的go工程,重新拾起,根据所需补充功能,目的是方便后续统一使用一个工程模板,有些预研性质的代码,也可以整合进去。github仓库在这里

后测试发现,在协程内使用Add会有问题。存在问题的代码片段如下:

    var WG sync.WaitGroup
    // WG.Add(1) 每个协程前先Add,才不会出问题
    go func() {
        WG.Add(1)
        defer WG.Done()
        foo1()
    }()

    go func() {
        WG.Add(1)
        defer WG.Done()
        foo2()
    }()

    go func() {
        WG.Add(1)
        defer WG.Done()
        foo3()
    }()

    WG.Wait()

    fmt.Println("process done...")

模拟并发,会出现如下错误:

2022/09/11 22:39:32 [Recovery] 2022/09/11 - 22:39:32 panic recovered:
POST /etc HTTP/1.1
Host: 127.0.0.1:9000
Accept: */*
Content-Length: 369
Content-Type: multipart/form-data; boundary=------------------------46e4a53b1188458a
User-Agent: curl/7.60.0
sync: WaitGroup is reused before previous Wait has returned
D:/go/src/sync/waitgroup.go:138 (0x47db64)
        (*WaitGroup).Wait: panic("sync: WaitGroup is reused before previous Wait has returned")

Add操作放到协程前面调用即可,如果能预期协程的数量,也可直接指定数量,如上述代码有3个协程,则可直接使用WG.Add(3)

修改 map 结构体

场合:

某工程有若干版本的数据表,读取文件较耗时,在初始化时需预加载到内存中,设计上加载最新的3个版本(因为较常用),按版本号查询,使用 map 为较佳方法,版本号作为 key,value 为结构体,存放各数据表。当某版本号数据表不存在时,则加载(当然,此过程较耗时),为了后面做LRU,在 map 的结构体中添加计数,在查询时累加该计数值,因此需使用结构体指针,而不能直接使用其值。

代码示例如下:

 
type MyInfo_t struct {
	AInfo []AInfo_t
	BInfo []BInfo_t
	CInfo []CInfo_t
	// more...

	Count uint64 // 缓存访问计数,后续可能做LRU
}

// 注:使用指针,方便修改记录数
var MapMyInfo map[string]*MyInfo_t

func LoadMyInfo(version string) {
	klog.Printf("need to put [%v] sta info to cache begin\n", version)
	var tmp conf.MyInfo_t

	tmp.AInfo = GetAInfo(version)
	tmp.BInfo = GetBInfo(version)
	tmp.CInfo = GetCInfo(version)
	slen := len(tmp.AInfo)
	ilen := len(tmp.BInfo)
	if slen == 0 || ilen == 0 {
		return
	}
	conf.MapMyInfo[version] = &tmp
	klog.Printf("put [%v] sta info done \n", version)
}

func GetStaGantervalInfo(version string) (key *conf.MyInfo_t, ok bool) {
	// 先查,如不存在,再添加,再查之
	key, ok = conf.MapMyInfo[version]
	if !ok {
		LoadMyInfo(version)
	}
    // 存在则添加计数
	key, ok = conf.MapMyInfo[version]
	if ok {
		key.Count++
	}
	return
}

注:LRU 一直想研究,就不知道何时有空。

工作记录

这个月,自毕业以降,使用语言是最多的,使用 C++ 做了用例编写及压力测试;使用 Delphi 完成一个数据库模块的添加;使用 Java 完成一个项目中的数据校验功能;使用 Go 做一个 https 服务。
其实对于 Delphi,我是比较抗拒的,主要是代码历史悠久,在进入新世纪之前已经形成了,过了二十年还在使用,文件多且复杂,而且现在能查到的资料也有很多个年头了,即使有电子书,我也不可能去学了。因为回报低,比如我熟悉了添加菜单时必须要做哪些操作,关联哪些响应函数,但又有何用?不似偏底层的C,当年所学,依然能发挥作用。不过领导也有体谅,跟我提到原则是尽量少改动。少改动的前提是知道怎么改,在哪里改最优,这才是最花时间的。

秋分前两天开了个重要会议,前一天新闻报道出来,接着加班,紧急响应并完成,作为全程参与又不重要的一份子,应该干家务的两天周末没有了,又少不了被抱怨。急忙赶出来的东西,难免出错,最后一周的时间基本都花在理解技术方案,理解参数,解决不一致的地方。有天解决一个精度问题,本来已有想法正在实施,领导临时进行了若干次指导,花费了很多时间,最后还是用自己的方法实现。说实话,我的确对Delphi不熟悉,对其在虚拟机xp下开发及单步调试也不熟悉,但目前而言,全部门只有一个我在维护,这是无为而为的事。

生活记录

老妈寄了点小豆给我,跟我通话时顺便问了妹妹借的钱的事,我如实说已经还了一些。上个月申请提前还款时,老妈转了些钱给我,知道我缺钱,我也知道妹妹家境,所以不催,但老妈着急,这次又提了。于是我和妹妹通话,没想到,自从妹夫手受伤公司没赔偿后,家境如此差。妹夫感觉已经是自暴自弃,烟酒没离身,还欠了债(从法律讲,债务和妹妹无关),也没给过钱家里。靠妹妹开小卖部和做手工,现在形势差,开工的人少,生意差。既要支撑家,又要养3个小孩。我能感同身受,我的家里也是一地鸡毛,关系也不好,只是角色换了而已,当然,我没有烟酒的习惯(当然,我曾经在一年内抽了一包烟),我的信用卡额度合计有大十几万,但也不敢越矩,不敢欠债。即便买房,也没有对家庭生活质量造成太大的影响,我省但家庭不省,该给小孩的支出依然有,只是像报一千多块钱的拼音班、几千块钱的机器人班,就无法做到了。我能做到在学校旁边买一套上百万的房子,能坚持还款,已是尽力了。

只是恨自己没钱。

思想方面

对互联网思考

最近一段时间看了些热门的视频和帖子,有各种声音,都看了但不发表评论(但不知这段会不会是评论)。
作为一名老网民,我基本不掺和事件的讨论。最近几年愈发感受到互联网的可怕(当然事物有两面性,互联网改变了我生活的各方面),所幸大锤还没有对手机、短视频产生依赖,而不到2岁半的大妞,玩平板的水平比哥哥高(但不知道会不会在某个时刻爆发)。
人到中年,对很多事有自己的看法。比如996,我并不是十分反感。我一直坚持带公司电脑回家,下半年事多,尤其这个月,几乎晚上都到凌晨才睡觉。与其在网络上振臂高呼,不如老实做个工具人,安心领薪水。这三年形势变数太大了,怕万一哪天失业了,或工资支撑不了房贷、学费、日常开支,到时一家子的生活,应该不能靠网络解决。
正是因为怕,所以这些话为防止不好的事发生(比如抬杠,臆想,揣测),都加了括号注释。

业余研究