導航:首頁 > 源碼編譯 > 源碼筆記23

源碼筆記23

發布時間:2023-01-08 08:15:41

㈠ Netty源碼筆記

Netty版本4.0.29.Final,以構造客戶端連接服務端的角度來追蹤源碼

NioEventLoopGroup的構造器中會調用父類MultithreadEventLoopGroup的構造器

在父類MultithreadEventExecutorGroup的構造器中

上面已經完成了NioEventLoop的創建,並保存在NioEventLoopGroup的數組屬性上。而關於NioEventLoop在具備線程池能力時,在何時啟動已經創建的線程呢?在SingleThreadEventExecutor::execute中可以找到答案

而關於NioEventLoop內線程啟動後的邏輯,可以在創建該線程時看到有向線程提交一個任務。根據任務內SingleThreadEventExecutor.this.run()可以定位到創建線程提交任務的NioEventLoop::run

NioEventLoop::run是Netty的核心所在。它是NioEventLoop的線程執行的唯一任務。方法內無限循環,阻塞等待IO事件或隊列中的任務

關於隊列中的任務從哪裡來?一是源碼內部,啟動時會直接提交任務到隊列中;二是可以直接取出channel中的NioEventLoop向其提交任務;三是使用Channel寫數據時,都是以任務的形式提交到隊列中。與Channel綁定的NioEventLoop循環時會消費提交到隊列中任務並執行,後續在分析unsafe時會一並提及。

客戶端Bootstrap配置引導時,需要指定Channel類型,後續會使用反射創建該Channel類型實例。

客戶端完成NioEventLoopGroup和Bootstrap的創建及對Bootstrap進行相關的設置後,使用Bootstrap嘗試與服務端建立連接。在同步與非同步之間,推薦使用非同步來監聽連接事件的結果。

AbstractBootstrap是Bootstrap的父類,initAndRegister中完成了通道的創建、初始化以及注冊

group()取到開始配置的NioEventLoopGroup,register在父類MultithreadEventLoopGroup中

雖說暫時不引入unsafe類邏輯,但在unsafe::register中,通道注冊完成後會調用管道的fireChannelRegistered方法,進而執行自定義的ChannelInitializer,最終形成完整的管道。
目前管道上鏈表有三個節點:head、自定義ChannelInitializer、tail(規定自頭向尾的流向為In,自尾向頭的為Out)
它們的類型都是AbstractChannelHandlerContext,每個Context上都持有對應的ChannelHandler

至此,Channel的初始化及注冊已經完成。回到Bootstrap::doConnect中,在Channel注冊這個非同步任務完成後,開始真正的連接服務端

channel連接建立完成後,可以使用channel寫數據

寫數據不會直接發送數據到服務端,而是會緩存起來,直到調用flush才會完成數據的最終發送。flush邏輯與寫數據一樣,channel到pipeline,tail到head。最終交由unsafe類來完成

以客戶端建立連接發送數據流程為例(服務端大部分邏輯相似),總結Netty的工作流程:

㈡ mmdetection源碼閱讀筆記(2)--Loss

之前寫了模型和網路的創建,這里就主要寫下訓練過程中具體的loss,主要分為以下幾部分

rpn_loss 的實現具體定義在 mmdet/models/anchor_head/rpn_head.py

具體的計算方式定義在其父類 mmdet/models/anchor_heads/anchor_head.py ,主要是 loss 和 loss_single 兩個函數。
先看 loss 函數

這個主要做了兩個事

首先,在此時 rpn 的輸出為 feature map 中每個位置的 anchor 分類的 score 以及該 anchor 的 bbox 的修正值,我們要通過和 gt 計算 loss 來優化我們的網路,但是我們的gt是一堆人工標注的 bbox ,無法直接計算 loss 。所以,我們應該要先獲取到 anchor 然後將這些 anchor 和 gt 對比在分別得到正負樣本以及對應的 target ,之後我們才能計算得到 loss 。

