第一次面百度,你覺得這個難度怎么樣?
圖片
面經詳解
操作系統處理死鎖的方法
首先我們來了解一下什么是死鎖:
圖片
死鎖(Deadlock):是指兩個或兩個以上的進程在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去。稱此時系統處于死鎖狀態或系統產生了死鎖。
產生死鎖的必要條件
圖片
- 互斥條件
- 不可剝奪條件
- 占有并請求條件
- 循環等待條件
死鎖的處理策略
操作系統內存管理的方法
操作系統的內存管理方法主要包括以下幾種:
- 分區分配
- 固定大小分區:內存被劃分為若干固定大小的分區,每個分區分配給一個進程。
優點:實現簡單,分區大小固定。
缺點:內存利用率低,可能導致內部碎片。
- 可變大小分區:根據進程需求動態分配內存分區。
優點:提高內存利用率,減少內部碎片。
缺點:容易產生外部碎片,需要定期進行內存緊湊。
- 頁式存儲管理
- 分頁:將內存和進程地址空間分成固定大小的頁(page)和頁框(page frame)。
優點:消除外部碎片,提高內存利用率。
缺點:可能產生內部碎片,頁表的管理需要額外的內存和處理時間。
- 段式存儲管理
- 分段:將進程的邏輯地址空間劃分為若干段(segment),每段有一個段號和偏移量。
優點:方便進程模塊化管理,保護不同段的內存。
缺點:可能產生外部碎片,段表管理復雜。
- 段頁式存儲管理
- 段頁結合:將分頁和分段結合使用。先將進程分成若干段,再將每段分成若干頁。
優點:結合了分頁和分段的優點,減少了碎片,提高了靈活性。
缺點:段表和頁表管理復雜,增加了內存開銷。
- 虛擬內存
- 需求分頁:進程只有在需要時才將相應的頁調入內存。
優點:減少內存使用,提高內存利用率。
缺點:需要頁表和頁面置換算法,可能產生頁面抖動(thrashing)。
- 頁面置換算法:在內存不足時,決定哪些頁面需要換出內存。
FIFO(先進先出):最先調入內存的頁最先被換出。
LRU(最近最少使用):換出最近最少使用的頁面。
OPT(最佳置換):換出將來最長時間不被訪問的頁面。
Clock(時鐘):一種近似LRU的算法,使用一個環形緩沖區來管理頁面。
- 內存緊湊和垃圾回收
- 內存緊湊:將內存中所有的空閑塊集中到一起,消除外部碎片。
優點:提高內存利用率。
缺點:需要大量的移動操作,開銷大。
- 垃圾回收:自動回收不再使用的內存塊。
優點:簡化內存管理,防止內存泄漏。
缺點:增加了系統開銷,可能影響性能。
redis持久化
RDB持久化(全量備份)
RDB持久化是指在指定時間間隔內將內存中的數據集快照寫入磁盤。實際上fork子線程,先將數據集寫入臨時文件,寫入成功后,在替換之前的文件,用二進制壓縮文件,RDB是Redis默認的持久化方式,會在對應目錄下生產一個dump.rdb文件,重啟會通過加載dump.rdb文件恢復數據。
RDB優點:
- 方便持久化:只有一個dump.rdb文件;
- 容災性好:一個文件可以保存到安全的磁盤;
- 性能好:fork子線程來完成寫操作,主線程繼續處理命令;
- 效率高:如何數據集偏大,RDB啟動效率比AOF高
RDB缺點:
- 數據安全性低:因為RDB是每隔一段時間進行持久化,可能會造成數據丟失。
- 由于RDB是通過fork子線程協助完成數據持久化工作的,因此如果數據集較大時,可能會導致整個服務停止服務幾百毫秒,甚至一分鐘。
AOF持久化(增量備份)
AOF持久化是以日志的形式記錄記錄每一個增刪操作然后追加到文件中。AOF的出現是為了彌補RDB備份的不足(數據不一致性)。
與RDB持久化相比,AOF的持久化實時性更好。
AOF的備份策略:Redis的配置文件中存在三種不同的AOF持久化方式:
- appendfsync always:每次有數據修改發生時都會同步。
- appendfsync everysec:每秒同步一次
- appendsync no:讓操作系統決定何時進行同步。
AOF優點:
- AOF實時性哈好,數據安全性更高;
- AOF通過append模式寫文件,即使中途服務器宕機,也可以通過redis-check-aof工具解決數據一致性問題。
- AOF機制的rewrite模式(文件過大會對命令進行合并重寫),可以刪除其中某些命令(比如誤操作的命令)
AOF缺點:
- AOF文件比RDB文件大,且恢復慢;
- 根據同步策略的不同,AOF在運行效率上往往會慢于RDB。
兩者結合
將 RDB 和 AOF 合體使用,這個方法是在 Redis 4.0 提出的,該方法叫混合使用 AOF 日志和內存快照,也叫混合持久化。
混合持久化工作在 AOF 日志重寫過程。
當開啟了混合持久化時,在 AOF 重寫日志時,fork 出來的重寫子進程會先將與主線程共享的內存數據以 RDB 方式寫入到 AOF 文件,然后主線程處理的操作命令會被記錄在重寫緩沖區里,重寫緩沖區里的增量命令會以 AOF 方式寫入到 AOF 文件,寫入完成后通知主進程將新的含有 RDB 格式和 AOF 格式的 AOF 文件替換舊的的 AOF 文件。
也就是說,使用了混合持久化,AOF 文件的前半部分是 RDB 格式的全量數據,后半部分是 AOF 格式的增量數據。
這樣的好處在于,重啟 Redis 加載數據的時候,由于前半部分是 RDB 內容,這樣加載的時候速度會很快。
加載完 RDB 的內容后,才會加載后半部分的 AOF 內容,這里的內容是 Redis 后臺子進程重寫 AOF 期間,主線程處理的操作命令,可以使得數據更少的丟失。
Memcache知道嗎
Memcache 是一種高性能的分布式內存對象緩存系統,主要用于加速動態 web 應用程序,通過減少數據庫負載來提高響應速度。它將數據存儲在內存中,從而能夠快速訪問和檢索數據。
Memcache 的主要特點和功能
- 緩存機制:
Memcache 通過將經常訪問的數據存儲在內存中,可以顯著減少對數據庫的查詢次數,從而提高應用程序的響應速度。
- 分布式架構:
Memcache 支持分布式部署,允許多個服務器共同維護一個緩存系統,從而提升緩存容量和訪問速度。
簡單的數據模型:
Memcache 使用鍵值對的形式存儲數據,每個緩存項都有一個唯一的鍵和對應的值。鍵是字符串,值可以是任意數據。
內存管理:
Memcache 自動管理內存,包括處理過期數據和根據內存限制逐出(evict)舊數據。
高并發性:
Memcache 設計為支持高并發訪問,適用于需要快速讀寫大量數據的場景。
支持多種編程語言:
Memcache 提供了多種客戶端庫,支持包括 PHP、Python、Java、Ruby、C# 等多種編程語言,方便開發者集成使用。
使用場景
- Web 緩存:
用于緩存數據庫查詢結果、API 響應、計算結果等,從而減少服務器負載和響應時間。
- 會話存儲:
Memcache 可以用來存儲會話數據,提高會話訪問速度,特別適用于分布式環境。
數據處理:
在需要頻繁讀取的數據處理場景下,使用 Memcache 可以顯著提高處理效率。
工作原理
- 存儲數據:
數據以鍵值對的形式存儲在 Memcache 中,鍵是唯一的標識符,值是存儲的數據。
- 數據訪問:
客戶端通過鍵來訪問對應的值,如果鍵存在,則直接返回存儲的值;如果鍵不存在,則需要從數據庫或其他存儲介質中獲取數據并緩存到 Memcache 中。
數據失效:
每個緩存項可以設置失效時間,超過失效時間后,緩存項將被刪除。此外,當 Memcache 達到內存限制時,舊的緩存項可能會被自動移除,以騰出空間存儲新的緩存項。
使用shell統計文件中top3的ip地址
要使用 Shell 腳本統計文件中出現次數最多的前三個 IP 地址,可以使用以下步驟和命令:
- 讀取文件內容:使用 cat 命令讀取文件內容。
- 提取 IP 地址:使用 awk 提取 IP 地址。
- 統計出現次數:使用 sort 和 uniq 統計每個 IP 地址出現的次數。
- 排序:按照出現次數排序。
- 取前 3 名:使用 head 取前 3 名。
磁盤滿了寫不進去,排查命令;如何查找大文件
當磁盤滿了,寫不進數據時,可以通過以下步驟和命令來排查問題:
1. 檢查磁盤使用情況
使用 df 命令查看文件系統的磁盤使用情況。
df -h
- -h 選項表示以人類可讀的格式顯示結果。
2. 查找大文件
使用 du 命令查找文件和目錄的磁盤使用情況,并找出占用大量空間的文件。
du -ah / | sort -rh | head -n 20
- -a 顯示所有文件和目錄的磁盤使用情況。
- -h 以人類可讀的格式顯示結果。
- sort -rh 根據文件大小進行排序,并按降序排列。
- head -n 20 顯示前 20 個占用空間最大的文件或目錄。
3. 檢查特定目錄的磁盤使用情況
有時系統目錄可能會占用大量空間,如 /var、/home 等。可以針對這些目錄進行檢查:
du -sh /var/*
- -s 顯示每個目錄的總大小。
- -h 以人類可讀的格式顯示結果。
4. 查找大文件
使用 find 命令查找特定大小以上的文件:
find / -type f -size +100M -exec ls -lh {} \; | awk '{ print $9 ": " $5 }'
- find / -type f -size +100M 查找大于 100MB 的文件。
- -exec ls -lh {} \; 列出這些文件的詳細信息。
- awk '{ print $9 ": " $5 }' 顯示文件名和大小。
說一下ES和Redis的區別
Elasticsearch (ES) 和 Redis 是兩種非常不同的技術,各自有不同的用途和特點:
1. 定位和用途
Elasticsearch (ES):
- 用途:Elasticsearch 是一個分布式搜索和分析引擎,主要用于處理和搜索大量的文本數據。
- 應用場景:全文搜索、日志和事件數據分析、實時數據監控、復雜查詢和分析。
- 數據存儲:以 JSON 文檔的形式存儲數據,支持復雜的查詢和過濾操作。
Redis:
- 用途:Redis 是一個高性能的鍵值存儲數據庫,常用于緩存、會話管理和實時數據處理。
- 應用場景:緩存、消息隊列、會話存儲、排行榜、實時統計、分布式鎖。
- 數據存儲:以鍵值對的形式存儲數據,支持多種數據結構,如字符串、哈希、列表、集合、有序集合等。
2. 數據模型
Elasticsearch (ES):
- 數據模型:文檔存儲。數據以 JSON 文檔形式存儲,每個文檔屬于一個索引,類似于關系數據庫中的表。
- 查詢語言:Elasticsearch 使用其特有的查詢 DSL(Domain Specific Language)來進行復雜查詢和分析。
Redis:
- 數據模型:鍵值存儲。數據以鍵值對形式存儲,支持多種數據結構。
- 查詢語言:Redis 使用簡單的命令行語法來進行數據操作,支持基本的 CRUD 操作和高級數據結構操作。
3. 持久化
Elasticsearch (ES):
- 持久化:默認情況下,數據持久化到磁盤,并支持分布式存儲和索引。Elasticsearch 的數據持久化機制確保了高可用性和數據的可靠性。
Redis:
- 持久化:支持多種持久化機制,如 RDB(快照)和 AOF(追加文件)。可以配置為無持久化模式,主要用于緩存和臨時數據存儲。
4. 性能
Elasticsearch (ES):
- 性能:在處理和搜索大量文本數據時性能非常優越,特別適合需要復雜查詢和全文搜索的場景。
- 延遲:相對于 Redis 來說,Elasticsearch 的查詢可能有較高的延遲,特別是在處理復雜查詢和分析時。
Redis:
- 性能:作為內存數據庫,Redis 提供非常高的讀寫性能和低延遲,非常適合需要快速響應的場景。
- 延遲:通常在亞毫秒級別,非常適合高頻率的讀寫操作。
5. 擴展性
Elasticsearch (ES):
- 擴展性:Elasticsearch 通過分片(sharding)和副本(replication)機制實現橫向擴展,能夠處理大規模的數據存儲和搜索需求。
- 集群:支持分布式集群,能夠動態添加和移除節點。
Redis:
- 擴展性:Redis 可以通過 Redis Cluster 實現水平擴展,支持分片,但在擴展和管理上相對于 Elasticsearch 更復雜。
- 集群:支持主從復制和哨兵模式來提高可用性,但原生集群模式管理相對復雜。
6. 使用場景
Elasticsearch (ES):
- 場景:日志分析(如 ELK 堆棧中的 "E")、全文搜索、實時數據分析、業務監控。
- 優勢:擅長處理海量文本數據和復雜查詢需求。
Redis:
- 場景:緩存、會話管理、消息隊列、實時計數、排行榜、臨時數據存儲。
- 優勢:高性能、低延遲的鍵值存儲和多種數據結構支持。
總結
- Elasticsearch:適用于需要處理和分析大量文本數據的場景,提供強大的全文搜索和分析能力。
- Redis:適用于需要高性能和低延遲的數據訪問場景,提供豐富的數據結構和簡單的操作命令。
編程題
兩個goroutine交替打印1-10
//G1 1
//G2 2
//G1 3
//G2 4
//…
//G1 9
//G2 10
先別看示例代碼,自己寫一下試試
~
~
~
~
~
~
示例代碼:
package main
import (
"fmt"
"sync"
)
func goroutine1(num chan int, wg *sync.WaitGroup) {
defer wg.Done()
for i := 1; i <= 10; i += 2 {
fmt.Println("G1", i)
num <- i
<-num
}
}
func goroutine2(num chan int, wg *sync.WaitGroup) {
defer wg.Done()
for i := 2; i <= 10; i += 2 {
<-num
fmt.Println("G2", i)
num <- i
}
}
func main() {
num := make(chan int)
var wg sync.WaitGroup
wg.Add(2)
go goroutine1(num, &wg)
go goroutine2(num, &wg)
wg.Wait()
}