Hive-優化(語法優化篇)

列裁剪與分區裁剪

在生產環境中,會面臨列很多或者數據量很大時,如果使用select * 或者不指定分區進行全列或者全表掃描時效率很低。Hive在讀取數據時,可以只讀取查詢中所需要的列,忽視其他的列,這樣做可以節省讀取開銷(中間表存儲開銷和數據整合開銷)

1.列裁剪:在查詢時只讀取需要的列。避免select *

2.分區裁剪:在查詢中只讀取需要的分區。

遵循一個原則:盡量少的讀入數據,盡早地數據收斂!

分組聚合優化

Map端聚合

Hive中未經優化的分組聚合,是通過一個MapReduce Job實現的。Map端負責讀取數據,并按照分組字段分區,通過Shuffle,將數據發往Reduce端,各組數據在Reduce端完成最終的聚合運算。

Hive對分組聚合的優化主要圍繞著減少Shuffle數據量進行,具體做法是map-side聚合。所謂map-side聚合,在Hive的Map階段開啟預聚合,先在Map階段預聚合,然后在Reduce階段進行全局的聚合。map-side聚合能有效減少shuffle的數據量,提高分組聚合運算的效率。

通俗理解:假設有張8000w數據表,聚合后30組數據,有10個map,若是沒有開啟分組聚合,則會map將8000w條數據傳給reduce,開啟分組聚合后,就會每個map先進行分組,10個map各有30組,再將這30*10組數據從map傳給reduce,這樣效率就會大大增加

map-side 聚合相關的參數如下:

--啟用map-side聚合,一般默認開啟

set hive.map.aggr=true;

?默認為開啟狀態

--用于檢測源表數據是否適合進行map-side聚合。檢測的方法是:先對若干條數據進行map-side聚合,若聚合后的條數和聚合前的條數比值小于該值,則認為該表適合進行map-side聚合;否則,認為該表數據不適合進行map-side聚合,后續數據便不再進行map-side聚合。

set hive.map.aggr.hash.min.reduction=0.5;

--用于檢測源表是否適合map-side聚合的條數。

set hive.groupby.mapaggr.checkinterval=100000;

默認為0.5和10w條

會先從大的數據表內,先抽取10w數據進行檢測,判斷看(分組后的數據)/10w是否在0.5以下,若是則會啟用map的分組聚合

--map-side聚合所用的hash table,占用map task堆內存的最大比例,若超出該值,則會對hash table進行一次flush。

set hive.map.aggr.hash.force.flush.memory.threshold=0.9;

優化案例

示例SQL

hive (default)> set hive.map.aggr=true/false;

explain

select t1.province_id,count(*) as cnt from ds_hive.ch12_order_detail_orc t1

group by t1.province_id

;

開啟分組聚合后,執行時間26s左右? application_1716866155638_175450??

關閉分組聚合后,執行時間在60s左右,效率提升了34s??application_1716866155638_175451

由上圖的詳細執行過程分析可知,開啟map聚合后,map輸出--reduce接受的數據是340,而關閉map分組聚合后,map數據--reduce接受的數據是8000w條,傳輸時間大大影響

大致的運行前后的步驟對比:

Count Distinct 的優化

在Hive中,DISTINCT關鍵字用于對查詢結果進行去重,以返回唯一的值。其主要作用是消除查詢結果中的重復記錄,使得返回的結果集中每個值只出現一次。

具體而言,當你在Hive中使用SELECT DISTINCT時,系統會對指定的列或表達式進行去重操作。盡管Hive中的DISTINCT關鍵字對于去重查詢是非常有用的,但在某些情況下可能存在一些缺點:性能開銷、數據傾斜、內存需求等。

group by 操作的具體實現原理

1.map階段,將group by后的字段組合作為一個key,如果group by單個字段,那么key就一個。將group by之后要進行的聚合操作字段作為值,如果要進行count,則value是賦1;如要sum另一個字段,那么value就是該字段。

