主頁 > 軟體設計 > 體驗為王-2021友盟+移動性能優化比賽第一名作品

體驗為王-2021友盟+移動性能優化比賽第一名作品

2021-10-27 10:12:15 軟體設計

文章目錄

  • 前言
  • 人臉識別會議系統性能優化
  • 一.專案背景
    • 1.簡介
    • 2.問題以及所遇到的挑戰
      • 1.問題
      • 2.挑戰
  • 二.解決問題的步驟
    • 1.復盤設計
    • 2.資料分析
      • 1.渲染模式分析
      • 2.分析耗電情況
      • 3.執行緒活動與CPU分析
      • 4.資料匯總
    • 3.定位問題
    • 4.分析問題
    • 5.解決問題
      • 1.開啟影片原生驅動
      • 2.使用互動管理器 InteractionManager
      • 3.重新渲染
    • 6.驗證問題(性能監控平臺的應用)
      • 1.Google Android Vitals + Firebase
      • 2.友盟+ U-APM
        • 2.1產品概述:
        • 2.2開發準備
        • 2.3集成SDK
        • 2.4權限授予
        • 2.5混淆設定
        • 2.6初始化sdk
  • 三.專案總結


前言

在這個“用戶體驗為王”的時代,如何能最大程度保障產品服務的穩定性,提供良好的用戶體驗是當前開發者需要思考和亟待解決的問題,由服務開發者11年之久的全域資料服務商——友盟+發起了2021移動應用性能挑戰賽,友盟+總裁、友盟+技術負責人、CSDN副總裁、思否CTO、阿里移動端飛豬、閑魚負責人等人共同組成專家評審組,經過評選,有幸獲得了第一名,現給大家分享下作品內容,大家也可以在評論區討論心得,

人臉識別會議系統性能優化

一.專案背景

1.簡介

公司是一家物聯網公司,意向自研一款人臉會議考勤簽到面板機,為了提高產品競爭力,主打性價比+定制化差異(硬體便宜好用,軟體頁面炫酷叼炸天);軟體研發部需要支撐配套的人臉會議考勤安卓平板應用,主要業務功能有:人臉識別功能(人臉采集、對比識別、人臉庫管理),會議模塊,考勤簽到功能,定制化互動模塊,
在這里插入圖片描述

人臉識別互動示意圖

與硬體產品經理的溝通后,提供一套樣機和一套產品清單來支撐軟體研發的開發和測驗,
主板是RK3288四核 1.8GHZ.2g記憶體,8G存盤的板子,安卓5.1的作業系統,螢屏是15.6英寸 1920*1080解析度 10點式電容觸摸屏,
在這里插入圖片描述

RK3288主板示意圖

在這里插入圖片描述

RK3288主板核心引數

框架選型是使用的React Native+tracker.js,考慮控制成本,沒有集成市面上的Android人臉識別SDK,通過經驗使用tracker.js替代opencv實作端的人臉識別捕捉,服務端實作人臉對比(這里為后續的錯誤埋下了伏筆),經過一段時間加班加點,開發了人臉會議考勤系統V0.1-Alpha版,
采購流程是比較慢的,等到開發板到了開始一輪真機測驗運行,搞了一輪以后組員說束手無策,別的機子都好好的,就這個不行,懷疑硬體問題,
排除硬體原因后,我整體的牽頭開始對于系統進行性能優化,

2.問題以及所遇到的挑戰

1.問題

1.人臉識別不流暢,人畫不同步,明顯延遲,人員高頻次出入鏡頭框會伴隨頓挫感,
2.POE供電,長時間運行軟體運行發熱發燙,
3.概率偶發性閃退現象,捕捉不到有價值的例外日志,

2.挑戰

1.沒有使用純安卓開發(組員基本不會安卓原生開發)+人臉識別安卓SDK(控制成本的訴求),限制了性能的上限,
2.硬體性能低,RK3288處理器,搭載的Mali-T764GPU,在14年當年算是神U,被譽為國產最強ARM處理器,但是已經6、7年過去了,我們采用的也是基礎版,安卓板人臉機還需要內置一些其他相關軟體,對性能和穩定性的要求還是比較高的,
3.概率性存在ANR/閃退崩潰問題,報錯模糊,定位不到問題,
4.組員整體為前端開發人員,對于app的優化和除錯經驗不足,

二.解決問題的步驟

1.復盤設計

忠告,先不要盯著問題本身,尤其是對于性能問題,這是大忌,這是對于很多開發人員都容易犯的錯誤,甚者用精妙的技巧去掩蓋系統設計上的缺陷,(產品設計,架構設計,原型設計,互動設計,UI設計等等)
如果系統運行或者測驗中出現了遠高于閾值的問題,第一步一定是先回過頭來看系統的看設計,(一定是)
沒有經驗的程式員會一頭扎入bug中,富有經驗的程式員會利用自有的思維方式了解問題,定位問題,分析問題,解決問題,驗證問題,而作為一個合格的架構師,或者技術團隊的leader,一定要學會“揪頭發”思維,
很多系統需要優化的問題,往往并不僅僅是一個技術問題,根源上可能是一個不合理的產品設計,冗余的架構,反人類的互動,層次過深的UI導致的,而由于系統的復雜度和團隊的溝通成本以及后期需求變動與場景的細化,往往在專案初期有些問題是很難暴露的,所以對于軟體系統的性能優化,第一步要復盤之前的設計與行為是否合理,
而事實上,所謂的差異化設計,在通過梳理精簡,剔除掉不合理因素后,對于一個工業平板app它的影片和互動還是太復雜了,

2.資料分析

本專案人臉檢測驗收標準:
包大小:~ 100M
最小人臉檢測大小:50px * 50px
可識別人臉角度:yaw ≤ ±30°, pitch ≤ ±30°
檢測速度:100ms 720p*
追蹤速度:50ms 720p*
人臉檢測耗時:< 200ms
人臉庫檢索速度:< 100ms
檢測+識別全流程耗時 < 500ms(app其他性能指標不做過多敘述)
工程化的一個要素就是用設定的標準去衡量離散型資料,如果優化沒有可量化的渲染性能評判標準,就是開發者\leader拍腦門決定了,所以不僅僅是測驗人員需要了解這些指標,開發者也要學會使用測驗工具去定位問題、驗證資料,
ok開始行動, Android adb網路連接安卓主板測驗,安裝apk,

1.渲染模式分析

打開安卓開發者模式,檢查 GPU 渲染速度和過度繪制,篩選出渲染壓力過大的頁面,

在這里插入圖片描述

GPU 渲染模式分析示意圖

在這里插入圖片描述

渲染顏色說明

過度繪制:實際上對于過度繪制相關的優化,要考慮投入產出比,過于精細的優化整體產出是不高的,該專案中只對于過度繪制紅色區域(過度繪制4次及以上區域)進行優化,

2.分析耗電情況

由于軟體伴有運行發熱發燙的現象,那么一定要分析耗電情況,
耗電統計是系統組件,也就是說系統運行他就一直在統計,所以獲取統計報告的時候需要將統計重置,
1.先斷開adb服務,然后開啟adb服務
殺死adb服務:執行adb kill-server 防止沖突和臟資料,
重啟adb: 執行adb devices或者adb start-server
2 .重置電池資料收集

adb shell dumpsys batterystats --enable full-wake-history
adb shell dumpsys batterystats --reset

正常情況下,我們應該斷開充電器并斷開usb連接(連接時充電),這樣會大大影響統計有效性,但是由于我們是poe供電,具體情況具體分析,使用資料輔助查找例外點,因為我們是5.1系統,所以使用adb命令:
在這里插入圖片描述

由于txt報告實在是比較大,10幾個m肉眼看不太現實,一般都配合Battery Historian這個工具來使用,
(注意:Battery Historian是android 5.0(api 21)及以上使用,如果有幸還在使用安卓4.4工業面板的可以略過此條了,)
在這里插入圖片描述

Battery Historian示例圖

3.執行緒活動與CPU分析

執行緒活動與CPU分析 工具有很多,但是Android Studio自帶的他不香嗎?(Rn安卓打包還是用Android Studio,使用vscode打包坑太多了,)
針對例外點進行分析,
在這里插入圖片描述

Android Studio CPU 分析器 示例圖(https://developer.android.com/)

4.資料匯總

資料顯示CPU的負擔過重,tracking導致行程有阻塞現象,
實際上大家一直認為是完全由于渲染壓力大導致的頁面卡頓,(渲染是RN 整個框架的瓶頸),報表資料顯示的恰恰相反,對于人臉識別,GPU并沒跑滿,圖形界面的渲染作業只有部分由GPU進行的,當tracking阻塞后會暫時等待發生卡頓,再逐個完成canvas 關鍵點渲染定位,呼叫介面,取得回傳資料后渲染資訊卡片和執行影片時導致第二次輕微卡頓(RN渲染卡頓),然后性能反應正弦函式波動,同時卡頓和不流暢現象消失,
導致“拍腦袋”定位問題就是因為前端同事對于日志和資料分析工具的使用是普遍不夠的,

3.定位問題

定位問題的方法有多種,像大家常用的二分查找法(二分注釋、二分回滾),或者 斷點除錯、分析日志,都可以有效的幫助我們快速定位問題,
那么通過資料的分析以及工具提供的關鍵類,我們也是比較清晰的找出了問題:資訊卡片影片+canvas特效+人臉識別相關函式,

4.分析問題

原有的實作方式:引入全部的相關js,new多個tracking.objectTracker來檢測人臉、眼睛、嘴的區域,在通過canvas實作人臉關鍵點的展示效果,
在這里插入圖片描述

而對人臉進行采集,Tracking.js 是使用 CPU 進行計算的,在影像的矩陣運算效率上,相對 GPU 要慢一些,
此時,有了資料的支撐,決定替換人臉識別框架層配合RN進行嘗試性優化,采用face-api.js

face-api.js
基于 TensorFlow.js 內核,實作了三種卷積神經網路架構,用于完成人臉檢測、識別和特征點檢測任務;其內部實作了一個非常輕巧,快速,準確的 68 點面部標志探測器,支持多種 tf 模型,微小模型僅為 80kb,另外,它還支持 GPU 加速,相關操作可以使用 WebGL 運行,
核心原理是針對人臉檢測作業實作了一個 SSD(Single Shot Multibox Detector)演算法,它本質上是一個基于 MobileNetV1 的卷積神經網路(CNN),在網路的頂層加入了一些人臉邊框預測層,
在這里插入圖片描述

face-api面部標志探測器

確認替換后,針對于React Native執行緒調度做一下調優,為了方便理解,我簡單繪制了一個示意圖,講解下流程:
?JS Thread:React 等 JavaScript 代碼都在這個執行緒執行,
?Bridge:連接橋,具有異步,序列化,批處理的特點
?Shadow Thread:進行布局計算和構造 UI 界面的執行緒,
?Native modules提供 Native 功能(比如相冊、藍牙)
?UI Thread:Android/iOS(或其它平臺)應用中的主執行緒,
在這里插入圖片描述
ReactNative執行緒示意圖

比如我們繪制一個UI,JS thread會先對其序列化,形成一條UIManager.createView 訊息,然后通過Bridge發到Shadow Thread,Shadow Tread接收到這條資訊后,先反序列化,形成Shadow tree,再轉換原生布局資訊,傳給UI thread,
而UI thread 拿到訊息后,同樣先反序列化,然后根據所給布局資訊,進行繪制,
而這一系列都強依賴于 bridge,像高度計算、UI更新每次的操作都通過 bridge傳遞,任務一多,就會生成任務佇列,異步操作批量處理,一些前端的更新很難及時反應到 UI 上,特別是類似于更新頻率較高的影片操作,任務較多,很難保證每一幀及時渲染,
那么,優化的方向:
1.減少 JS Thread 和 UI Thread 之間的異步通信,或者減少較少JSON的大小
2.盡量減少 JS Thread 側的計算

5.解決問題

整體解決方案是face-api替代tracker;React Native做一下調優,下面主要分三步講下React Native調優,

1.開啟影片原生驅動

useNativeDrive: true
JS Thread 和 UI Thread 之間是通過 JSON 字串傳遞訊息的,對于一些非布局的屬性、直接事件,(useNativeDriver 這個屬性只能使用到只有非布局相關的影片屬性上,例如 transform 和 opacity,布局相關的屬性,比如說 height 和 position 相關的屬性,開啟后會報錯,)比如人臉識別成功,人員資訊卡片影片,我們可以使用 useNativeDrive: true 開啟原生影片驅動,

Animated.timing(this.state.animatedValue, { toValue: 1, duration: 500, useNativeDriver: true, // <-- Add this }).start();  

通過啟用原生驅動,我們在啟動影片前就把其所有配置資訊都發送到原生端,利用原生代碼在 UI 執行緒執行影片,而不用每一幀都在兩端間來回溝通,如此一來,影片一開始就完全脫離了 JS 執行緒,因此此時即便 JS 執行緒被卡住,也不會影響到影片了,

2.使用互動管理器 InteractionManager

使用InteractionManager將部分需要優化的任務在互動操作和影片完成之后再執行,比如:會場分布的跳轉影片,目的是平衡復雜任務和互動影片之間的執行時機,

const handle = InteractionManager.createInteractionHandle();// 執行影片... (`runAfterInteractions`中的任務現在開始排隊等候)// 在影片完成之后開始清除句柄:InteractionManager.clearInteractionHandle(handle);// 在所有句柄都清除之后,現在開始依序執行佇列中的任務  

根據官方解釋的解釋:runAfterInteractions接受一個回呼函式,或是一個PromiseTask物件,該物件回傳一個Promise,如果提供的引數是一個PromiseTask, 那么即便是異步的它也會阻塞任務佇列,直到它執行完畢后,才會執行下一個任務,這樣就可以按需優化影片流暢度,

3.重新渲染

首先,RN與React中,當父組件中觸發setState, 未修改任何state中的值也會引起所有子組件的重新渲染, 或者當父組件傳給子組件的props發生改變, 不管該props是否被子組件用到, 也都會去重新渲染子組件,
那么,針對重新渲染問題,使用PureComponent和shouldComponentUpdate對于普通函式進行優化;對于hook組件使用memo優化;
至驗證后整體得到改善,互動較為流暢,達到基本性能指標,現在主要是針對于概率性問題是否復現,尋求測驗同事的幫助,

6.驗證問題(性能監控平臺的應用)

首先為什么要使用性能監控平臺:1.處理重復資訊,避免一些問題在多個APP上重復處理,或者在一個APP上反復處理;2持續捕捉重要可疑資訊,提升效率,降低人力成本,
其次什么時候、什么場景下使用性能監控平臺:除了測驗、運維需要使用性能監控平臺,開發者也要學會利用性能監控平臺去輔助定位解決問題,這里推薦兩個方案:

1.Google Android Vitals + Firebase

Android vitals是Google為提高Android設備穩定性和性能而推出的一項計劃, Google Play 的Android vitals控制臺可以突出顯示崩潰率、ANR 發生率、喚醒次數過多以及喚醒鎖定被卡住等指標,包含了開發者常用功能,關鍵是不侵入代碼,應用比較方便,
而Firebase除此之外還可以獲取詳細的自定義崩潰報告資料,以了解應用中出現的崩潰情況,該工具會按相似堆疊軌跡將崩潰分門別類,并根據崩潰對用戶所產生影響的嚴重程度進行分級,除了接收自動生成的報告外,還可以通過記錄自定義事件來獲知導致應用崩潰的操作,
在這里插入圖片描述

在這里插入圖片描述

Vitals + Firebase功能對比圖(圖片來源官網)

所以一般情況下使用Android Vitals可處理大部分簡單問題,并可搭配Firebase靈活處理自定義事件,
不太方便的是Google國內限制,需要公司申請專線跨境聯網,并且網路波動時,經常需要身份驗證(這點比較煩人),
費用上:Android Vitals使用免費,但是需要25$注冊開發者賬號;Firebase有免費版和付費版,適合外企、跨國公司或者有相關資質的公司研發使用,

2.友盟+ U-APM

2.1產品概述:

由于Google國內限制,很多企業沒有網路報備不能連接外網,那么友盟+ 的U-APM也可以完美滿足以上需求,針對于我的專案,我這里是選擇接入友盟+SDK協助問題檢測,
友盟的推送和統計在業界做的是比較好的,而比較熟悉友盟的朋友應該了解U-APP的穩定性功能,那么U-APM就是友盟+在U-APP穩定性功能的基礎上升級推出的一款面向開發者監控應用的穩定性資料產品,

在這里插入圖片描述

為什么選擇友盟+ U-APM 應用性能監控平臺:
該產品不僅通過發現線上問題-快速定位問題-高效解決問題打造體系化線上質量監控平臺,而且擁有支持實時監控線上App崩潰趨勢,7*24小時監控告警與修復驗證,復現用戶崩潰現場,關鍵環節的重點監控,修復測驗等特點,

重點還在于有阿里技術的加持,可以提供長期穩定的產品迭代和專案服務及專家咨詢能力,貼心啊,企業工程化需要的就是長期穩定!小廠的產品可能用著用著就找不到人了,

在這里插入圖片描述

2.2開發準備

如果之前有使用過U-APP的,可以直接查看官網的升級說明按體驗U-APM;那么沒有使用過友盟產品的需要到 【友盟+】官網.
注冊并且添加新應用,獲得AppKey,
注:請一定認真閱讀U-APM合規指南,滿足工信部相關合規要求,避免因隱私政策風險導致APP下架,

2.3集成SDK

maven自動集成:
maven自動集成是比較簡單快速的
首先在工程build.gradle配置腳本中buildscript和allprojects段中添加【友盟+】sdk 新maven倉庫地址,如下圖,

在這里插入圖片描述
在這里插入圖片描述

然后在工程App 對應build.gradle配置腳本dependencies段中添加SDK庫依賴,是不是很簡單呢,

dependencies {  
    implementation fileTree(include:['*.jar'], dir:'libs')  
  
// 下面各SDK根據宿主App是否使用相關業務按需引入,  
    implementation  'com.umeng.umsdk:common:9.4.4'// 必選  
    implementation  'com.umeng.umsdk:asms:1.4.1'// 必選  
    implementation 'com.umeng.umsdk:apm:1.4.2' // 必選  
}  

手動Android Studio集成:
那么我這里是采用的手動集成
1.首先在選擇U-APM SDK組件并下載,解壓.zip檔案得到相應組件包
在這里插入圖片描述

得到如下檔案:
在這里插入圖片描述

umeng-common-9.4.4.jar // 統計SDK 必選
umeng-asms-armeabi-v1.4.1.aar // 必選
以及apm目錄下的
umeng-apm-armeabi-v1.4.2.aar//U-APM SDK 必選
可如有UTDID需求,集成thirdparties下
utdid4all-1.5.2.1-proguard.jar UTDID服務的補充包
如需要ABTest模塊,可集成common下
umeng-abtest-v1.0.0.aar ABTest模塊
2.在Android Studio的專案工程libs目錄中拷入以上jar包,
右鍵Android Studio的專案工程 —> 選擇Open Module Settings —> 在 Project Structure彈出框中 —> 選擇 Dependencies選項卡 —> 點擊左下“+” —> 選擇組件包型別 —> 引入相應的組件包,

3在app的build.gradle檔案中引入相應的組件包,參考示例如下:

repositories{  
    flatDir{  
        dirs 'libs'  
}  
}  
dependencies {  
    implementation fileTree(include:['*.jar'], dir:'libs')  
    implementation (name:'umeng-asms-armeabi-v1.4.1', ext:'aar')   
    implementation (name:'umeng-apm-armeabi-v1.4.2', ext:'aar')  
}  

注意:如果需要適配armeabi 以外的平臺,或者遇到了多CPU架構so庫加載失敗問題[SA10070],除了需要引入相應的包,還要分別下載并考入對應的.so檔案,

2.4權限授予

按照官網教程授予如下權限:
在這里插入圖片描述

<manifest ……>  
<uses-sdkandroid:minSdkVersion="8"></uses-sdk>  
<uses-permissionandroid:name="android.permission.ACCESS_NETWORK_STATE"/>  
<uses-permissionandroid:name="android.permission.ACCESS_WIFI_STATE"/>  
<uses-permissionandroid:name="android.permission.READ_PHONE_STATE"/>  
<uses-permissionandroid:name="android.permission.INTERNET"/>  
<application ……>  

2.5混淆設定

如果APP中使用了代碼混淆,需要增加如下配置

-keep class com.umeng.** { *; }  
  
-keep class com.uc.** { *; }  
  
-keep class com.efs.** { *; }  
  
-keepclassmembers class *{  
     public<init>(org.json.JSONObject);  
}  
-keepclassmembers enum *{  
      publicstatic**[] values();  
      publicstatic** valueOf(java.lang.String);  
}  

2.6初始化sdk

在rn的安卓原生的application.onCreate函式中呼叫基礎組件包提供的初始化函式:

/** 
* 注意: 即使您已經在AndroidManifest.xml中配置過appkey和channel值,也需要在App代碼中調 
* 用初始化介面(如需要使用AndroidManifest.xml中配置好的appkey和channel值, 
* UMConfigure.init呼叫中appkey和channel引數請置為null), 
*/  
UMConfigure.init(Context context,String appkey,String channel,int deviceType,String pushSecret);  

或者呼叫此預初始化函式

public static void preInit(Context context,String appkey,String channel)  
然后打開日志開關
** 
*設定組件化的Log開關 
*引數: boolean 默認為false,如需查看LOG設定為true 
*/  
UMConfigure.setLogEnabled(true);  

至此即可使用卡頓分析功能、Java、Native崩潰分析、ANR分析功能等等基礎功能了,因為其原理通過主執行緒的回應時間,將有卡頓體驗的設備資訊、卡頓日志進行上報,那么等待設備上報后我們可以在web控制臺看到上傳的Error(列印SDK集成或運行時錯誤資訊),Warn(列印SDK警告資訊),Info(列印SDK提示資訊),Debug(列印SDK除錯資訊),以及報表,
在這里插入圖片描述

但是從報文直接看錯誤堆疊非常麻煩, U-APM利用聚合演算法提供了卡頓模塊的功能,篩選影響用戶量大的200個堆疊從堆疊頂到堆疊底雙向聚合,展示出現頻率前10的模塊,子樹深度最多支持50層,幫助下挖詳細的卡頓模塊資訊,
在這里插入圖片描述
除此之外,U-APM中還提供了啟動分析、記憶體分析、網路分析,用戶細查模塊等高級功能,除了記憶體分析外是其他功能需要進行配置才能使用的,大家可以去體驗一下,
那么最終通過U-APM也是順利的驗證問題、解決問題,完成了整個研發倍訓,感興趣的話,可以免費體驗U-APM.

三.專案總結

1.不要盯著問題看,對于app的性能優化也好,系統優化也好,問題的表象可能是由于本質的副作用帶來的,例如,本專案中區域現象是卡頓、不流暢,只盯著現象,我們很可能陷入優化困境,去優化渲染、減少canvas繪圖,甚至精簡業務,而最終突破我們的性能瓶頸是通過修改實作方式達成的,更適合業務場景、更能發揮機器性能,而這一切,需要資料支撐
2. 用資料說話,不要憑感覺,去檢測性能問題、評估性能優化的效果,要有可量化的渲染性能評判標準,以及可量化、可視化的優化工具,利用經驗去感覺、猜測對于團隊是沒有沉淀的,而資料和工具是可以傳承的,例如:對于優化性能如果沒有標準,對于結果沒有資料體現,那么整體的作業是沒有意義的,成功與否全靠leader拍腦門決定,
3.使用低配置的設備:同樣的程式,在低端配置的設備中,相同的問題會暴露得更為明顯,例如:在前期安卓開發真機上并沒有卡頓現象,放在工業真機上才暴露出卡頓等問題,而對于高低端設備都能帶來很好的用戶體驗,一直是一個很重要的問題,
4.權衡利弊:在能夠保證產品穩定、按時完成需求的前提下去做優化,投入產出比過高時,應采取其他方案,切勿過度優化,永遠不要忘記,優化性能的目的是提高用戶體驗,而不是炫技
5.拋棄沉沒成本:對于研發中已經付出且不可識訓的成本,不要影響未來的決策,例如:對于已經使用track開發的人臉識別模塊,資料證明選型影響到了性能,投入產出比在可接受范圍內,越早替換預期收益越高,

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/337761.html

標籤:其他

上一篇:.NET 基金會,你是為開源而生,還是在為微軟服務?

下一篇:20年前iPod改變了世界,20年后它變成了懷舊機器

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more