文章目錄
- 1.__call__魔法方法(完成)
- (1)使實體物件變為可呼叫物件
- (2)彌補hasattr()函式短板
- (3)再來一個栗子
- 2.yield的用法
- 3.C++的左值和右值參考(沒答上)
- 4.input=8*8,filter=3*3,stride=1,padding=1卷積結果
- 5.GBDT的特征怎么選擇
- 6.智能指標怎么解決交叉參考,造成的記憶體泄漏
- (1)交叉參考的栗子:
- (2)解決方案
- 7. C++多執行緒了解不?
- (1)并行和并發的概念:
- (2)并發的基本方法
- (3)C++11中的并發與多執行緒
- 8.頭檔案functional(C++11特性)
- 9.小結
- Reference
1.__call__魔法方法(完成)
(1)使實體物件變為可呼叫物件
__call__
類似在類中多載()
運算子,使得類實體物件可以像呼叫普通函式一樣,即使用物件名()
:
class Pig:
# 定義__call__方法
def __call__(self,name,add):
print("呼叫__call__()方法",name,add)
pig = Pig()
pig("你是豬嗎?","不是哦")
# 呼叫__call__()方法 你是豬嗎? 不是哦
通過在Pig
類中實作__call__
方法,使得實體物件pig
變為可呼叫物件,對于可呼叫物件,名稱()
等價于名稱.__call__
,即上面的代碼等價于為pig.__call__("你是豬嗎?", "不是哦")
,
- python中的可呼叫物件:
- 自定義函式
- python內置函式
- 上面的類實體物件
(2)彌補hasattr()函式短板
hasattr(當前物件, 屬性)
函式能夠判斷當前物件是否包含對應的屬性 or 方法,但是不能判斷同名情況,是指類屬性 還是 類方法,
類實體物件包含的方法,也是可呼叫物件(有__call__()
方法),但是類屬性不是可呼叫物件,所以如下栗子的say
類方法是可呼叫物件,擁有__call__()
方法,
class CLanguage:
def __init__ (self):
self.name = "language"
self.add = "english"
def say(self):
print("hello world!")
clangs = CLanguage()
if hasattr(clangs,"name"):
print(hasattr(clangs.name,"__call__"))
print("**********")
if hasattr(clangs,"say"):
print(hasattr(clangs.say,"__call__"))
(3)再來一個栗子
class Entity:
'''呼叫物體來改變物體的位置,'''
def __init__(self, x):
self.x = x
def __call__(self):
'''改變物體的位置'''
print('self.x:', self.x)
entity = Entity(1)
entity()
================================
output:
self.x: 1
2.yield的用法
一個列印斐波那契數列的栗子:
def fab(max):
n, a, b = 0, 0, 1
while n < max:
yield b # 使用 yield
# print b
a, b = b, a + b
n = n + 1
for n in fab(5):
print (n)
-
yield
的作用就是把一個函式變成一個 generator,呼叫 fab(5) 不會執行 fab 函式,而是回傳一個iterable
物件! -
在 for 回圈執行時,每次回圈都會執行
fab
函式內部的代碼,執行到 yield b 時,fab 函式就回傳一個迭代值,下次迭代時,代碼從 yield b 的下一條陳述句繼續執行,而函式的本地變數看起來和上次中斷執行前是完全一樣的,于是函式繼續執行,直到再次遇到 yield, -
也可以手動呼叫 fab(5) 的 next() 方法(因為 fab(5) 是一個 generator 物件,該物件具有 next() 方法):
>>>f = fab(5)
>>> f.next()
1
>>> f.next()
1
>>> f.next()
2
>>> f.next()
3
>>> f.next()
5
>>> f.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
3.C++的左值和右值參考(沒答上)
這玩意還要好好學學:C++11的左值參考與右值參考總結
4.input=88,filter=33,stride=1,padding=1卷積結果
padding后是9乘9,然后和卷積核運算后是7乘7,
5.GBDT的特征怎么選擇
決策樹常用于分類,目標就是將具有 P P P 維特征的 n n n 個樣本分到 C C C 個類別中,相當于做一個映射 C = f ( n ) C = f(n) C=f(n) ,將樣本經過一種變換賦予一個 l a b e l label label,可以把分類的程序表示成一棵樹,每次通過選擇一個特征 p i pi pi 來進行進一步分叉分類,
決策樹中的特征重要性,不像線性回歸一樣可以用系數表示特征重要性,而根據每次分叉選擇哪個特征對樣本進行劃分,能夠又快又準地對樣本進行分類,即根據不同的特征選擇方案,我們分為了:ID3、C4.5、CART等演算法,
ID3樹 | C4.5樹 | CART演算法 | |
---|---|---|---|
評價標準 | 資訊增益 | 資訊增益比 | 基尼指數 |
樣本型別 | 離散型變數 | 連續型變數 | 連續型變數 |
任務 | 分類 | 分類 | 分類and回歸(回歸樹使用最小平方誤差) |
6.智能指標怎么解決交叉參考,造成的記憶體泄漏
結論:創建物件時使用shared_ptr
強智能指標指向,其余情況都使用weak_ptr
弱智能指標指向,
(1)交叉參考的栗子:
當A類中有一個指向B類的shared_ptr
強型別智能智能,B類中也有一個指向A類的shared_ptr
強型別智能指標,
main
函式執行后有兩個強智能指標指向了物件A,物件A的參考計數為2,B類也是:
#include <iostream>
#include <memory>
using namespace std;
class B;
class A{
public:
shared_ptr<B> _bptr;
};
class B{
public:
shared_ptr<A> _aptr;
};
int main(){
shared_ptr<A> aptr(new A());
shared_ptr<B> bptr(new B());
aptr->_bptr = bptr;
bptr->_aptr = aptr;
return 0;
}
而當主函式main
的return
回傳后,物件A
的參考計數減一變為1(aptr
沒指向A
物件了),B
物件也是,參考計數不為0,即不能析構2個物件釋放記憶體,造成記憶體泄漏,
(2)解決方案
將類A和類B中的shared_ptr
強智能指標都換成weak_ptr
弱智能指標;
class A{
public:
weak_ptr<B> _bptr;
};
class B{
public:
weak_ptr<A> _aptr;
};
weak_ptr
弱智能指標,雖然有參考計數,但實際上它并不增加計數,而是只觀察物件的參考計數,所以此時物件A的參考計數只為1,物件B的參考計數也只為1,
7. C++多執行緒了解不?
多執行緒指的是在一個程式行程中處理控制流的多路并行通道,它在所有作業系統上為運行該程式提供了相同程度的并發性,C++ 11 之后添加了新的標準執行緒庫 std::thread
,std::thread
在 <thread>
頭檔案中宣告,
(1)并行和并發的概念:
- 并行:同時執行,計算機在同一時刻,在某個時間點上處理兩個或以上的操作,(如下圖)
判斷一個程式是否并行執行,只需要看某個時刻上是否多兩個或以上的作業單位在運行,一個程式如果是單執行緒的,那么它無法并行地運行,利用多執行緒與多行程可以使得計算機并行地處理程式(當然 ,前提是該計算機有多個處理核心),
- 并發:同一時間段內可以交替處理多個操作,如下圖,每個佇列都有自己的安檢視窗,兩個佇列中間沒有競爭關系,佇列中的某個排隊者只需等待佇列前面的人安檢完成,然后再輪到自己安檢,
如果我們將程式的結構設計為可以并發執行的,那么在支持并行的機器上,我們可以將程式并行地執行,因此,并發重點指的是程式的設計結構,而并行指的是程式運行的狀態,并發編程,是一種將一個程式分解成小片段獨立執行的程式設計方法,
(2)并發的基本方法
- 多行程:
- 如你和小伙伴要開發一個專案,但是已經放假回家了,所以通過wechat聯系,各自作業時互不干擾,這里的小伙伴代表執行緒,作業地點代表一個處理器,這個場景的每個小伙伴是一個單執行緒的行程(擁有獨立的處理器),
- 多個行程獨立地運行,它們之間通過行程間常規的通信渠道傳遞訊息(信號,套接字,檔案,管道等),這種行程間通信不是設定復雜就是速度慢,這是因為為了避免一個行程去修改另一個行程,作業系統在行程間提供了一定的保護措施,當然,這也使得撰寫安全的并發代碼更容易,運行多個行程也需要固定的開銷:行程的啟動時間,行程管理的資源消耗,
- 多執行緒:
- 上學時,你和小伙伴在實驗室共同討論問題,頭腦風暴,更有效地溝通專案,這里的場景即只有一個處理器,所有小伙伴都是屬于同一行程的執行緒,
C++11 標準提供了一個新的執行緒庫,內容包括了管理執行緒、保護共享資料、執行緒間的同步操作、低級原子操作等各種類,標準極大地提高了程式的可移植性,以前的多執行緒依賴于具體的平臺,而現在有了統一的介面進行實作, - 在當個行程中運行多個執行緒也可以并發,執行緒就像輕量級的行程,每個執行緒相互獨立運行,但它們共享地址空間,所有執行緒訪問到的大部分資料如指標、物件參考或其他資料可以在執行緒之間進行傳遞,它們都可以訪問全域變數,行程之間通常共享記憶體,但這種共享通常難以建立且難以管理,缺少執行緒間資料的保護,因此,在多執行緒編程中,我們必須確保每個執行緒鎖訪問到的資料是一致的,
- 上學時,你和小伙伴在實驗室共同討論問題,頭腦風暴,更有效地溝通專案,這里的場景即只有一個處理器,所有小伙伴都是屬于同一行程的執行緒,
(3)C++11中的并發與多執行緒
C++11 新標準中引入了幾個頭檔案來支持多執行緒編程:(所以我們可以不再使用 CreateThread 來創建執行緒,簡簡單單地使用 std::thread 即可,)
< thread >
:包含std::thread類以及std::this_thread命名空間,管理執行緒的函式和類在 中宣告.
< atomic >
:包含std::atomic和std::atomic_flag類,以及一套C風格的原子型別和與C兼容的原子操作的函式,
< mutex >
:包含了與互斥量相關的類以及其他型別和函式
< future >
:包含兩個Provider類(std::promise和std::package_task)和兩個Future類(std::future和std::shared_future)以及相關的型別和函式,
< condition_variable >
:包含與條件變數相關的類,包括std::condition_variable和std::condition_variable_any,
8.頭檔案functional(C++11特性)
<functional>
是C++標準庫中的一個頭檔案,定義了C++標準中多個用于表示函式物件(function object)的類模板,包括演算法操作、比較操作、邏輯操作;- 以及用于系結函式物件的實參值的系結器(binder),這些類模板的實體是具有函式呼叫運算子(function call operator)的C++類,這些類的實體可以如同函式一樣呼叫,不必寫新的函式物件,而僅是組合預定義的函式物件與函式物件配接器(function object adaptor),就可以執行非常復雜的操作,
9.小結
演算法專案,C++11特性問了幾個,常見機器學習演算法都問,
Reference
[1] C++11多執行緒的三種創建方式
[2] Linux c++執行緒同步的四種方式:互斥鎖,條件變數,讀寫鎖,信號量
[3] 菜鳥教程—C++ std::thread
[4] https://www.cnblogs.com/yskn/p/9355556.html(重點)
[5] 菜鳥教程—C++多執行緒
[6] C++/C++11中頭檔案functional的使用
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/438646.html
標籤:AI