2.shuffle階段,按照key的不同分發到不同的reducer。注意此時可能因為key分布不均勻而出現數據傾斜的問題。這個問題是我們處理數據傾斜比較常規的查找原因的方法之一,也是我們解決數據傾斜的處理階段。(當執行過程中,出現其他任務都已完成,持續等待一個reudce過程的時候,就看出現了數據傾斜問題)

3.reduce階段,如果是count將相同key的值累加,如果是其他操作,按需要的聚合操作,得到結果。

distinct 的具體實現,當執行Distinct操作時,Hive會將操作轉化為一個MapReduce作業,并按照指定的列進行分組。在Map階段,每個Mapper會讀取輸入數據,并將指定的列作為輸出的key,然后,通過Shuffle過程將具有相同key的數據發送到同一個Reducer中。

當distinct一個字段時,這里會將group by的字段和distinct的字段組合在一起作為map輸出的key,value設置為1,同時將group by的字段定為分區鍵,這一步非常重要,這樣就可以將GroupBy字段作為reduce的key,在reduce階段,利用mapreduce的排序,輸入天然就是按照組合key排好序的。根據分區鍵將記錄分發到reduce端后,按順序取出組合鍵中的distinct字段,這時distinct字段也是排好序的。依次遍歷distinct字段,每找到一個不同值,計數器就自增1,即可得到count distinct結果。

count(distinct)全局合操作的時候,即使我們設定了reduce task的具體個數,例如set mapred.reduce.tasks=100;hive最終也只會啟動一個reducer。這就造成了所有map端傳來的數據都在一個tasks中執行,這唯一的Reduce Task需要Shuffle大量的數據,并且進行排序聚合等處理,這使得這個操作成為整個作業的IO和運算瓶頸。

?針對上述說的問題,我們可以修改對應的sql來進行優化, count+group by 或者sum+group by的方案來優化,在第一階段選出全部的非重復的字段id,在第二階段再對這些已消重的id進行計數

重到細粒度的(日),再聚合到粗粒度(省份)

(目前測試結果不能完全驗證如上理論,暫放,確定后再更新)

-- count(distinct)

select count(distinct province_id) from ds_hive.ch12_order_detail_orc ;

-- 優化版 count + group by?

select count(product_id)
from (select product_id
from ds_hive.ch12_order_detail_orc
group by product_id
)t;

第一階段我們可以通過增大Reduce的并發數,并發處理Map輸出。在第二階段,由于id已經消重,因此COUNT(*)操作在Map階段不需要輸出原id數據,只輸出一個合并后的計數即可。這樣即使第二階段Hive強制指定一個Reduce Task的時候,極少量的Map輸出數據也不會使單一的Reduce Task成為瓶頸。

其實在實際運行時,Hive還對這兩階段的作業做了額外的優化。它將第二個MapReduce作業Map中的Count過程移到了第一個作業的Reduce階段。這樣在第一階Reduce就可以輸出計數值,而不是消重的全部id。這一優化大幅地減少了第一個作業的Reduce輸出IO以及第二個作業Map的輸入數據量。最終在同樣的運行環境下優化后的語句可以說是大大提升了執行效率。

Join優化

Hive擁有多種join算法,包括Common Join,Map Join,Bucket Map Join,Sort Merge Buckt Map Join等,下面對每種join算法做簡要說明:

Common Join? (完整進行map-reduce階段)

Common Join是Hive中最穩定的join算法,其通過一個MapReduce Job完成一個join操作。Map端負責讀取join操作所需表的數據,并按照關聯字段進行分區,通過Shuffle,將其發送到Reduce端,相同key的數據在Reduce端完成最終的Join操作。

如果不指定MapJoin或者不符合MapJoin的條件,那么Hive解析器會將Join操作轉換成Common Join,即:在Reduce階段完成join。

整個過程包含Map、Shuffle、Reduce階段

(1)Map階段