所以第一步通過 anchor_list, valid_flag_list = self.get_anchors(featmap_sizes, img_metas) 獲取到了所有的 anchor 以及一個 是否有效的 flag (根據bbox是否超出圖片邊界來計算。)
拿到了所有的 anchor 之後就是和gt對比來區分正負樣本以及生成 label 了,通過定義在 mmdet/core/anchor/anchor_target.py 的 anchor_target() 實現。
在這個函數中調用 assigner 將 anchor 和 gt 關聯起來,得到 正樣本 和 負樣本 ,並用 sampler 將這些結果進行封裝,方便之後使用。
得到了 target 過後,就是計算 loss 了,在 self.loss_single 中,

這里用的 loss 就是常見的 CrossEntropyLoss 和 SmoothL1Loss

之前的 rpn_loss 是對候選框的第一次修正,這里的 bbox_loss 就是第二次修正了,兩者的實際差別主要體現在分類上,在 rpn 階段只分兩類(前景和背景),這里分類數為 N+1 (真實類別+背景)
具體定義在 mmdet/models/bbox_heads/bbox_head.py

可以看到和 rpn loss 相比,這里要簡單很多,因為這里只包含了 rpn loss 中實際計算 loss 的部分,但是他也同樣需要 rpn 中的 assign 和 sample 操作,兩者的區別只是 assign 的輸入不同, rpn 的 assign 輸入是該圖所有的 anchor , bbox 部分 assign 的輸入就是 rpn 的輸出。這里的 loss 和 rpn 中的計算方式完全一樣,就不在贅述了。

mask 部分計算 loss 之前也有一個獲取 target 的步驟。
mmdet/models/mask_heads/fcn_mask_head.py

這里獲取 target 相對之前來說就要簡單點了,通過定義在 mmdet/core/mask/mask_target.py 的 mask_target() 取到和 prooisals 相同大小的 mask 就行了。

而 loss 部分也比較簡單,也是用的 CrossEntropyLoss 。

總的來說這些 loss 還是算比較好理解的,看起來有三部分的 loss ,但是實際上每個部分的都差不多。
下一篇就准備寫下整個的訓練流程了,相當於將前面這三篇給連起來,有個更具體的理解。

㈢ consul源碼筆記

從本周開始對consul的源碼做一個簡單的閱讀和了解,希望能持續下去吧。
consul是使用go編寫的,在閱讀過程中可能會涉及到對go語法的相關筆記,這個會分開兩個系列文章去更新。

1.agent的定義(agent.go)

agent是一個常駐進程部署在所有機器上,可以分client和server兩種模式運行(client模式只負責轉發請求,輕量級)。
config為agent的配置,包括nodeID等核心的配置都在里
delegate為Server或者client的對象,取決於進程啟動選擇的方式
2.程序入口(agent.go)

這里主要是構建一個Server或者client的對象,我們接下來看一個server對象是如何構建的

我們看下server對象的重要屬性,跟raft協議相關的對象封裝在這里。

這里做的事情很簡單,啟動伺服器並輸出日誌。

最後我們看起構建一個raft對象具體做了哪些事情。

㈣ springboot 2.x源碼筆記- 配置文件載入 ConfigFileApplicationListener

至此,整個environment的配置載入過程就完成了。

配置項的注入是要等到bean的實例化後初始化階段, 參考這里 .實例化後,會通過org.springframework.beans.factory.annotation.#postProcessProperties-->org.springframework.beans.factory.annotation.InjectionMetadata#inject--->org.springframework.beans.factory.annotation..AutowiredMethodElement#inject--->org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveDependency--->org.springframework.beans.factory.support.DefaultListableBeanFactory#doResolveDependency

總結:

㈤ 源碼修煉筆記之Dubbo線程池策略

FixedThreadPool

FixThreadPool內部是通過ThreadPoolExecutor來創建線程,核心線程數和最大線程數都是上下文中指定的線程數量threads,因為不存在空閑線程所以keepAliveTime為0,
當queues=0,創建SynchronousQueue阻塞隊列;
當queues<0,創建無界的阻塞隊列LinkedBlockingQueue;
當queues>0,創建有界的阻塞隊列LinkedBlockingQueue。
採用bbo自己實現的線程工廠NamedInternalThreadFactory,將線程置為守護線程(Demon)
拒絕策略為AbortPolicyWithReport,策略為將調用時的堆棧信息保存到本地文件中,並拋出異常RejectedExecutionException

