面试题答案
一键面试-
溢出情况: 在Go语言中,整型运算发生溢出时不会抛出异常,而是会截断结果。例如,对于无符号整数
uint8
,它的取值范围是0
到255
。当进行超出这个范围的运算时会截断。package main import ( "fmt" ) func main() { var a uint8 = 255 a = a + 1 fmt.Printf("result: %d\n", a) }
上述代码中,
a
初始值为255
,再加上1
,结果应该是256
,但由于uint8
最大只能表示255
,所以结果会截断为0
。 -
可能遇到整型溢出的业务场景:
- 计数器场景:例如在记录网站的访问量时,如果使用一个较小的整型(如
int16
)来记录,随着访问量的不断增加,很可能会超出其表示范围,导致溢出。 - 时间戳计算:在处理时间相关计算时,如果使用整型来存储时间戳差值,在长时间跨度计算(如跨越多年的时间差)时,可能会出现溢出。
- 计数器场景:例如在记录网站的访问量时,如果使用一个较小的整型(如
-
避免方法:
- 选择合适的数据类型:根据业务场景预估数据的最大值,选择足够大的整型数据类型。如在记录网站访问量时,如果访问量可能很大,可以使用
int64
。 - 溢出检查:在进行运算前,手动检查是否可能溢出。例如在进行加法运算前,检查是否会超过目标类型的最大值。对于无符号整数
x
和y
,x + y
可能溢出的检查可以这样写:
func addNoOverflow(x, y uint64) (uint64, bool) { result := x + y if result < x { return 0, true } return result, false }
- 使用大整数库:如果需要处理非常大的整数,Go语言标准库提供了
math/big
包,可以处理任意大小的整数,避免溢出问题。例如:
package main import ( "fmt" "math/big" ) func main() { var a, b big.Int a.SetString("12345678901234567890", 10) b.SetString("98765432109876543210", 10) var result big.Int result.Add(&a, &b) fmt.Println(result.String()) }
这样可以安全地处理大整数运算而不用担心溢出。
- 选择合适的数据类型:根据业务场景预估数据的最大值,选择足够大的整型数据类型。如在记录网站访问量时,如果访问量可能很大,可以使用