Step1: 讀取源表的數據,Map輸出時候以Join on條件中的列為key,如果Join有多個關聯鍵,則以這些關聯鍵的組合作為key;

Step2: Map輸出的value為join之后所關心的(select或者where中需要用到的)列;同時在value中還會包含表的Tag信息,用于標明此value對應哪個表;

Step3: 按照key進行排序。

(2)Shuffle階段

根據key的值進行hash,并將key/value按照hash值推送至不同的reduce中,這樣確保兩個表中相同的key位于同一個reduce中。

(3)Reduce階段

根據key的值完成join操作,期間通過Tag來識別不同表中的數據。

舉個例子:

SELECT t1.stu_id

???????????,t1.score

???????????,t2.sex

??????from ds_hive.ch7_score_info t1

??join ds_hive.ch7_stu_info? t2

????????on t1.stu_id=t2.stu_id

;

執行計劃如下,完整的common join 會完整的經過map-reduce階段

?執行過程如下:

JOIN操作涉及合并兩個或多個表的數據,以便通過共同的列值將它們關聯起來。這樣的關聯操作在處理大規模數據時可能會面臨一些性能挑戰,因此有必要進行優化。

性能開銷: JOIN操作通常涉及將分布在不同節點上的數據進行合并。在傳統的MapReduce執行環境中,這意味著需要進行數據的分發、排序和聚合操作,這些操作都會帶來較大的性能開銷

Shuffle開銷: 在傳統的MapReduce中,JOIN操作的Shuffle階段涉及將相同鍵的數據合并到一起。這個過程需要大量的網絡通信和數據傳輸,尤其是當數據分布不均勻時。

內存消耗: 處理大規模數據的JOIN操作可能需要大量的內存,特別是在進行排序和合并時。這可能導致內存不足的問題,進而影響性能。

復雜度: JOIN操作可能涉及復雜的計算,特別是在關聯多個表或在多列上進行關聯時。這增加了查詢的復雜性,可能導致較長的執行時間。

Map Join (大表join小表)

Map Join算法可以通過兩個只有map階段的Job完成一個join操作。其適用場景為大表join小表。因為只經map+map階段,減少了shuffle的處理,reduce的讀取和處理過程,從而進行性能優化。若某join操作滿足要求,則:

第一個Job會讀取小表數據,將其制作為hash table,并上傳至Hadoop分布式緩存(本質上是上傳至每個執行任務的NodeManager節點本地磁盤)。

第二個Job會先從分布式緩存中讀取小表數據,并緩存在Map Task的內存中,然后掃描大表數據,這樣在map端即可完成關聯操作。

Map Join有兩種觸發方式,一種是用戶在SQL語句中增加hint提示,另外一種是Hive優化器根據參與join表的數據量大小,自動觸發。

1)Hint提示

用戶可通過如下方式,指定通過map join算法,并且將作為map join中的小表。這種方式已經過時,不推薦使用

hive (default)>

select?/*+ mapjoin(ta) */

????ta.id,

????tb.id

from table_a ta

join table_b tb

on ta.id=tb.id

;

2)自動觸發

Hive在編譯SQL語句階段,起初所有的join操作均采用Common Join算法實現。

之后在物理優化階段,Hive會根據每個Common Join任務所需表的大小判斷該Common Join任務是否能夠轉換為Map Join任務,若滿足要求,便將Common Join任務自動轉換為Map Join任務。

但有些Common Join任務所需的表大小,在SQL的編譯階段是未知的(例如對子查詢進行join操作),所以這種Common Join任務是否能轉換成Map Join任務在編譯階是無法確定的。

針對這種情況,Hive會在編譯階段生成一個條件任務(Conditional Task),其下會包含一個計劃列表,計劃列表中包含轉換后的Map Join任務以及原有的Common Join任務。最終具體采用哪個計劃,是在運行時決定的。大致思路如下圖所示:

Map join自動轉換的具體判斷邏輯如下圖所示

參數如下:

--啟動Map Join自動轉換

