01.29 金融科技求職面試題


金融科技求職面試題


1、 線程和進程

什麼叫"多任務"呢?簡單地說,就是操作系統可以同時運行多個任務。打個比方,你一邊在用瀏覽器上網,一邊在聽MP3,一邊在用Word趕作業,這就是多任務,至少同時有3個任務正在運行。還有很多任務悄悄地在後臺同時運行著,只是桌面上沒有顯示而已。

現在,多核CPU已經非常普及了,但是,即使過去的單核CPU,也可以執行多任務。由於CPU執行代碼都是順序執行的,那麼,單核CPU是怎麼執行多任務的呢?

答案就是操作系統輪流讓各個任務交替執行,任務1執行0.01秒,切換到任務2,任務2執行0.01秒,再切換到任務3,執行0.01秒……這樣反覆執行下去。表面上看,每個任務都是交替執行的,但是,由於CPU的執行速度實在是太快了,我們感覺就像所有任務都在同時執行一樣。

真正的並行執行多任務只能在多核CPU上實現,但是,由於任務數量遠遠多於CPU的核心數量,所以,操作系統也會自動把很多任務輪流調度到每個核心上執行。

對於操作系統來說,一個任務就是一個進程(Process),比如打開一個瀏覽器就是啟動一個瀏覽器進程,打開一個記事本就啟動了一個記事本進程,打開兩個記事本就啟動了兩個記事本進程,打開一個Word就啟動了一個Word進程。

有些進程還不止同時幹一件事,比如Word,它可以同時進行打字、拼寫檢查、打印等事情。在一個進程內部,要同時幹多件事,就需要同時運行多個"子任務",我們把進程內的這些"子任務"稱為線程(Thread)。

由於每個進程至少要幹一件事,所以,一個進程至少有一個線程。當然,像Word這種複雜的進程可以有多個線程,多個線程可以同時執行,多線程的執行方式和多進程是一樣的,也是由操作系統在多個線程之間快速切換,讓每個線程都短暫地交替運行,看起來就像同時執行一樣。當然,真正地同時執行多線程需要多核CPU才可能實現。

我們前面編寫的所有的Python程序,都是執行單任務的進程,也就是隻有一個線程。如果我們要同時執行多個任務怎麼辦?

有兩種解決方案:

一種是啟動多個進程,每個進程雖然只有一個線程,但多個進程可以一塊執行多個任務。

還有一種方法是啟動一個進程,在一個進程內啟動多個線程,這樣,多個線程也可以一塊執行多個任務。

當然還有第三種方法,就是啟動多個進程,每個進程再啟動多個線程,這樣同時執行的任務就更多了,當然這種模型更復雜,實際很少採用。

總結一下就是,多任務的實現有3種方式:

· 多進程模式;

· 多線程模式;

· 多進程+多線程模式。

同時執行多個任務通常各個任務之間並不是沒有關聯的,而是需要相互通信和協調,有時,任務1必須暫停等待任務2完成後才能繼續執行,有時,任務3和任務4又不能同時執行,所以,多進程和多線程的程序的複雜度要遠遠高於我們前面寫的單進程單線程的程序。因為複雜度高,調試困難,所以,不是迫不得已,我們也不想編寫多任務。但是,有很多時候,沒有多任務還真不行。想想在電腦上看電影,就必須由一個線程播放視頻,另一個線程播放音頻,否則,單線程實現的話就只能先把視頻播放完再播放音頻,或者先把音頻播放完再播放視頻,這顯然是不行的。

Python既支持多進程,又支持多線程。


2、 有指針和無指針

指針是C語言的核心概念,使用指針可以帶來如下的好處:

(1)可以提高程序的編譯效率和執行速度,使程序更加簡潔。

(2)通過指針被調用函數可以向調用函數處返回除正常的返回值之外的其他數據,從而實現兩者間的雙向通信。

(3)利用指針可以實現動態內存分配。

