手機網(wǎng)站建設(shè)咨詢查詢百度關(guān)鍵詞排名
乘除順序問題
在據(jù)卡特蘭數(shù)[1]公式,解決leetcode-96 不同的二叉搜索樹[2]時,遇到一個非常詭異的問題,
package?main
import?"fmt"
func?main()?{
?for?i?:=?0;?i?<=?40;?i++?{
??fmt.Printf("第%d個卡特蘭數(shù)為:%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
}
即 注釋掉的這一行,居然和上一行得出了完全不同的結(jié)果. 雖然馬上解決,但對固有認知影響巨大---
難道對一直以來習以為常的乘法語法糖理解有誤???
*= 為乘法和賦值運算符,它將右操作數(shù)與左操作數(shù)相乘,并將結(jié)果賦給左操作數(shù). C *= A 相當于 C = C * A
讀了一遍感覺沒問題,那原因出在哪里呢?
構(gòu)建demo,
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)
}
結(jié)果為
當前的rs1,rs2為:?2?2
2?*?(2*i?+?1)?/?(i?+?2)為:?2
最后rs1?is,rs2?is:?5?4
初步判斷,問題出在除法這里. 去掉除法部分后,確實得到的結(jié)果都一樣.
在數(shù)學中 乘除運算不分先后. 但因為可能無法整除,對計算機來說,除不盡的部分會一律向下取整。所以乘除的先后順序,實際是對最終結(jié)果有影響的
對于 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.
但在使用時,務(wù)必注意,如0 */10 * * * *
,是從下一個 xx:x0:00 開始,每10分鐘執(zhí)行一次.
如寫成 * */10 * * * *
, 就成了每秒鐘執(zhí)行一次,如有對數(shù)據(jù)庫的讀寫操作,會造成巨大壓力.
上線前可以用這個工具[3], 選Java(Spring)
項,來校驗一下
map和slice變量的賦值作用范圍問題
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
}
運行結(jié)果:
map?is:?map[gender:女]
map?is:?map[gender:男?name:dashen]
但這種寫法,非常不Golang!
在函數(shù)A中定義一個map記為m,想要在函數(shù)B,函數(shù)C中對其進行賦值或修改,是沒有必要傳指針的
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
}
運行結(jié)果:
map?is:?map[gender:女]
map?is:?map[gender:男?name:dashen]
對于slice,情況有所不同
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
}
運行結(jié)果:
slice?is:?[宋江]
slice?is:?[晁蓋]
與map的"全部引用"不同,slice只是底層數(shù)組是指針類型,長度和容量不是.
對于上面這樣只修改原有值,而沒有append操作的行為,是沒有問題的.
但如果有append操作,引發(fā)了擴容,底層數(shù)組的地址變了,則將會得不到預期結(jié)果
sql的update問題

update一條不存在的記錄,Affected rows為0,但并不會報錯
UPDATE a SET
name="卡拉馬佐夫兄弟" WHERE id=12345

update一條存在的記錄,但實際并沒有對現(xiàn)有內(nèi)容進行更新,Affected rows也會是0

Golang 58個坑[4]
參考資料
卡特蘭數(shù): https://dashen.tech/2021/02/28/%E5%8D%A1%E7%89%B9%E5%85%B0%E6%95%B0/
[2]leetcode-96 不同的二叉搜索樹: https://dashen.tech/2015/03/01/leetcode-96-%E4%B8%8D%E5%90%8C%E7%9A%84%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91/
[3]這個工具: https://tool.lu/crontab/
[4]Golang 58個坑: https://www.bookstack.cn/read/topgoer/e2f3480b549aebc2.md
本文由 mdnice 多平臺發(fā)布