set hive.auto.convert.join=true;

--一個Common Join operator轉為Map Join operator的判斷條件,若該Common Join相關的表中,存在n-1張表的大小總和<=該值,則生成一個Map Join計劃,此時可能存在多種n-1張表的組合均滿足該條件,則hive會為每種滿足條件的組合均生成一個Map Join計劃,同時還會保留原有的Common Join計劃作為后備(back up)計劃,實際運行時,優先執行Map Join計劃,若不能執行成功,則啟動Common Join后備計劃。

set hive.mapjoin.smalltable.filesize=25000000;

--開啟無條件轉Map Join

set hive.auto.convert.join.noconditionaltask=false;

--無條件轉Map Join時的小表之和閾值,若一個Common Join operator相關的表中,存在n-1張表的大小總和<=該值,此時hive便不會再為每種n-1張表的組合均生成Map Join計劃,同時也不會保留Common Join作為后備計劃。而是只生成一個最優的Map Join計劃。

set hive.auto.convert.join.noconditionaltask.size=?20971520;

3)示例SQL

set hive.auto.convert.join=false(true);

explain
SELECT t1.province_id
,count(*) as cnt
from ds_hive.ch12_order_detail_orc t1
join ds_hive.ch12_product_info_orc t3 on t1.province_id=t3.id
group by t1.province_id
;

參數設置為false(未優化):既有map,又有reduce,然后join是在reduce階段

執行完時間 161s

參數設置為true(優化):第一個map加載本地文件,第二個map進行join

執行時間35s

結論:未開啟mapjoin,進行commonjoin,執行時間161s,使用mapjoin,執行時間35s,執行效率大大提升

接著我們再來測試另外一個參數。調整hive.auto.convert.join.noconditionaltask.size參數(小于此設置的表會識別為小表),使其小于t3 表 的大小

set hive.auto.convert.join=true;

--重要,一般企業來調整此參數來決定小表的大小,比如讓一些略大于小表閾值的表進行mapjoin

set hive.auto.convert.join.noconditionaltask.size=252300;

explain
SELECT t1.user_id
,t1.create_time
,t3.id
from ds_hive.ch12_order_detail_orc t1
join ds_hive.ch12_product_info_orc t3 on t1.province_id=t3.id
;

--------此類優化用的少

set hive.auto.convert.join.noconditionaltask=false;

set hive.mapjoin.smalltable.filesize=?15230000;

第一個sql,因為設置了.noconditionaltask.size=252300,小于表的大小,最終選擇了commonjoin執行,第二遍我們關閉有條件執行,由于smalltable.filesize大于小表只有commonjoin,這時候調大set hive.mapjoin.smalltable.filesize=379000002;讓其小表大于smalltable.filesize,這時候最終會選擇mapjoin。

Bucket Map Join(大表join大表)

兩張表都相對較大,若采用普通的Map Join算法,則Map端需要較多的內存來緩存數據,當然可以選擇為Map段分配更多的內存,來保證任務運行成功。但是,Map端的內存不可能無上限的分配,所以當參與Join的表數據量均過大時,就可以考慮采用Bucket Map Join算法。Bucket Map Join是對Map Join算法的改進,其打破了Map Join只適用于大表join小表的限制,可用于大表join大表的場景。

Bucket Map Join的核心思想是:若能保證參與join的表均為分桶表,且關聯字段為分桶字段,且其中一張表的分桶數量是另外一張表分桶數量的整數倍,就能保證參與join的兩張表的分桶之間具有明確的關聯關系,所以就可以在兩表的分桶間進行Map Join操作了。這樣一來,第二個Job的Map端就無需再緩存小表的全表數據了,而只需緩存其所需的分桶即可。其原理如圖所示:

優化條件:

1) set hive.optimize.bucketmapjoin = true;

2) 一個表的bucket數是另一個表bucket數的整數倍

3) bucket列 == join列

4) 必須是應用在map join的場景中