(4)指針還用於表示和實現各種複雜的數據結構,從而為編寫出更加高質量的程序奠定基礎。

(5)利用指針可以直接操縱內存地址,從而可以完成和彙編語言類似的工作。

(6)跟容易實現函數的編寫和調用。

當然,指針也是一把雙刃劍,如果對指針不能正確理解和靈活有效的應用,利用指針編寫的程序也更容易隱含各式各樣的錯誤,同時程序的可讀性也會大打折扣。


3、淺拷貝與深拷貝

淺拷貝可以使用列表自帶的copy()函數(如list.copy()),或者使用copy模塊的copy()函數。深拷貝只能使用copy模塊的deepcopy(),所以使用前要導入:from copy import deepcopy

如果拷貝的對象裡的元素只有值,沒有引用,那淺拷貝和深拷貝沒有差別,都會將原有對象複製一份,產生一個新對象,對新對象裡的值進行修改不會影響原有對象,新對象和原對象完全分離開。

如果拷貝的對象裡的元素包含引用(像一個列表裡儲存著另一個列表,存的就是另一個列表的引用),那淺拷貝和深拷貝是不同的,淺拷貝雖然將原有對象複製一份,但是依然保存的是引用,所以對新對象裡的引用裡的值進行修改,依然會改變原對象裡的列表的值,新對象和原對象完全分離開並沒有完全分離開。而深拷貝則不同,它會將原對象裡的引用也新創建一個,即新建一個列表,然後放的是新列表的引用,這樣就可以將新對象和原對象完全分離開。


3、 類和繼承

類可以看做相同的屬性和方法抽象概括而來,對象就是類實例化而來。

子類繼承父類的屬性和方法,可以有比父類更具體的屬性和方法,在類的屬性和方法使用中,首先在子類中查找再往父類上查找,節約代碼。如果在繼承元組中列了一個以上的類,那麼它就被稱作"多重繼承" 。繼承可以把父類的所有功能都直接拿過來,這樣就不必重零做起,子類只需要新增自己特有的方法,也可以把父類不適合的方法覆蓋重寫。

那麼可以在 子類的 __init__中調用一下父類的 __init__ 方法,這樣就可以調用了:

金融科技求職面試題

