字節(jié)跳動 Golang面試

應朋友之邀刺桃,今天下午去字節(jié)送了顆人頭,最后不負眾望,被面試官攆出來了……

一面

談一下之前重構百度賬號中心的方案

吹了一波之前在百度改造restful接口的方案,但面試官并不感冒敢靡,提了一個顯示文章的列表的場景,但感覺沒有理解面試官的意思苦银,沒有提出面試官滿意的restful解決方案啸胧,剛開始就得了個負分,這塊得抽空找大佬再探討探討幔虏,等后面有什么心得再補充吧

mysql索引快的原理

回答這個問題需要先看一下數(shù)據(jù)庫的存儲結構


頁結構

頁和頁之間的關系

頁和頁之間的關系

有個知識纺念,之前不知道的
聚集索引:以主鍵創(chuàng)建的索引,葉子節(jié)點存儲的是表中的數(shù)據(jù)
非聚集索引:非主鍵創(chuàng)建的索引想括,葉子節(jié)點中存儲的是主鍵和索引列陷谱,使用非聚集索引查詢數(shù)據(jù),會查詢到葉子上的主鍵主胧,再根據(jù)主鍵查到數(shù)據(jù)(這個過程叫做回表)

沒有用索引的時候叭首,需要遍歷雙向鏈表來定位對應的頁,有了索引踪栋,可以用二分查找焙格,這么弱智的答案,我當時居然沒想到夷都,這也是后面面試官問為什么主鍵建議用自增字段的答案

頁碼跳頁性能(即sql offset會不會影響性能)

mysql查詢時眷唉,offset過大影響性能的原因是多次通過主鍵索引訪問數(shù)據(jù)塊的I/O操作
InnoDB會,MyISAM不會囤官,如圖所示


InnoDB和MyISAM對比圖

InnoDB的二級索引對應的是主鍵冬阳,mysql查詢的時候會根據(jù)主鍵將數(shù)據(jù)塊查出來,然后執(zhí)行offset丟棄党饮,如果只查主鍵就不會有性能問題肝陪。MyISAM的主鍵索引和二級索引都指向數(shù)據(jù)塊,因此沒有這方面的問題

優(yōu)化措施

先查詢偏移后的主鍵刑顺,再查詢數(shù)據(jù)塊

select a.* from member as a inner join (select id from member where gender=1 limit 300000,1) as b on a.id=b.id

golang中new和make的區(qū)別

  1. make 僅用來分配及初始化類型為 slice氯窍、map、chan 的數(shù)據(jù)蹲堂。new 可分配任意類型的數(shù)據(jù).
  2. new 分配返回的是指針狼讨,即類型 *Type。make 返回引用柒竞,即 Type.
  3. new 分配的空間被清零, make 分配空間后政供,會進行初始化.

有一個字母翻譯對照表,1代表A朽基,2代表B布隔,以此類推至26代表Z,現(xiàn)給一個整形數(shù)組踩晶,例如[1,2,3,4,5,6,7,8,9],求共有多少種翻譯方式

package main

import (
    "fmt"
)

func main() {
    s := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
    dict := make(map[int]string)
    for i := 1; i < 27; i++ { //初始化字典
        dict[i] = string('A' + (i - 1))
    }
    count := 0
    for i := 0; i < len(s); i++ {
        if i == 0 {
            count++
        } else if s[i-1]*10+s[i] < 27 && s[i-1]*10+s[i] > 0 {
            count++
        }
    }
    fmt.Println(count)
}

redis zset的數(shù)據(jù)結構

zset結構

如圖所示执泰,L0層存儲所有的數(shù)據(jù),L1層隨機抽取幾個組成一個系數(shù)索引渡蜻,L2層進一步抽取L1層术吝,從而組成一個多層稀疏索引,這樣就可以用二分法快速的找出所需要的數(shù)據(jù)了