Bucket Map Join不支持自動轉換,發須通過用戶在SQL語句中提供如下Hint提示,并配置如下相關參數,方可使用。

1)Hint提示

hive (default)>

select?/*+ mapjoin(ta) */

????ta.id,

????tb.id

from table_a ta

join table_b tb on ta.id=tb.id;

2)相關參數

--關閉cbo優化,cbo會導致hint信息被忽略

set hive.cbo.enable=false;

--map join hint默認會被忽略(因為已經過時),需將如下參數設置為false

set hive.ignore.mapjoin.hint=false;

--啟用bucket map join優化功能

set hive.optimize.bucketmapjoin =?true;

Sort Merge Bucket Map Join(大表join大表)

Sort Merge Bucket Map Join(簡稱SMB Map Join)基于Bucket Map Join。SMB Map Join要求,參與join的表均為分桶表,且需保證分桶內的數據是有序的,且分桶字段、排序字段和關聯字段為相同字段,且其中一張表的分桶數量是另外一張表分桶數量的整數倍。

SMB Map Join同Bucket Join一樣,同樣是利用兩表各分桶之間的關聯關系,在分桶之間進行join操作,不同的是,分桶之間的join操作的實現原理。Bucket Map Join,兩個分桶之間的join實現原理為Hash Join算法;而SMB Map Join,兩個分桶之間的join實現原理為Sort Merge Join算法。

Hash Join和Sort Merge Join均為關系型數據庫中常見的Join實現算法。Hash Join的原理相對簡單,就是對參與join的一張表構建hash table,然后掃描另外一張表,然后進行逐行匹配。Sort Merge Join需要在兩張按照關聯字段排好序的表中進行,其原理如圖所示:

Hive中的SMB Map Join就是對兩個分桶的數據按照上述思路進行Join操作。可以看出,SMB Map Join與Bucket Map Join相比,在進行Join操作時,Map端是無需對整個Bucket構建hash table,也無需在Map端緩存整個Bucket數據的,每個Mapper只需按順序逐個key讀取兩個分桶的數據進行join即可。

Sort Merge Bucket Map Join有兩種觸發方式,包括Hint提示和自動轉換。Hint提示已過時,不推薦使用。下面是自動轉換的相關參數:

--啟動Sort Merge Bucket Map Join優化

set hive.optimize.bucketmapjoin.sortedmerge=true;

--使用自動轉換SMB Join

set hive.auto.convert.sortmerge.join=true;

兩張表都相對較大,除了可以考慮采用Bucket Map Join算法,還可以考慮SMB Join。相較于Bucket Map Join,SMB Map Join對分桶大小是沒有要求的。

謂詞下推

謂詞下推(predicate pushdown)是指,盡量將過濾操作前移,以減少后續計算步驟的數據量。數倉實際開發中經常會涉及到多表關聯,這個時候就會涉及到on與where的使用。一般在面試的時候會提問:條件寫在where里和寫在on有什么區別?

相關參數為:

--是否啟動謂詞下推(predicate pushdown)優化

set hive.optimize.ppd =?true;

示例SQL語句

hive (default)>

explain

SELECT t1.id

,t2.province_name

from ds_hive.ch12_order_detail_orc t1

left join ds_hive.ch12_province_info_orc t2 on t1.province_id=t2.id

where t1.product_num=20?and t2.province_name='江蘇'

;

關閉謂詞下推優化

--是否啟動謂詞下推(predicate pushdown)優化

set hive.optimize.ppd =?false;

--為了測試效果更加直觀,關閉cbo優化

set hive.cbo.enable=false;

--為了測試效果更加直觀,關閉mapjoin

set hive.auto.convert.join=false;

通過執行計劃可以看到,當我們把謂詞下推關閉以后,數據是所有數據關聯以后才進行過濾的,這樣如果量表數據量大,就大大降低了我們的執行效率

開啟謂詞下推優化

--是否啟動謂詞下推(predicate pushdown)優化

