一不留神就掉坑

乘除顺序问题

在据卡特兰数公式,解决leetcode-96 不同的二叉搜索树时,遇到一个非常诡异的问题,

go 复制代码
package main

import "fmt"

func main() {

	for i := 0; i <= 40; i++ {
		fmt.Printf("第%d个卡特兰数为:%d\n", i, numTrees(i))
	}

}
func numTrees(n int) int {

	rs := 1
	for i := 0; i < n; i++ {
		rs = rs * 2 * (2*i + 1) / (i + 2)
        //rs *= 2 * (2*i + 1) / (i + 2)
	}
	return rs
}

即 注释掉的这一行,居然和上一行得出了完全不同的结果. 虽然马上解决,但对固有认知影响巨大---难道对一直以来习以为常的乘法语法糖理解有误???

*= 为乘法和赋值运算符,它将右操作数与左操作数相乘,并将结果赋给左操作数. C *= A 相当于 C = C * A

读了一遍感觉没问题,那原因出在哪里呢?

构建demo,

go 复制代码
package main

import "fmt"

func main() {

	rs1 := 2
	rs2 := 2
	i := 3
	fmt.Println("当前的rs1,rs2为:", rs1, rs2)
	fmt.Println("2 * (2*i + 1) / (i + 2)为:", 2*(2*i+1)/(i+2))
	rs1 = rs1 * 2 * (2*i + 1) / (i + 2)
	rs2 *= 2 * (2*i + 1) / (i + 2)
	fmt.Println("最后rs1 is,rs2 is:", rs1, rs2)

}

结果为

rs 复制代码
当前的rs1,rs2为: 2 2
2 * (2*i + 1) / (i + 2)为: 2
最后rs1 is,rs2 is: 5 4

初步判断,问题出在除法这里. 去掉除法部分后,确实得到的结果都一样.

在数学中 乘除运算不分先后. 但因为可能无法整除,对计算机来说,除不尽的部分会一律向下取整。所以乘除的先后顺序,实际是对最终结果有影响的

对于 rs1 ,其等于 2 * 2 * 7 / 5,即28/5,向下取整,即为5

对于rs2 , 会先计算后面部分2 * (2*3 + 1) / (3 + 2) = 14/5 = 2, 而后计算 2*2 = 4


crontab配置问题

Linux自带的crontab只能精确到分钟,而某些语言的工具包,可以提供精确到秒的crontab.

但在使用时,务必注意,如0 */10 * * * *,是从下一个 xx:x0:00 开始,每10分钟执行一次.

如写成 * */10 * * * *, 就成了每秒钟执行一次,如有对数据库的读写操作,会造成巨大压力.

上线前可以用这个工具, 选Java(Spring)项,来校验一下


map和slice变量的赋值作用范围问题

go 复制代码
package main

import "fmt"

func main() {

	m := make(map[string]string)

	m["gender"] = "女"

	fmt.Println("map is:", m)

	f1(&m)

	fmt.Println("map is:", m)

}

func f1(m1 *map[string]string) *map[string]string {

	(*m1)["name"] = "dashen"
	(*m1)["gender"] = "男"
	return m1
}

运行结果:

go 复制代码
map is: map[gender:女]
map is: map[gender:男 name:dashen]

但这种写法,非常不Golang!

在函数A中定义一个map记为m,想要在函数B,函数C中对其进行赋值或修改,是没有必要传指针的

go 复制代码
package main

import "fmt"

func main() {

	m := make(map[string]string)

	m["gender"] = "女"

	fmt.Println("map is:", m)

	f1(m)

	fmt.Println("map is:", m)

}

func f1(m1 map[string]string) map[string]string {

	m1["name"] = "dashen"
	m1["gender"] = "男"
	return m1
}

运行结果:

go 复制代码
map is: map[gender:女]
map is: map[gender:男 name:dashen]

对于slice,情况有所不同

go 复制代码
package main

import "fmt"

func main() {

	sli := make([]string, 1)

	sli[0] = "宋江"

	fmt.Println("slice is:", sli)

	f1(sli)

	fmt.Println("slice is:", sli)

}

func f1(sli1 []string) []string {

	sli1[0] = "晁盖"

	return sli1
}

运行结果:

go 复制代码
slice is: [宋江]
slice is: [晁盖]

与map的"全部引用"不同,slice只是底层数组是指针类型,长度和容量不是.

对于上面这样只修改原有值,而没有append操作的行为,是没有问题的.

但如果有append操作,引发了扩容,底层数组的地址变了,则将会得不到预期结果


sql的update问题

update一条不存在的记录,Affected rows为0,但并不会报错

UPDATE a SET name="卡拉马佐夫兄弟" WHERE id=12345

update一条存在的记录,但实际并没有对现有内容进行更新,Affected rows也会是0


Golang 58个坑

相关推荐
行百里er3 小时前
Redis 完结篇——Redis 热点问题在 Spring Boot 项目中实战
redis·后端
高频因子挖掘机4 小时前
只取最近 60 个交易日,却每次拉全历史:量化脚本变慢的原因与改法
后端·github·api
孟健5 小时前
从5000亿Token到83%字节匹配:AI逆向工程与重构的工程闭环实践
后端·架构·ai编程
码事漫谈6 小时前
丢得静悄悄,谈一谈 Agent 的记忆是怎么没的
后端
迪飞特科技6 小时前
智慧物业平台实战:Spring Boot 整合小程序实现报修巡检费用全流程
spring boot·后端·小程序
考虑考虑6 小时前
@JsonInclude注解使用
spring boot·后端·spring
IT_陈寒6 小时前
Vite的这个问题坑了我三天,原来如此解决!
前端·人工智能·后端
网易云信6 小时前
大模型能上岗做销售吗?我们让 12 款国产模型交了 420 份作业
前端·后端
CCblandy6 小时前
HTTP 长连接 3 类故障实测:[WinError 10053]、99 个 TIME_WAIT、69 次多余握手,4 种对策怎么选
后端·python·网络协议·http·云原生·性能优化·架构
蜗牛互联网6 小时前
Python Agent工具调用的白名单、参数校验与审批门禁
java·服务器·前端·人工智能·后端·python