CachedThreadPool

CachedThreadPool與FixedThreadPool的區別是核心線程數和最大線程數不相等,通過alive來控制空閑線程的釋放

LimitedThreadPool

LimitedThreadPool與CachedThreadPool的區別是空閑線程的超時時間為Long.MAX_VALUE,相當於線程數量不會動態變化了,創建的線程不會被釋放。

EagerThreadPool

與上述三種線程池不同,EagerThreadPool並非通過JUC中的ThreadPoolExecutor來創建線程池,而是通過EagerThreadPoolExecutor來創建線程池,EagerThreadPoolExecutor繼承自ThreadPoolExecutor,實現自定義的execute方法,採用的阻塞隊列是TaskQueue,TaskQueue繼承自LinkedBlockingQueue。

execute方法首先調用ThreadPoolExecutor的execute方法,如果執行失敗會重新放入TaskQueue進行重試。

實現自定義的ThreadPool

ThreadPool被定義為一個擴展點,如下所示,

其默認實現是FixedThreadPool,可以通過實現該擴展來實現自定義的線程池策略。

㈥ String類源碼筆記(一):成員變數和構造器

String類表示字元串,所有類似"abc"形式的字元串(或魔法字元串)都被看作是這個類的實例。String是不可變的,當一個字元串在常量池中被創建時,他的值就不會被改變。

所在路徑:javalangString.java

為了保證String類是一個不可變類,String類的成員變數多為私有和不可變的。

其中serialPersistentFields在序列化時使用:

JDK8的String類一共有16個構造器,其中兩個是@Deprecated,一個是私有構造器,剩下的13個是可以調用的。

無參構造器直接將""的value賦值給當前類的value。""的value是一個空的char[],其length為0。調用使用了無參構造器的String對象的isEmpty()方法會得到true,調用length()方法會得到0,判斷其==null會得到false。

入參為String對象時,構造器會對其進行直接取值。

入參為字元串數組時,構造器調用的是Arrays.Of()方法。

其中Arrays.Of()方法是為了將入參的字元串序列深拷貝到this.valuie中,他的源碼為:

其中System.array()方法的源碼為:

這個方法支持直接傳入想要生成的String的母串,通過偏移量和有效長度找出需要賦值給this.value的部分,然後調用Arrays.OfRange()方法進行深拷貝。

當需要將一個Unicode編碼序列轉換為String時,可以使用以下構造器:

當需要將一個bytes[]轉換為String時,可以使用以下構造器:

此外,還有一些將上述構造器進一步封裝的構造器,其本質都是簡化入參。另外,String類的構造器同樣支持傳入StringBuffer和StringBuilder。如果傳入的是StringBuffer,構造器會為其加鎖。如果傳入的是StringBuilder則不會加鎖。

事實上,StringBuffer和StringBuilder的toString()方法調用的也是String類的構造器,他們最終的底層實現都是Arrays.Of()。

最後,String類還提供了一個保護類型的構造方法。該方法相比入參為char[]的構造器多了一個share參數,這個參數並沒有實際作用,只是用來和其他構造器進行區分。當String類內部調用該構造器時:

該構造器不能對外暴露的原因是需要保持String類的不可變性。

㈦ Eureka源碼淺讀---自我保護機制

Eureka源碼採用1.7.2版本

本人小白,此文為本人閱讀源碼筆記,如果您讀到本文,您需要自己甄別是否正確,文中的說明只代表本人理解,不一定是正確的!!!

自我保護機制設計的初衷是防止服務注冊服務因為本地網路故障,長時間未接受到心跳請求,造成錯誤的移除大量服務實例,其實調用服務還是可用的

自我保護機制是和自動故障移除聯系在一起的,針對的移除實例也是自動故障移除

在服務故障移除的方法中有這樣一個判斷,當返回false時候,直接返回,不進行故障實例的摘除
進入該方法

關於獲取上一分鍾心跳總數,Eureka Server內部採用的是定時線程進行統計,使用兩個AtomicLong進行保存當前和上一分鍾的心跳總數

該方法初始化了運行了定時調度的線程進行統計,默認執行間隔為1min,執行流程:

那麼當前的心跳總數是怎麼計算的呢,直接看心跳的renew()方法,是否嵌入了計數器累計操作

如上所示,當接收到心跳時,當前心跳計數器進行了遞增操作

而getNumOfRenewsInLastMin()獲取上一分鍾心跳總數就是獲取lastBucket數量,再找下該定時任務啟動的入口

和自動故障移除的定時同時啟動的,那麼lastBucket代表了上一分鍾的心跳總數

接下來,我們需要看看期望每分鍾最小心跳總數的由來:

numberOfRenewsPerMinThreshold最開始的初始化計算是在Eureka Server初始化計算的,使用當前Server拉取到的服務實例總數 * 0.85

在openForTraffic()方法中使用初始化拉取的服務實例總數作為基數標准進行計算,(int) (this.expectedNumberOfRenewsPerMin * serverConfig.getRenewalPercentThreshold()) -> count * 2 * 0.85,
集群模式下,count為其他節點中已注冊的服務實例總數,單節點就為0

下面我們看看在注冊中心接收到注冊,下線等請求執行時,維護numberOfRenewsPerMinThreshold

注冊,當前實例數量+2,下線,當前實例數量-2,然後再次*0.85,計算期望每分鍾最小心跳數



在Eureka Server中有專門的定時任務進行更新numberOfRenewsPerMinThreshold,默認每15min執行一次

主要流程如下:

注意,自動服務故障移除沒有進行numberOfRenewsPerMinThreshold的更新

<font color= 'blue'>服務故障實例的摘除需要判斷當前是否處於自我保護模式,而自我保護模式的默認是開啟(isSelfPreservationModeEnabled),需要判斷上一分鍾的心跳總數是否大於期望每分鍾最小心跳數,如果在15分鍾內,累計丟失了15%以上的節點心跳,那麼Eureka Server就會認為當前所處的網路環境異常,從而處於自動保護模式,故障實例將不會移除,再等待15min後,進行expectedNumberOfRenewsPerMin的基於當前服務實例的重新計算後,自我保護模式才會關閉!</font>

自我保護服務開啟模擬:

㈧ InteractionManager源碼閱讀筆記

InteractionManager的直接翻譯是交互管理器,在react-native的文檔里,其作用描述為:"Interactionmanager 可以將一些耗時較長的工作安排到所有互動或動畫完成之後再進行。這樣可以保證 JavaScript 動畫的流暢運行。"

我們最常用這個類的場景是:從A頁面跳轉到B頁面,然後想讓B頁面的網路請求或者頁面刷新工作放到過場動畫結束後再去做,這時可以用InteractionManager的runAfterInteractions函數來實現。

那麼問題來了,如果A頁面有一個循環不停止的動畫,這時候再跳轉B頁面,B頁面為了轉場動畫的順暢使用了runAfterInteractions,但由於A頁面的循環動畫而永遠無法進入回調閉包,這個問題怎麼解決呢?

react-native官方已經考慮到了,在Animated類裡面的 loop 方法,有這么一段話:"In addition, loops can prevent VirtualizedList-based components from rendering more rows while the animation is running. You can pass isInteraction: false in the child animation config to fix this."。雖然這段話不是在解決我們說的問題,但是所提到的isInteraction屬性,我們可以通過Animated的源碼,看到這個屬性是用來幹嘛的。

由此可見,這個isInteraction屬性是用來控制是否創建句柄的。

那麼關鍵的來了,InteractionManager.createInteractionHandle()和InteractionManager.runAfterInteractions()之間的具體關系是什麼樣的呢?

我們可以看看InteractionManager的 源碼 :

先看這一對函數:

一個是創建句柄一個是清除句柄,其實創建句柄很簡單,所謂的句柄就是全局變數_inc自增後的結果,然後加入了_addInteractionSet的集合。清除句柄,就是把handle從_addInteractionSet中移除,加入_deleteInteractionSet。那麼整個InteractionManager是如何運作起來的呢?runAfterInteractions中的回調是如何被調用的?這其實最核心的部分是在_scheleUpdate裡面:

_scheleUpdate主要是處理了InteractionManager的deadline,然後調用了_processUpdate:

如上圖所示,第一個紅框裡面其實就是InteractionManager最核心的部分。還記得剛才的createInteractionHandle和clearInteractionHandle么,其實整個InteractionManager就是實現了生產者消費者模型。第二個紅框部分,其實就是去執行runAfterInteractions裡面的閉包回調。我們最後再看runAfterInteractions:

參數task最終加入了_taskQueue中,而這個_taskQueue會在_processUpdate中被遍歷執行。

用一個很通俗易懂的方法來解釋InteractionManager,比如我們去面館吃面,跟老闆說我要一碗面(createInteractionHandle),然後我們就找個位子等老闆把面端上來了(runAfterInteractions(()=>{console.log('吃面')})),過了一陣子老闆面做好了,於是端上面(clearInteractionHandle),我們就吃到面了。那麼又有個疑問了,為啥InteractionManager要設計的這么復雜呢?直接存一下回調,然後觸發回調不就好了么。這就好比我們出去吃面,不可能吃光面一樣。比如我們要吃一碗雪菜肉絲面,那麼流程就得這樣了:

最後,我們看一下react-native裡面會有哪些地方默默的為我們createInteractionHandle呢?

一共就這兩處,第一處就是創建動畫的時候,官方文檔上也說了可以用來延遲耗時操作,保證轉場動畫流暢。第二處是這個 PanResponder ,官方文檔也做了解釋,保證手勢響應順暢。但其實大家在理解了上面吃面的例子後,也可以擴展一下自己的思維,靈活的運用InteractionManager。

㈨ MyBatis­Plus快速入門源碼筆記共享,拿走吧你

為什麼要學習它呢?

答:MyBatisPlus可以節省我們大量工作時間,所有的CRUD代碼它都可以自動化完成!

優點:
1. 易於上手和掌握。
2. sql寫在xml里,便於統一管理和優化。
3. 解除sql與程序代碼的耦合。
4. 提供映射標簽,支持對象與資料庫的orm欄位關系映射
5. 提供對象關系映射標簽,支持對象關系組建維護
6. 提供xml標簽,支持編寫動態sql。

MyBatis Plus(簡稱 MP)是一個 MyBatis的增強工具,在 MyBatis 的基礎上只做增強不做改變,為簡化開發、提高效率而生。

就像 魂斗羅 中的 1P、2P,基友搭配,效率翻倍。

特性:

無侵入 :只做增強不做改變,引入它不會對現有工程產生影響,如絲般順滑。

損耗小 :啟動即會自動注入基本 CURD,性能基本無損耗,直接面向對象操作 強大的 CRUD 操作 :內置通用 Mapper、通用 Service,僅僅通過少量配置即可實現單表大部分 CRUD 操作,更有強大的條件構造器,滿足各類使用需求 支持 Lambda 形式調用 :通過 Lambda 表達式,方便地編寫各類查詢條件,無需再擔心欄位寫錯。

支持組件自動生成 :支持多達 4 種主鍵策略(內含分布式唯一 ID 生成器 Sequence),可自由配置,完美解決主鍵問題。

支持 ActiveRecord 模式 :支持 ActiveRecord 形式調用,實體類只需繼承 Model 類即可進行強大的 CRUD 操作。

支持自定義全局通用操作 :支持全局通用方法注入( Write once, use anywhere )。

內置代碼生成器 :採用代碼或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 層代碼,支持模板引擎,更有超多自定義配置等您來使用 內置分頁插件 :基於 MyBatis 物理分頁,開發者無需關心具體操作,配置好插件之後,寫分頁等同於普通 List查詢。

分頁插件支持多種資料庫 :支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多種資料庫。

內置性能分析插件 :可輸出 Sql 語句以及其執行時間,建議開發測試時啟用該功能,能快速揪出慢查詢。

內置全局攔截插件 :提供全表 delete 、 update 操作智能分析阻斷,也可自定義攔截規則,預防誤操作。

1.1 、引入mybatis-plus相關maven依賴


引入mybatis-plus在spring boot中的場景啟動器