set hive.optimize.ppd =?true;

--為了測試效果更加直觀,關閉cbo優化

set hive.cbo.enable=false;

通過執行計劃可以看出,過濾操作位于執行計劃中的join操作之前。大大減少了關聯的數據量。對整體執行效率有很大提升。

開啟謂詞執行做關聯,優化一下SQL

--是否啟動謂詞下推(predicate pushdown)優化

set hive.optimize.ppd =?true;

--為了測試效果更加直觀,關閉cbo優化

set hive.cbo.enable=false;

-- 將where條件里關于t2的過濾放到on條件后

explain
? ? SELECT t1.id
? ? ? ? ? ?,t2.province_name
? ? ? from ds_hive.ch12_order_detail_orc t1
left join ds_hive.ch12_province_info_orc ?t2
? ? ? ? on t1.province_id=t2.id?and t2.province_name='江蘇'
? where t1.product_num=20
;

通過執行計劃可以看出,t1和t2過濾操作都位于執行計劃中的join操作之前,對倆個表都是先過濾再關聯,效率更一步提升。

當我們使用左關聯的時候:1.所有條件寫在where中,只有左邊的條件先過濾;2.當所有條件寫在 on 里面只有右邊的條件起作用,3.為了可以讓條件都起作用,就把左表條件寫在where里,右邊條件寫在 on 里,兩者都先過濾

結論:

  1. 對于Join(Inner Join)、Full outer Join,條件寫在on后面,還是where后面,性能上面沒有區別,join謂詞下推都生效,Full outer Join都不生效;
  2. 對于Left outer Join ,右側的表寫在on后面、左側的表寫在where后面,性能上有提高;
  3. 對于Right outer Join,左側的表寫在on后面、右側的表寫在where后面,性能上有提高;

合理選擇排序

order by
全局排序,只走一個reducer,當表數據量較大時容易計算不出來,性能不佳慎用,在嚴格模式下需要加limit

sort by
局部排序,即保證單個reduce內結果有序,但沒有全局排序的能力。

distribute by
按照指定的字段把數據劃分輸出到不同的reducer中,是控制數據如何從map端輸出到reduce端,hive會根據distribute by后面的字段和對應reducer的個數進行hash分發

cluster by
擁有distrubute by的能力,同時也擁有sort by的能力,所以可以理解cluster by是 distrubute by+sort by

實例代碼優化

-- 優化前
select
id         
,count(*) as cnt
from ds_hive.ch12_order_detail_orc t1
group by id
order by cnt
limit 100
;

執行時間109.9s

-- 優化后
select
id
,cnt
from
(select id       ,count(*) as cntfrom ds_hive.ch12_order_detail_orc t1group by id
) t1
distribute by cnt
sort by id
limit 100
;

執行時間69s

通過優化前后時間對比,可以看到優化效果

注意實際企業運維可以通過參數 set hive.mapred.mode=strict 來設置嚴格模式,這個時候使用 orderby 全局排序必須加 limit;建議如果不是非要全局有序的話,局部有序的話建議使用 sortby,它會視情況啟動多個 reducer 進行排序,并且保證每個 reducer 內局部有序。為了控制map 端數據分配到 reducer 的 key,往往還要配合 distribute by 一同使用。如果不加 distribute by 的話,map 端數據就會隨機分配到 reducer。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/897351.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/897351.shtml
英文地址,請注明出處:http://en.pswp.cn/news/897351.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

rkipc控制ircut的分析

rk_isp_set_night_to_day函數 rkipc控制ircut主要通過rk_isp_set_night_to_day函數&#xff0c;例如在ser_rk_isp_set_night_to_day函數中 int ser_rk_isp_set_night_to_day(int fd) {int ret 0;int id, len;char *value NULL;if (sock_read(fd, &id, sizeof(id)) SOC…

Android Retrofit + RxJava + OkHttp 網絡請求高效封裝方案