利用redis做一個延時事件執(zhí)行系統(tǒng)(設計)

延時執(zhí)行設計

當時想的設計跟盒子科技的這張PPT高度類似茸苇,以時間為score排苍,以事件數(shù)組為value,存儲成一個zset学密,然后定期去取一定數(shù)量的事件進行執(zhí)行淘衙。如果延時執(zhí)行事件比較稀疏,就設定一個值腻暮,比如每次取的事件必須是一分鐘內(nèi)的彤守,一分鐘內(nèi)沒有時間則等待下次再取毯侦。

二面

PHP代碼sleep的時候,進程狀態(tài)是怎樣的具垫,進程都有哪幾種狀態(tài)

  1. 創(chuàng)建狀態(tài)
  2. 就緒狀態(tài)
  3. 運行狀態(tài)
  4. 阻塞狀態(tài)
  5. 終止狀態(tài)

當代碼執(zhí)行sleep的時候進程處于阻塞狀態(tài)

linux系統(tǒng)中如何查看進程狀態(tài)

使用命令 ps -aux侈离,STAT列即為進程狀態(tài)

進程示例

linux上進程有五種狀態(tài)

  1. R——Runnable(運行):正在運行或在運行隊列中等待
  2. S——sleeping(中斷):休眠中,受阻筝蚕,在等待某個條件的形成或接收到信號
  3. D——uninterruptible sleep(不可中斷):收到信號不喚醒和不可運行卦碾,進程必須等待直到有中斷發(fā)生
  4. Z——zombie(僵死):進程已終止,但進程描述還在起宽,直到父進程調(diào)用wait4()系統(tǒng)調(diào)用后釋放
  5. T——traced or stoppd(停止):進程收到SiGSTOP,SIGSTP,SIGTOU信號后停止運行

狀態(tài)后綴表示:

<:優(yōu)先級高的進程
N:優(yōu)先級低的進程
L:有些頁被鎖進內(nèi)存
s:進程的領導者(在它之下有子進程)
l:ismulti-threaded (using CLONE_THREAD, like NPTL pthreads do)
+:位于后臺的進程組

數(shù)據(jù)庫事務的實現(xiàn)原理

數(shù)據(jù)庫不同的存儲引擎可能會有一些區(qū)別洲胖。這里拿常用的InnerDB存儲引擎舉例:

原子性實現(xiàn)原理:

通過數(shù)據(jù)庫Undo Log實現(xiàn)的。事務中在操作任何數(shù)據(jù)之前坯沪,首先將原數(shù)據(jù)備份到Undo Log然后進行數(shù)據(jù)的修改绿映。如果事務中有任意操作發(fā)生異常或用戶執(zhí)行了 Rollback 語句屏箍,那么數(shù)據(jù)庫就會使用Undo Log中的備份將數(shù)據(jù)恢復到事務開始之前的狀態(tài)绘梦。

一致性實現(xiàn)原理:

與原子性實現(xiàn)原理一樣也是利用Undo Log

持久性實現(xiàn)原理:

通過數(shù)據(jù)庫Redo Log實現(xiàn)的,Redo Log與Undo Log 相反赴魁,Redo Log 記錄的是新數(shù)據(jù)的備份卸奉,事務提交之前,會把數(shù)據(jù)備份到Redo Log中并持久化颖御。當系統(tǒng)崩潰時榄棵,雖然數(shù)據(jù)沒有持久化到數(shù)據(jù)庫中,但是 Redo Log 已經(jīng)持久化潘拱。系統(tǒng)可以根據(jù) Redo Log 的內(nèi)容疹鳄,將所有數(shù)據(jù)恢復到最新的

隔離性實現(xiàn)原理:

隔離性的實現(xiàn)原理比較特殊,是通過數(shù)據(jù)庫鎖的機制實現(xiàn)的芦岂。
隔離性分四個級別:讀未提交(Read uncommitted)瘪弓、讀已提交(Read committed)、可重復讀(Repeatable reads)禽最、可序列化(Serializable)
MySQL的默認隔離級別就是Repeatable,Oracle默認Read committed

讀未提交:一個事務可以讀到另外一個事務未提交的數(shù)據(jù)腺怯。臟讀

實現(xiàn):事務在讀數(shù)據(jù)的時候并未對數(shù)據(jù)進行加鎖。
事務在發(fā)生更新數(shù)據(jù)的瞬間川无,必須先對其加 行級共享鎖呛占,直到事務結束才釋放。
舉例:事務A讀取某行記錄時(沒有加鎖)懦趋,事務2也能對這行記錄進行讀取晾虑、更新。當事務B對該記錄進行更新時,事務A讀取該記錄帜篇,能讀到事務B對該記錄的修改版本糙捺,即使該修改尚未被提交。
事務A更新某行記錄時笙隙,事務B不能對這行記錄做更新继找,直到事務A結束。

讀已提交:一個事務可以讀到另外一個事務提交的數(shù)據(jù)逃沿。不可重復讀

實現(xiàn):事務對當前被讀取的數(shù)據(jù)加 行級共享鎖(當讀到時才加鎖),一旦讀完該行幻锁,立即釋放該行級共享鎖凯亮;
事務在更新某數(shù)據(jù)的瞬間(就是發(fā)生更新的瞬間),必須先對其加 行級排他鎖哄尔,直到事務結束才釋放假消。
原理:事務A讀取某行記錄時,事務B也能對這行記錄進行讀取岭接、更新富拗;當事務B對該記錄進行更新時,事務A再次讀取該記錄鸣戴,讀到的只能是事務B對其更新前的版本啃沪,或者事務B提交后的版本。
事務A更新某行記錄時窄锅,事務B不能對這行記錄做更新创千,直到事務1結束。
流程描述:事務A讀操作會加上共享鎖入偷,事務B寫操作時會加上排他鎖追驴,當事務B正在寫操作時,事務A要讀操作疏之,發(fā)現(xiàn)有排他鎖殿雪,事務A就會阻塞,等待排他鎖釋放(事務B寫操作提交才會釋放)锋爪,才能進行讀操作丙曙。

可重復讀

實現(xiàn):事務在讀取某數(shù)據(jù)的瞬間(就是開始讀取的瞬間),必須先對其加 行級共享鎖几缭,直到事務結束才釋放河泳;
事務在更新某數(shù)據(jù)的瞬間(就是發(fā)生更新的瞬間),必須先對其加 行級排他鎖年栓,直到事務結束才釋放拆挥。
舉例:事務A讀取某行記錄時,事務B也能對這行記錄進行讀取、更新纸兔;當事務B對該記錄進行更新時惰瓜,事務A再次讀取該記錄,讀到的仍然是第一次讀取的那個版本汉矿。
事務A更新某行記錄時崎坊,事務B不能對這行記錄做更新,直到事務1結束洲拇。

可序列化(Serializable) 寫操作串聯(lián)執(zhí)行

實現(xiàn):事務在讀取數(shù)據(jù)時奈揍,必須先對其加 表級共享鎖 ,直到事務結束才釋放赋续;
事務在更新數(shù)據(jù)時男翰,必須先對其加 表級排他鎖 ,直到事務結束才釋放纽乱。
舉例:事務A正在讀取A表中的記錄時蛾绎,則事務B也能讀取A表,但不能對A表做更新鸦列、新增租冠、刪除,直到事務A結束薯嗤。
事務A正在更新A表中的記錄時顽爹,則事務B不能讀取A表的任意記錄,更不可能對A表做更新骆姐、新增话原、刪除,直到事務A結束诲锹。
原理:在讀操作時繁仁,加表級共享鎖,事務結束時釋放归园;寫操作時候黄虱,加表級獨占鎖,事務結束時釋放庸诱。