ps:切記不可再在pom.xml文件中引入mybatis與mybatis-spring的maven依賴,這一點,mybatis-plus的官方文檔中已經說明的很清楚了.

1.2、創建數據表

(1)SQL語句



(2) 數據表結構

1.3、 創建java bean

根據數據表新建相關實體類

1 package com.example.demo.pojo



1.4、 配置application.proprties

數據源使用druid



ps:在進行crud實驗之前,簡單對mybatis與mybatis-plus做一個簡單的對比

2.1、mybatis與mybatis-plus實現方式對比

(1)提出問題: 假設我們已存在一張 tbl_employee 表,且已有對應的實體類 Employee,實現 tbl_employee 表的 CRUD操作我們需要做什麼呢?

(2)實現方式: 基於 Mybatis 需要編寫 EmployeeMapper 介面,並手動編寫 CRUD 方法 提供 EmployeeMapper.xml 映射文件,並手動編寫每個方法對應的 SQL 語句. 基於 Mybatis-plus 只需要創建 EmployeeMapper 介面, 並繼承BaseMapper 介面.這就是使用 mybatis-plus 需要完成的所有操作,甚至不需要創建 SQL 映射文件。

2.2、BaseMapper介面介紹

(1)如何理解核心介面BaseMapper?

在使用Mybatis-Plus時,核心操作類是BaseMapper介面,其最終也是利用的Mybatis介面編程的實現機制,其默認提供了一系列的增刪改查的基礎方法,並且開發人員對於這些基礎操作不需要寫SQL進行處理操作(Mybatis提供的機制就是需要開發人員在mapper.xml中提供sql語句),那樣我們可以猜測肯定是Mybatis-Plus完成了BaseMapper介面提供的方法的SQL語句的生成操作。

(2)BaseMapper介面為我們定義了哪些方法?

BaseMapper介面源碼:





(3) mybatis-plus中常用的註解 1


由於我們的數據表名於實體類的類名不一致,並且實體類於數據表還存在欄位名不對應的情況,因此我們需要引入mybatis-plus的註解.



編寫EmployeeMapper介面繼承BaseMapper介面



准備考試環境:



(1)插入



(2)修改



控制台列印出的sql語句

如果我們不設置實體類的email與gender屬性,結果是怎樣的呢?



控制台sql語句:

顯然,mybatis-plus為我們做了非空判斷,空值的話,默認不更新對應的欄位.想一想,這是不是類似於mybatis中的動態sql呢?

這種處理效果又會帶來什麼好處呢?

(3)查詢



selectById方法



selectBatchIds方法



ps:發現該方法底層使用的竟然是sql的in關鍵字

selectByMap方法



(4)刪除



3、不得不提的條件構造器---Wrapper

3.1.wrapper及其子類介紹

(1)Wrapper :條件構造抽象類,最頂端父類,抽象類中提供3個方法以及其他方法.

㈩ suricata源碼筆記:main函數

main()函數位於suricata.c文件,其主要流程如下:

24. 執行PostConfLoadedSetup,即運行那些需要在 配置載入完成 後就立馬執行的函數。這裡面涉及的流程和函數非常多:

閱讀全文

與源碼筆記23相關的資料

熱點內容
加密門禁卡寫入成功無法開門 瀏覽:447
齒輪傳動pdf 瀏覽:35
alpinelinux 瀏覽:148
手機端app的掃碼功能在哪裡 瀏覽:225
少兒編程中小班英語教案 瀏覽:450
鎖屏密碼加密手機怎麼解除 瀏覽:203
linuxlostfound 瀏覽:132
征途伺服器ip地址 瀏覽:328
git提交代碼命令行 瀏覽:163
什麼叫瀏覽器伺服器結構 瀏覽:155
於謙聊天哪個app 瀏覽:447
小鵬汽車nlp演算法工程師薪資 瀏覽:879
代碼加密與隱藏 瀏覽:647
fordfulkerson演算法 瀏覽:350
京東熱app在哪裡可以下載 瀏覽:874
彩報圖書app哪個好 瀏覽:301
新君威20壓縮比 瀏覽:186
手機php整站 瀏覽:915
windows路由跳轉命令 瀏覽:472
量子遺傳演算法程序 瀏覽:222