Retrofit RxJava OkHttp 是 Android 開發中常用的網絡請求庫組合。Retrofit 是一個類型安全的 HTTP 客戶端&#xff0c;RxJava 是一個響應式編程庫&#xff0c;OkHttp 是一個高效的 HTTP 客戶端。 Retrofit RxJava OkHttp 的組合可以提供以下功能&#xff1a; 職責清晰 R…

【nRF52832】【Nodic】開發入門【三】模塊化

title: nRF52832開發入門【二】模塊化 tags: nodic categories: nodic abbrlink: 37752 date: 2025-03-09 17:22:17 1. 介紹 我們實際開發過程中往往會很復雜&#xff0c;為了更好的管理代碼&#xff0c;我們需要模塊化。模塊化的好處有很多&#xff0c;比如&#xff1a; 降…

爬蟲案例八js逆向爬取網易音樂

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言一、js逆向的前期準備二、網站分析三、代碼 前言 提示&#xff1a;這里可以添加本文要記錄的大概內容&#xff1a; 爬取網易音樂 提示&#xff1a;以下是本篇…

vue2實現組件庫的自動按需引入,unplugin-auto-import,unplugin-vue-components

1.使用ant-design-vue或者element-ui時&#xff0c;如何每個組件都去import導入組件&#xff0c;大大降低了開發效率&#xff0c;如果全局一次性注冊會增加項目體積&#xff0c;那么如何實現既不局部引入&#xff0c;也不全局注冊&#xff1f; 2.在element-plus官網看到有說明…

【Andrej Karpathy 神經網絡從Zero到Hero】--2.語言模型的兩種實現方式 (Bigram 和 神經網絡)

目錄 統計 Bigram 語言模型質量評價方法 神經網絡語言模型 【系列筆記】 【Andrej Karpathy 神經網絡從Zero到Hero】–1. 自動微分autograd實踐要點 本文主要參考 大神Andrej Karpathy 大模型講座 | 構建makemore 系列之一&#xff1a;講解語言建模的明確入門&#xff0c;演示…

(二 十 二)趣學設計模式 之 備忘錄模式!

目錄 一、 啥是備忘錄模式&#xff1f;二、 為什么要用備忘錄模式&#xff1f;三、 備忘錄模式的實現方式四、 備忘錄模式的優缺點五、 備忘錄模式的應用場景六、 總結 &#x1f31f;我的其他文章也講解的比較有趣&#x1f601;&#xff0c;如果喜歡博主的講解方式&#xff0c;…

安裝SPSS后啟動顯示應用程序無法啟動,因為應用程序的并行配置不正確的解決方案

軟件安裝報錯問題有需要遠程文章末尾獲取聯系方式&#xff0c;可以幫你遠程處理各類安裝報錯。 一、安裝SPSS后啟動顯示應用程序無法啟動&#xff0c;因為應用程序的并行配置不正確報錯 在成功安裝 SPSS 軟件后&#xff0c;嘗試啟動應用程序時&#xff0c;系統彈出錯誤提示窗…

IP,MAC,ARP 筆記

1.什么是IP地址 IP 地址是一串由句點分隔的數字。IP 地址表示為一組四個數字&#xff0c;比如 192.158.1.38 就是一個例子。該組合中的每個數字都可以在 0 到 255 的范圍內。因此&#xff0c;完整的 IP 尋址范圍從 0.0.0.0 到 255.255.255.255。 IP 地址不是隨機的。它們由互…

C++11中的Condition_variable

C11中的condition_variable 在C11中&#xff0c;條件變量&#xff08;std::condition_variable&#xff09;是線程同步機制之一&#xff0c;用于在多線程環境中實現線程間的通信和協調。它允許一個或多個線程在某個條件尚未滿足時等待&#xff0c;直到其他線程通知條件已經滿足…

IO多路復用實現并發服務器

