一面:
1.B+樹(shù)的時(shí)間復(fù)雜度:O(logn),當(dāng)時(shí)說(shuō)成nlogn是講話(huà)時(shí)沒(méi)思考,B樹(shù)也說(shuō)成B減樹(shù),汗顏。
2.聚簇索引在存儲(chǔ)方式上的特點(diǎn),跟主鍵id是否自增有沒(méi)有關(guān)聯(lián):只要聚簇索引是相鄰的,那么對(duì)應(yīng)的數(shù)據(jù)一定也是相鄰地存放在磁盤(pán)上的。如果主鍵不是自增id,那么可以想象它會(huì)不斷地調(diào)整數(shù)據(jù)的物理地址、分頁(yè)。比如,使用UUID作為聚簇索引會(huì)很糟糕:它使得聚簇索引的插入變得完全隨機(jī)。
3.mysql的樂(lè)觀(guān)鎖、悲觀(guān)鎖區(qū)別:樂(lè)觀(guān)鎖用版本號(hào)方式來(lái)解決,悲觀(guān)鎖用阻塞其他select操作的方式解決問(wèn)題。
4.tcp/ip分層當(dāng)時(shí)講的模糊,現(xiàn)在重講:
比特流一層
arp協(xié)議等,以及物理地址尋址、數(shù)據(jù)的成幀、流量控制、數(shù)據(jù)的檢錯(cuò)、重發(fā)一層
ip協(xié)議一層
tcp udp等協(xié)議一層
http,ftp等協(xié)議一層
5.線(xiàn)程,進(jìn)程,協(xié)程的區(qū)分:
進(jìn)程擁有自己獨(dú)立的堆和棧,既不共享堆,亦不共享?xiàng)#M(jìn)程由操作系統(tǒng)調(diào)度。
線(xiàn)程擁有自己獨(dú)立的棧和共享的堆,共享堆,不共享?xiàng)#€(xiàn)程也由操作系統(tǒng)調(diào)度。
協(xié)程和線(xiàn)程一樣共享堆,不共享?xiàng)#瑓f(xié)程由程序員在代碼里調(diào)度。(援引網(wǎng)絡(luò)博文)
當(dāng)運(yùn)行一個(gè)程序時(shí),OS會(huì)為這個(gè)程序啟動(dòng)一個(gè)進(jìn)程,可以將進(jìn)程看做一個(gè)包含了程序在運(yùn)行中需要用到和維護(hù)的各種資源的容器。
一個(gè)線(xiàn)程是一個(gè)執(zhí)行空間,這個(gè)空間會(huì)被OS來(lái)運(yùn)行函數(shù)中所寫(xiě)的代碼。每個(gè)進(jìn)程至少包含一個(gè)線(xiàn)程,每個(gè)進(jìn)程的初始線(xiàn)程被稱(chēng)作主線(xiàn)程。(援引自GO語(yǔ)言實(shí)戰(zhàn))
6.用grep從百萬(wàn)行數(shù)據(jù)里面匹配出對(duì)應(yīng)模式的數(shù)據(jù)前10條:
grep -e "pattern" -m 10 filepath
7.redis pub/sub如何保證消息可靠性?
redis的pub/sub不能直接支持消息可靠,建議用rabbitmq等功能更強(qiáng)的消息隊(duì)列。
8.php浮點(diǎn)型應(yīng)注意什么?(當(dāng)時(shí)沒(méi)有講很細(xì),沒(méi)有講出浮點(diǎn)型保存的小數(shù)為什么精度會(huì)失準(zhǔn)。)
二進(jìn)制保存十進(jìn)制的小數(shù),比如5.2 在十進(jìn)制5.2是有限小數(shù),改成二進(jìn)制確實(shí)無(wú)限小數(shù),所以保存起來(lái),精度肯定會(huì)有一些缺失。
詳解可以參考盧鈞軼博客http://cenalulu.github.io/linux/about-denormalized-float-number/
可以知道需要用到bcmath這樣的數(shù)學(xué)函數(shù)庫(kù)來(lái)操作浮點(diǎn)數(shù)的運(yùn)算,來(lái)保證精度。
參考鳥(niǎo)哥博客,http://www.laruence.com/2011/12/19/2399.html http://www.laruence.com/2013/03/26/2884.html
二面
1.積分排行榜解決方案:利用redis的zset數(shù)據(jù)結(jié)構(gòu)的 zrank key member實(shí)現(xiàn),原理類(lèi)似二分搜索。
2.go高并發(fā)的原理:我的回答是利用了協(xié)程,占用cpu和內(nèi)存的資源比進(jìn)程和線(xiàn)程少。理由顯然單薄。補(bǔ)充如下:
內(nèi)存方面:
執(zhí)行協(xié)程只需要極少的棧內(nèi)存(大概是4~5KB),默認(rèn)情況下,線(xiàn)程棧的大小為1MB-8MB
goroutine 的創(chuàng)建初始內(nèi)存成本很低廉,并且會(huì)根據(jù)需要?jiǎng)討B(tài)增長(zhǎng)和縮減占用的資源。這使得 goroutine 會(huì)從 4096 字節(jié)的初始棧內(nèi)存占用開(kāi)始按需增長(zhǎng)或縮減內(nèi)存占用,而無(wú)需擔(dān)心資源的耗盡。(援引自網(wǎng)絡(luò)博文)
模型優(yōu)勢(shì)方面:GO語(yǔ)言自帶一個(gè)可以調(diào)度線(xiàn)程和協(xié)程運(yùn)行的調(diào)度處理器,這個(gè)調(diào)度處理器實(shí)現(xiàn)了一些高級(jí)的算法,并發(fā)模型具有優(yōu)勢(shì)。
進(jìn)程I/O訪(fǎng)問(wèn),阻塞了后面所有的計(jì)算,OS就直接把CPU切換到其他進(jìn)程,讓人家先用著。當(dāng)然除了I\O阻塞,還有時(shí)鐘阻塞等等。然后就出現(xiàn)了一個(gè)問(wèn)題,就是太慢了,一切換進(jìn)程得反復(fù)進(jìn)入內(nèi)核,置換掉一大堆狀態(tài)。進(jìn)程數(shù)一多,大部分系統(tǒng)資源就被進(jìn)程切換給吃掉了。后來(lái)也有用線(xiàn)程來(lái)改善的,大致意思就是,這個(gè)地方阻塞了,但我還有其他地方的邏輯流可以計(jì)算,這些邏輯流是共享一個(gè)地址空間的,不用特別麻煩的切換頁(yè)表、刷新TLB等,只要把寄存器刷新一遍就行,能比切換進(jìn)程開(kāi)銷(xiāo)少點(diǎn)。而協(xié)程是在進(jìn)程里寫(xiě)一個(gè)邏輯處理器調(diào)度,利用到了并發(fā)優(yōu)勢(shì),又可以避免反復(fù)系統(tǒng)調(diào)用,也沒(méi)有進(jìn)程切換造成的開(kāi)銷(xiāo)。這種用戶(hù)態(tài)線(xiàn)程就叫協(xié)程。
協(xié)程主要解決了兩個(gè)必須的問(wèn)題:一是碰著阻塞式I\O會(huì)導(dǎo)致整個(gè)進(jìn)程被掛起;二是由于缺乏時(shí)鐘阻塞,進(jìn)程需要自己擁有調(diào)度線(xiàn)程的能力。如果一種實(shí)現(xiàn)使得每個(gè)線(xiàn)程需要自己通過(guò)調(diào)用某個(gè)方法,主動(dòng)交出控制權(quán)。那么我們就成這種用戶(hù)態(tài)線(xiàn)程是協(xié)作式的,就是協(xié)程。(引用自知乎~阿貓)
3.分庫(kù)分表技術(shù)方面考慮,什么時(shí)候該分庫(kù)分表,怎么操作?
垂直分表,把不常用的字段拆分到另外一張表。
垂直分庫(kù),把不同業(yè)務(wù)的數(shù)據(jù)放在不同的庫(kù)。服務(wù)化的拆分利于解耦和提高性能,也利于系統(tǒng)擴(kuò)展。
水平分表,表中的數(shù)據(jù)(比如user表)按照一定規(guī)律(比如對(duì)id進(jìn)行hash和取模后拆分)。可以一定程度緩解查詢(xún)性能瓶頸。但還會(huì)有庫(kù)級(jí)別IO瓶頸,因?yàn)閿?shù)據(jù)在同一個(gè)庫(kù)中。
水平分庫(kù)分表,于水平分表類(lèi)似,唯一不同是將這些拆分出來(lái)的表保存在不同的數(shù)據(jù)庫(kù)中。在冷熱數(shù)據(jù)分離的場(chǎng)景很適用。能有效緩解單機(jī)和單褲性能瓶頸壓力,突破IO、連接數(shù)、硬件資源的瓶頸。(援引Infoq作者 丁浪)
4.mysql讀寫(xiě)分離或負(fù)載均衡靠什么機(jī)制調(diào)度?
應(yīng)該是問(wèn)mysql數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)層主流方案,這個(gè)我沒(méi)接觸過(guò),以后再補(bǔ)充。
5.mysql跨庫(kù)事務(wù)怎么做
第一,用mysql5.7的XA特性。第二,或者用隊(duì)列(需要設(shè)計(jì)一下這個(gè)隊(duì)列,我后面補(bǔ)充下)來(lái)確保兩個(gè)任務(wù)執(zhí)行成功(限不需要回滾的場(chǎng)景)
6.redis集群增加或減少一個(gè)節(jié)點(diǎn)應(yīng)注意什么?
參考codis的redis集群方案的增加和減少節(jié)點(diǎn)的方法。http://www.lxweimin.com/p/ec6a04eb66c3
7.swoole worker 的運(yùn)行方式,我回答是以多線(xiàn)程方式運(yùn)行的,其實(shí)是以多進(jìn)程方式運(yùn)行。
關(guān)于Reactor Worker Task的關(guān)系,我后期再補(bǔ)充下。
14.memcache 一致性哈希原理?
簡(jiǎn)單的講,就是利用hash環(huán)和虛擬節(jié)點(diǎn)的思路,把請(qǐng)求分發(fā)到分布得很細(xì)密的虛擬節(jié)點(diǎn)上。增加或刪除節(jié)點(diǎn)的時(shí)候,該節(jié)點(diǎn)的緩存會(huì)被分發(fā)到下一虛擬節(jié)點(diǎn),而不會(huì)影響其他節(jié)點(diǎn)的已有緩存的命中率。
參考,朱雙印博客
http://www.zsythink.net/archives/1182
php對(duì)memcache/memcached的一致性實(shí)操,可以通過(guò)三種方式實(shí)現(xiàn):
第一,修改php.ini memcache擴(kuò)展的配置:
[Memcache]
Memcache.allow_failover = 1
Memcache.hash_strategy =consistent
Memcache.hash_function =crc32
第二,使用memcachd擴(kuò)展時(shí),可以通過(guò)setOption方法配置。
$mem = new Memcached();
$mem->setOption(Memcached::OPT_HASH, Memcached::HASH_CRC);
$mem->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT);
$servers = array(
array('192.168.20.193', 11211, 33),
array('192.168.20.194', 11211, 67)
);
$mem->addServers($servers);
print_r($mem->get('str_key'));
第三,可以通過(guò)php代碼實(shí)現(xiàn),比如flexihash.php類(lèi)庫(kù)
援引http://www.itnose.net/detail/6619318.html