聚簇索引

跟聚集索引是一個東西捻浦,參見上面的聚集索引

反轉一個鏈表,如1->2->3->4->5->6桥爽,轉為1->5->4->3->2->6

package main

import "fmt"

// ListNode 鏈表節(jié)點
type ListNode struct {
    Val  int
    Next *ListNode
}

//反轉鏈表的實現(xiàn)
func reversrList(head *ListNode) *ListNode {
    cur := head
    var pre *ListNode = nil
    for cur != nil {
        pre, cur, cur.Next = cur, cur.Next, pre //這句話最重要
    }
    return pre
}

// Print 打印鏈表
func (l *ListNode) Print() {
    for l != nil {
        if l.Val > 0 {
            fmt.Println(l.Val)
        }
        l = l.Next
    }
}

func main() {
    m := 1
    n := 4
    root := new(ListNode)//頭結點
    p := root
    for i := 1; i < 7; i++ {//初始化鏈表
        node := new(ListNode)
        node.Val = i
        p.Next = node
        p = p.Next
    }
    p.Next = new(ListNode)//尾節(jié)點
    l1 := root
    var l2, l3 *ListNode
    p = root
    index := 0
    for l3 == nil {//截成三段
        if index == m {
            l2 = p.Next
            p.Next = nil
            p = l2
        }
        if index == n {
            l3 = p.Next
            p.Next = nil
        }
        p = p.Next
        index++
    }
    l2 = reversrList(l2)// 反轉l2
    list := []*ListNode{l2, l3}
    p = l1
    index = 0
    for index < len(list) {//拼接起來
        for p.Next != nil {
            p = p.Next
        }
        p.Next = list[index]
        index++
    }
    l1.Print()
}

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末朱灿,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子钠四,更是在濱河造成了極大的恐慌盗扒,老刑警劉巖跪楞,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異侣灶,居然都是意外死亡甸祭,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進店門褥影,熙熙樓的掌柜王于貴愁眉苦臉地迎上來池户,“玉大人,你說我怎么就攤上這事凡怎⌒=梗” “怎么了?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵统倒,是天一觀的道長斟湃。 經(jīng)常有香客問我,道長檐薯,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任注暗,我火速辦了婚禮坛缕,結果婚禮上,老公的妹妹穿的比我還像新娘捆昏。我一直安慰自己赚楚,他們只是感情好,可當我...
    茶點故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布骗卜。 她就那樣靜靜地躺著宠页,像睡著了一般。 火紅的嫁衣襯著肌膚如雪寇仓。 梳的紋絲不亂的頭發(fā)上举户,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天,我揣著相機與錄音遍烦,去河邊找鬼俭嘁。 笑死,一個胖子當著我的面吹牛服猪,可吹牛的內(nèi)容都是我干的供填。 我是一名探鬼主播,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼罢猪,長吁一口氣:“原來是場噩夢啊……” “哼近她!你這毒婦竟也來了?” 一聲冷哼從身側響起膳帕,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤粘捎,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體晌端,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡捅暴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了咧纠。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蓬痒。...
    茶點故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖漆羔,靈堂內(nèi)的尸體忽然破棺而出梧奢,到底是詐尸還是另有隱情,我是刑警寧澤演痒,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布亲轨,位于F島的核電站,受9級特大地震影響鸟顺,放射性物質(zhì)發(fā)生泄漏惦蚊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一讯嫂、第九天 我趴在偏房一處隱蔽的房頂上張望蹦锋。 院中可真熱鬧,春花似錦欧芽、人聲如沸莉掂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽憎妙。三九已至,卻和暖如春曲楚,著一層夾襖步出監(jiān)牢的瞬間厘唾,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工龙誊, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留阅嘶,地道東北人。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓载迄,卻偏偏與公主長得像讯柔,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子护昧,可洞房花燭夜當晚...
    茶點故事閱讀 45,500評論 2 359