一.select函數 select 的調用注意事項 在使用 select 函數時&#xff0c;需要注意以下幾個關鍵點&#xff1a; 1. 參數的修改與拷貝 readfds 等參數是結果參數 &#xff1a; select 函數會直接修改傳入的 fd_set&#xff08;如 readfds、writefds 和 exceptfds&#xf…

_二級繼電器程控放大倍數自動設置

簡介 在開發項目中&#xff0c;有時會遇到需要使用程控放大的情況&#xff0c;如果沒有opa那種可編程放大器&#xff0c;那么就需要通過繼電器來控制放大倍數。而在繼電器程控中&#xff0c;常用的是二級程控&#xff0c;三級程控相較于二級就復雜了許多。 在二級程控中&#x…

電腦總顯示串口正在被占用處理方法

1.現象 在嵌入式開發過程中&#xff0c;有很多情況下要使用串口調試&#xff0c;其中485/422/232轉usb串口是非常常見的做法。 根據協議&#xff0c;接口芯片不同&#xff0c;需要安裝對應的驅動程序&#xff0c;比如ch340&#xff0c;cp2102&#xff0c;CDM212364等驅動。可…

優雅拼接字符串:StringJoiner 的完整指南

在Java開發中&#xff0c;字符串拼接是高頻操作。無論是日志格式化、構建CSV數據&#xff0c;還是生成動態SQL&#xff0c;開發者常需處理分隔符、前綴和后綴的組合。傳統的StringBuilder雖然靈活&#xff0c;但代碼冗余且易出錯。Java 8推出的StringJoiner類&#xff0c;以簡潔…

LabVIEW閉環控制系統硬件選型與實時性能

在LabVIEW閉環控制系統的開發中&#xff0c;硬件選型直接影響系統的實時性、精度與穩定性。需綜合考慮數據采集速度&#xff08;采樣率、接口帶寬&#xff09;、計算延遲&#xff08;算法復雜度、處理器性能&#xff09;、輸出響應時間&#xff08;執行器延遲、控制周期&#x…

Hive的架構

1. 概念 Hive 是建立在 Hadoop 上的數據倉庫工具&#xff0c;旨在簡化大規模數據集的查詢與管理。它通過類 SQL 語言&#xff08;HiveQL&#xff09;將結構化數據映射為 Hadoop 的 MapReduce&#xff0c;適合離線批處理&#xff0c;尤其適用于數據倉庫場景。 2. 數據模型 表&a…

深入解析:Linux中KVM虛擬化技術

這篇文章將深入分析Linux中虛擬化技術的實現----KVM技術&#xff0c;從KVM技術的簡介、技術架構、以及虛擬機和宿主機交互的重要處理邏輯出發&#xff0c;深入探究KVM技術的實現。 一、KVM簡介&#xff1a; 首先&#xff0c;我們先查看一下KVM架構&#xff0c;看看它的整體工…

golang學習筆記——go語言安裝及系統環境變量設置

文章目錄 go語言安裝go envgo getgoproxy測試安裝 Go 插件安裝 Go 插件依賴工具參考資料用戶環境變量和系統環境變量用戶環境變量系統環境變量示例設置環境變量的步驟設置用戶環境變量設置系統環境變量 驗證環境變量總結 2024年最火的5大Go框架1. Gin&#xff1a;高并發接口的“…

3.6c語言

#define _CRT_SECURE_NO_WARNINGS #include <math.h> #include <stdio.h> int main() {int sum 0,i,j;for (j 1; j < 1000; j){sum 0;for (i 1; i < j; i){if (j % i 0){sum i;} }if (sum j){printf("%d是完數\n", j);}}return 0; }#de…

【TI】如何更改 CCS20.1.0 的 WORKSPACE 默認路徑

參考鏈接&#xff1a; 如何更改 CCS Theia 中工作區的默認位置&#xff1f;- Code Composer Studio 論壇 - Code Composer Studio?? - TI E2E 支持論壇 --- How to change the default location for the workspace in CCS Theia? - Code Composer Studio forum - Code Comp…