<code>class Animal:/<code>
<code>    def __init__(self):/<code>
<code>        self.a = 'aaa'/<code>
<code>class Cat(Animal):/<code>
<code>    def __init__(self):/<code>
<code>        super().__init__()  #也可以用 Animal.__init__(self)  這裡面的self一定要加上/<code>
<code>cat = Cat()print(cat.a)>>>aaa生成器和迭代器迭代是Python最強大的功能之一,是訪問集合元素的一種方式。迭代器是一個可以記住遍歷的位置的對象。迭代器對象從集合的第一個元素開始訪問,直到所有的元素被訪問完結束。迭代器只能往前不會後退。迭代器有兩個基本的方法:iter()和next()。字符串,列表或元組對象都可用於創建迭代器:在 Python 中,使用了 yield 的函數被稱為生成器(generator)。跟普通函數不同的是,生成器是一個返回迭代器的函數,只能用於迭代操作,更簡單點理解生成器就是一個迭代器。在調用生成器運行的過程中,每次遇到 yield 時函數會暫停並保存當前所有的運行信息,返回 yield 的值, 並在下一次執行 next() 方法時從當前位置繼續運行。調用一個生成器函數,返回的是一個迭代器對象。可變對象和不可變對象Python3 中有六個標準的數據類型:· Number(數字) Python3 支持int、float、bool、complex(複數)。· String(字符串)· List(列表)· Tuple(元組)· Set(集合)· Dictionary(字典)Python3 的六個標準數據類型中:· 不可變數據(3 個):Number(數字)、String(字符串)、Tuple(元組);· 可變數據(3 個):List(列表)、Dictionary(字典)、Set(集合)。hive中Sort By,Order By,Cluster By,Distribute By,Group By的區別order by:  hive中的order by 和傳統sql中的order by 一樣,對數據做全局排序,加上排序,會新啟動一個job進行排序,會把所有數據放到同一個reduce中進行處理,不管數據多少,不管文件多少,都啟用一個reduce進行處理。如果指定了hive.mapred.mode=strict(默認值是nonstrict),這時就必須指定limit來限制輸出條數,原因是:所有的數據都會在同一個reducer端進行,數據量大的情況下可能不出結果,那麼在這樣的嚴格模式下,必須指定輸出的條數。sort by:sort by 是局部排序,會在每個reduce端做排序,每個reduce端是排序的,也就是每個reduce出來的數據是有序的,但是全部不一定有序,除非一個reduce,一般情況下可以先進行局部排序完成後,再進行全局排序,會提高不少效率。distribute by:  distribute by 是控制map端在reduce上是如何區分的,distribute by 會把指定的值發到同一個reduce中,比如 用上面數據distribute by id 它就會把id相同的值放到一個reduce中執行,不是一個值一個reduce,而是相同的值進入到一個reduce,例如用上面數據可以進入到2個reduce,一般情況下可以sort by 結合使用,先進行分組reduce,再進行排序(相當於mapreduce中的分區函數)。PS:Order by 能夠預期產生完全排序的結果,但是它是通過只用一個reduce來做到這點的。所以對於大規模的數據集它的效率非常低。在很多情況下,並不需要全局排序,此時可以換成Hive的非標準擴展sort by。Sort by為每個reducer產生一個排序文件。在有些情況下,你需要控制某個特定行應該到哪個reducer,通常是為了進行後續的聚集操作。Hive的distribute by 子句可以做這件事cluster by(只能是使用默認的升序排序,不能使用ACS和DESC):  這個其實就是distribute by 和sort by 結合使用的結果(前提是同一個字段)。  例如:select id,money,name from t cluster by id;  等價於:select id,money,name from t distribute by id sort by iddistribute by和group by的區別:  都是按key值劃分數據 都使用reduce操作 **唯一不同的是,distribute by只是單純的分散數據,distribute by col – 按照col列把數據分散到不同的reduce。而group by把相同key的數據聚集到一起,後續必須是聚合操作。order by和sort by的區別:  order by是全局排序 sort by只是確保每個reduce上面輸出的數據有序。如果只有一個reduce時,和order by作用一樣。Hive分區表和分桶表的區別分區在HDFS上的表現形式是一個目錄, 分桶是一個單獨的文件分區: 細化數據管理,直接讀對應目錄,縮小mapreduce程序要掃描的數據量分桶: 1、提高join查詢的效率(用分桶字段做連接字段)     2、提高採樣的效率Hive數據傾斜處理hive底層的執行引擎 mr:mapreduce 由兩部分組成:map 、 reduce歸根結底:底層mr的數據傾斜。怎麼判斷程序發生了數據傾斜?reduce停留在一個階段很長時間不動數據傾斜與 1)數據量; 2)map端key的設置;有關hive中哪些操作容易造成數據傾斜:join操作:join關聯時有null值關聯時數據類型不同小表 關聯 大表 造成數據傾斜set hive.auto.convert.join = true; //設置mapjoin優化自動開啟裝飾器就是現在比如有很多個性化函數,但是每個函數都有一些重複的代碼。現在需要做的就是將這些重複的代碼放到一個裝飾器函數的內層函數之中,個性化函數作為裝飾器的參數傳入,裝飾器形成閉包。Python存在這樣的語法糖,@ 然後調用個性化函數就可以了。個性化函數的參數對應內層函數的參數,函數對應外層函數參數。主要就是起到不改變代碼的情況下,增加更多的函數功能。python2和python3的range(100)的區別python2返回列表,python3返回迭代器,節約內存/<code> 


分享到:


相關文章: