模塊怎么用_Android 組件化/模塊化 的理解!

aaf77f99bedaa2e74f9e294e6361b8eb.gif

作者:前行的烏龜

到現在組件化真的不是什么新鮮東西了,大公司都用的滾瓜爛熟,龍飛鳳舞了,也就是現在部分中型項目和小項目在組件化的路上努力。所以同志們,組件化沒玩過的,不熟悉的趕緊搞起來,說一點,你不會組件化,發布影子工程那么對你來說就是個噩夢。從本質上來講任何技術進步都是在現實需求的逼迫下抓耳撓腮,耗盡無數頭發才想出來的。哈哈,這里說個笑話罷了。所以呢組件化這個東西出來這么久了,頁發展了這么久了,用的人越來越多,那肯定是對我們顯示開發大有裨益的,下伙伴們不會,不熟悉抓緊啦,要不面試問你你怎么回答呢!

下面來正式說說組件化

組件化這個東西其實并不復雜,他就是種思路,本質上是一種 app 架構思路,說穿了很簡單的,難在組件化改造的時候,真正寫起代碼會出現不少棘手的問題,當然這些坑基本前人都趟完了,這里我主要是記錄下,要是你看到熟悉的部分,請不要罵我啊,畢竟都是前輩們的東西啊。

這里補充一下,組件化是一種 app 架構,他的發展也是沿著正常的技術發展脈絡來的,也是為了以追求高復用,高可維護性的目的的代碼封裝,區別是組件化是對整個 app 的再次封裝。

廢話了這么多,那么什么是組件化呢,各位看官想不要著急,在詳細說組件化之前,我們要搞懂2個概念,就是上面說的組件和模塊。

首先組件和模塊都不是官方規定的,都是這些技術發展下來大家約定俗成的概念,其實很簡單,一說就明白

  • 模塊:android 中的模塊就是業務模塊,單指業務,是按照業務對 app 進行拆分,比如說訂單我們搞成一個模塊,個人中心我們搞成一個模塊,視頻,音頻這些都搞成模塊,在app中的體現就是 一個個module,module 的中文意思也是模塊,這不準這就是 google 對我們的暗示呢。模塊化的目的是為了搭積木,隨便拿幾個模塊module 出來就可以誰誰便便的上線一個 app,你還別說現在影子 app 的需求很旺盛,你去看看大公司的項目那個不是一堆影子工程,頭條還搞出一個頭條視頻的馬甲呢,這其實就是把視頻 module 拿出來,加上一個啟動頁。這樣的例子是比比皆是的,要不說不會組件化影子工程對你就是噩夢呢,哈哈,到時候維護那是想也別想了,代碼你要搞多少份啊。

  • 組件:這個一樣簡單啊,說穿了就是我們平時干的事,對功能的封裝,這就是組件,一個功能就是一個組件,IO,數據庫,網絡等等這些功能都是組件,這么說你就明白了吧。既然這樣那為毛線我們還要搞出來這個一個組件的概念,當然了任何事都是有其意義的,因為組件對功能代碼的封裝有個很高了明確的要求:一處封裝,處處使用。要我們把維護性,復用性,擴展性,性能做到極致,因為這樣才能真正做到一處封裝,處處使用。當然組件的范圍現在也是覆蓋的很廣的,app 中的一切都是組件,基本上我們分為:基礎功能組件,通用UI組件,基礎業務組件。

以上我談了下我自己對于模塊化,組件化的理解,是目前開發中對于模塊和組件的理解。在模塊化和組件化的發展中概念也是有些調整變化的,大家只要看現在是什么樣子就好了,深入學習的話有興趣可以看看組件化,模塊化的發展歷程。

我認為 Android 模塊化探索與實踐 對于模塊化,組件化概念的解釋是最優秀的。

組件化和模塊化在現在看是一回事了,如果把一個項目看成是袋中的組合的話,那么模塊就是體積最大的哪些袋子,組件就是體積小的袋子,大的袋子是最直接可被外接觀測和接觸的袋子,大的袋子也是用小的袋子組成的,一個不太恰當的比喻吧,模塊和組件就是這樣的關系,是我們對業務和功能拆分,封裝的理解。

好了正式開始介紹了組件化啦

組件化在工程表現上就是我們把 app 按照其業務的不同,劃分為不同的 module模塊,把各種功能封裝成一個個 library,module 之間是嚴格禁止橫向依賴的,要不怎么單獨使用呢,我不能為了用一個 module,把相關的module 都帶上吧,要是這么 module 還有依賴的module 呢,這樣談復用性就是扯淡了。

主 app 就是我們常說的殼工程依賴這些 module,library 由需求的 module 依賴,但是要考慮library 版本的問題,隨著業務和功能的擴展,library 的數量也是巨大的,微信在組件化拆分時據說拆分出80多個 module,可見 library 也是少不了的。

module 和 library 多數時候我們是提供arr 和 jar 來給殼工程引用的,arr 和 jar 在編譯時是不會再編譯的,只會檢查版本,保留一個最新的版本,既提高了 app 的編譯速度,也提供一種資源沖突解決方式。

下面我放一些圖來描述一下組件化,大伙仔細看看,圖比文字可生動多了

d123e65c8e44ac3c54778a30d4abb98d.png
e6991258d9698e978e161808815588cd.png
modules.png
3f4e79fddd25038c648cdf843040b750.png
ad2ed5e6e413a337d89a0aa6192fc496.png
8a122de8b6a1378d4fc462d7f5e58d4a.png

項目如何組件化:

08d035544513cb67da77dd4ca8075428.png
.
8ba95258fff4cd949dc1c2d3e427eb14.png
c55cf1463ea9e634d1d3253fbd7478d6.png

組件化核心:router

我們在抽象 module 時,module 之間是沒有相互依賴的,是嚴格解耦的,為了達到我們復用的目的。module 之間不能相互依賴,就沒法調用別的 module 的代碼了,那么面對業務之間的頁面相互調起,相互通信這些常見的需求我們該怎么辦,沒錯就是大伙在上面的圖里面看見的東西 router。

router 是我們統一制定的模塊間通訊協議,router 中我們主要是處理以下幾個問題:

模塊之間頁面跳轉
模塊之間數據傳遞
模塊初始化處理

41a1381e60689ca035c47bb033bc63f1.png
router.png

router 這東西有現成的,你也可以自己封裝。使用的思路都是把 router 作為一個組件,所有的業務 module 都依賴這個 router 組件,當然殼app 也是,然后我們把需要的模塊間頁面跳轉,數據傳遞,初始化都注冊到 router 中,這里面就體現到我們定義的統一,通用的模塊通訊協議的重要性了,router 維護多個集合保存這里關系,然后我們通過router 就可以實現模塊間的通訊了。

router 的封裝還是挺麻煩的,要寫好了不容易,現在用的比較多的有:

  • 阿里的 ARouter

  • 最早出現的 ActivityRouter

  • spiny同學的router這是我的最愛,目前不維護了,思路很棒,并且考慮到了進程化的問題,可惜沒有使用 APT 注解技術

  • 練手的 router

上面我介紹了幾個 router 路由,基本上不論是自己寫還是用現成的,router 基本上都是上面這幾個的樣子了,當然了現在好的 router 還是要使用 APT注解技術來動態去 router 注冊模塊方法,自己寫代碼去注冊的話使用很使用,有些問題不好處理,比如 router 的靜態實例要是被回收了,你再 new 一個出來,那么模塊注冊的方法怎么辦,寫起來太麻煩,還不如 APT 注解來的方便,擴展性也好。這里有個ToyBricks_Android項目模塊化解決方案 可以解決 APT不能掃描 arr 包的問題。

最后說一下,module 間的通訊其實可以分成3種:

  • 頁面調起

  • 某種事件的通知

  • 直接調用某些模塊的業務方法

頁面調起現在的 router 都可以很好的完成這個任務。

某些事件的通知,比如我切換城市了,通知某些頁面去顯示或是刷新數據,這個根據業務來說影響的范圍會很廣的,會影響多個業務的,因為 module 的復用性,我們在 module 中是不能確定會具體影響哪些業務module 的,那么這種場景使用 eventbus/廣播比較合適了。

直接調用默寫模塊的業務方法,這屬性業務模塊間在業務上的強耦合了,這個碰到產品這么設計你也沒辦法,一般碰到這樣的場景也是會保證相關的業務module 都是會加載的,所以呢在定義 router 靈活一些,可以做到調用指定module 的某些方法

找到另一個說法,我很喜歡,和我的理念也很接近
出自:Android 架構設計:MVC、MVP、MVVM和組件化

所謂的組件化,通俗理解就是將一個工程分成各個模塊,各個模塊之間相互解耦,可以獨立開發并編譯成一個獨立的 APP 進行調試,然后又可以將各個模塊組合起來整體構成一個完整的 APP。它的好處是當工程比較大的時候,便于各個開發者之間分工協作、同步開發;被分割出來的模塊又可以在項目之間共享,從而達到復用的目的。組件化有諸多好處,尤其適用于比較大型的項目。

各個模塊之間如何進行數據共享和數據通信?我們可以把需要共享的數據劃分成一個單獨的模塊來放置公共數據。各個模塊之間的數據通信,我們可以使用阿里的 ARouter 進行頁面的跳轉,使用封裝之后的 RxJava 作為 EventBus 進行全局的數據通信。

router 我不想說太多,也說不好,這部分大伙看我最后的鏈接吧,或是看看上面4個路由也可以,不論如何實現,router 是為了給 module 模塊搭建一個通訊的中間平臺,目的就是這樣。仔細的大家多看吧,這里我也是看別人的。

我再逼逼一下,module 和 library 我們盡量不要提供源代碼的方式提供依賴,這不符合我們復用的目的,到時候你發布幾個影子功能或是別的 app,那么你使用源代碼依賴方式的 module 和 library 你怎么提供維護,所以盡量使用 arr 和 jar 的方式。我們可以把一些定位相近library 打包成一個 module 也是不錯的。

我們一定要熟悉gradle的使用,在組件化中我們會大量的使用 gradle 提供各種資源加載的配置和環境配置

組件化最核心的目的就是代碼的高可復用和高可維護和高可擴展性能,其他的優點都是屬于連帶性質的,我們要先把握住核心點學習,其他的都不是主要,有時間再看

組件化碰到的問題

1. 子模塊單獨編譯測試

在做組件化開發時,我們測試 module 庫都是把 module 單獨達成 apk 文件,在發布module時 提供 library 供外界依賴,這都是通過配置 module 的 gradle 的編譯模式實現的

首先在子模塊build.gradle中定義常量,來標示模塊目前是否處于開發模式

def isDebug = true
在子模塊的build.gradle中進行模式配置。debug模式下編譯成獨立app,release模式下編譯成library。

1if?(isDebug.toBoolean())?{
2????apply?plugin:?'com.android.application'
3}?else?{
4????apply?plugin:?'com.android.library'
5}

兩種模式下模塊AndroidManifest.xml文件是有差別的。作為獨立運行的app,有自己的Application,要加Launcher的入口intent,作為library不需要。這個問題很好解決,寫兩個不同的AndroidManifest.xml即可,并在gradle中進行配置。

a53d48f582a37096017aafe80039bf09.png

在 gradle 腳本中配置

 1android?{
2????sourceSets?{
3????????main?{
4????????????if(isDebug.toBoolean())?{
5????????????????manifest.srcFile?'src/debug/AndroidManifest.xml'
6????????????}?else?{
7????????????????manifest.srcFile?'src/release/AndroidManifest.xml'
8????????????}
9????????}
10????}
11}

2. sdk和第三方庫的版本一致性

不同module依賴sdk版本不一致,會因兼容性問題導致編譯問題。
不同module引用了同一個第三方庫的不同版本,并且這個庫沒有做到向前兼容,就有可能出現方法找不到、參數不對應等問題。
所以有必要統一整個project的依賴版本。

在最外層build.gradle中定義的常量能被整個project的build.gradle文件引用,統一的版本定義可以放在這里。

 1ext?{
2????android_compileSdkVersion?=?25
3????android_buildToolsVersion?=?'25.0.2'
4????android_minSdkVersion?=?21
5????android_targetSdkVersion?=?25
6
7????lib_appcompat?=?'com.android.support:appcompat-v7:25.1.1'
8????lib_picasso?=?'com.squareup.picasso:picasso:2.5.2'
9????lib_gson?=?'com.google.code.gson:gson:2.6.1'
10}

我沒試過 arr資源的 module 是否還可以使用這種方式

3. 資源id沖突

android 中 module的資源文件最后都是會合并到主項目中的,資源文件的 id 最終和 moudle 是的 id 是不一樣的,所以這就會出現資源重名的問題,解決這個問題,我們的做法就是module 資源加一個統一的前綴

 1andorid{
2????...
3
4????buildTypes{
5????????...
6????}
7
8????resourcePrefix?"moudle_prefix"
9
10}

但是注意 res 文件夾下的文件可以用 gradle 腳本加前綴,但是圖片資源不行,圖片資源我們還是需要在命名時自己添加前綴

4. application初始化的問題

子模塊作為application時,有一些初始化的工作需要在Application.onCreate時進行。而作為library時,調不到這個onCreate。所以自己寫一個靜態方法,供主工程的Application調用。

 1public?class?ApplicationA?extends?Application?{
2
3@Override?public?void?onCreate()?{
4??super.onCreate();
5??//給底層library設置context
6??AppContext.init(getApplicationContext());
7}
8??/** 9???*?作為library時需要初始化的內容10???*/
11??public?static?void?onCreateAsLibrary()?{
12????//給FunctionBus傳入接口的實例
13????FunctionBus.setFunction(new?FunctionA()?{
14??????@Override?public?String?getData(String?key)?{
15????????return?"xixi";
16??????}
17????});
18??}
19}

主工程的Application onCreate時記得初始化子模塊。

1public?class?MainApplication?extends?Application?{
2
3??@Override?public?void?onCreate()?{
4????super.onCreate();
5????AppContext.init(getApplicationContext());
6????ApplicationA.onCreateAsLibrary();
7????ApplicationB.onCreateAsLibrary();
8??}
9}

除了提供方法在殼工程里面調用,還可以結合使用了 APT 技術的 router 來做,使用注解,就不用我們自己去調用了,徹底解耦

5. library依賴問題

先說一個問題,在組件化工程模型圖中,多媒體組件和Common組件都依賴了日志組件,而A業務組件有同時依賴了多媒體組件和Common組件,這時候就會有人問,你這樣搞豈不是日志組件要被重復依賴了,而且Common組件也被每一個業務組件依賴了,這樣不出問題嗎?

其實大家完全沒有必要擔心這個問題,如果真有重復依賴的問題,在你編譯打包的時候就會報錯,如果你還是不相信的話可以反編譯下最后打包出來的APP,看看里面的代碼你就知道了。組件只是我們在代碼開發階段中為了方便叫的一個術語,在組件被打包進APP的時候是沒有這個概念的,這些組件最后都會被打包成arr包,然后被app殼工程所依賴,在構建APP的過程中Gradle會自動將重復的arr包排除,APP中也就不會存在相同的代碼了;

但是雖然組件是不會重復了,但是我們還是要考慮另一個情況,我們在build.gradle中compile的第三方庫,例如AndroidSupport庫經常會被一些開源的控件所依賴,而我們自己一定也會compile AndroidSupport庫 ,這就會造成第三方包和我們自己的包存在重復加載,解決辦法就是找出那個多出來的庫,并將多出來的庫給排除掉,而且Gradle也是支持這樣做的,分別有兩種方式:根據組件名排除或者根據包名排除,下面以排除support-v4庫為例:

1dependencies?{
2????compile?fileTree(dir:?'libs',?include:?['*.jar'])3????compile("com.jude:easyrecyclerview:$rootProject.easyRecyclerVersion")?{
4????????exlude?module:?'support-v4'//根據組件名排除
5????????exlude?group:?'android.support.v4'//根據包名排除
6????}
7}

library重復依賴的問題算是都解決了,但是我們在開發項目的時候會依賴很多開源庫,而這些庫每個組件都需要用到,要是每個組件都去依賴一遍也是很麻煩的,尤其是給這些庫升級的時候,為了方便我們統一管理第三方庫,我們將給給整個工程提供統一的依賴第三方庫的入口,前面介紹的Common庫的作用之一就是統一依賴開源庫,因為其他業務組件都依賴了Common庫,所以這些業務組件也就間接依賴了Common所依賴的開源庫。

 1dependencies?{
2????compile?fileTree(dir:?'libs',?include:?['*.jar']) 3????//Android?Support 4????compile?"com.android.support:appcompat-v7:$rootProject.supportLibraryVersion" 5????compile?"com.android.support:design:$rootProject.supportLibraryVersion" 6????compile?"com.android.support:percent:$rootProject.supportLibraryVersion" 7????//網絡請求相關 8????compile?"com.squareup.retrofit2:retrofit:$rootProject.retrofitVersion" 9????compile?"com.squareup.retrofit2:retrofit-mock:$rootProject.retrofitVersion"10????compile?"com.github.franmontiel:PersistentCookieJar:$rootProject.cookieVersion"11????//穩定的12????compile?"com.github.bumptech.glide:glide:$rootProject.glideVersion"13????compile?"com.orhanobut:logger:$rootProject.loggerVersion"14????compile?"org.greenrobot:eventbus:$rootProject.eventbusVersion"15????compile?"com.google.code.gson:gson:$rootProject.gsonVersion"16????compile?"com.github.chrisbanes:PhotoView:$rootProject.photoViewVersion"1718????compile?"com.jude:easyrecyclerview:$rootProject.easyRecyclerVersion"19????compile?"com.github.GrenderG:Toasty:$rootProject.toastyVersion"2021????//router22????compile?"com.github.mzule.activityrouter:activityrouter:$rootProject.routerVersion"23}24

6. module不同業務環境使用不同代碼

我們做項目至少會有測試和線上2套環境吧,組件化讓我們開始重視 gradle,通過 gradle 配置我們可以減少很多代碼的書寫的,切換環境我們也是可以用 gradle 實現的,在不通過的環境下注冊不同的代碼文件,看下面這張圖

bca2480981366e22ce4d002db92dff2d.png

我們有 debug 和 release2個環境,里面放的是不同環境執行的代碼,main 里面是跟環境切換無關的代碼部分,我我們這樣設置 gradle 就可以了

 1android?{
2????//?...
3????sourceSets?{
4????????debug?{
5????????????java.srcDirs?=?['src/main/java',?'src/debug/java']
6????????}
7????????release?{
8????????????java.srcDirs?=?['src/main/java',?'src/release/java']
9????????}
10????}
11}

此外在發布該 library 時,需要指定一些設置,如下:

1android?{
2????//?...
3????defaultConfig?{
4????????//?...
5????????defaultPublishConfig?'release'
6????????publishNonDefault?true
7????}
8}

說明:

  • defaultPublishConfig 'release',默認 library 只會生產 release 下的版本,此版本將會被所有項目使用,通過defaultPublishConfig可以控制默認生產哪個版本的庫。

  • publishNonDefault true,默認情況下不能生產所有版本的 library,通過設置publishNonDefault為true,可以同時生產所有版本的 library。
    業務組件 module 依賴不同的基礎組件生產的 library,如下:

1dependencies?{
2????//?...
3????debugCompile?project(path:?':baselibrary',?configuration:?"debug")4????releaseCompile?project(path:?':baselibrary',?configuration:?"release")5}6

在使用通過這樣的配置腳本解決了多個 APK 包依賴同一組件生產的不同的 library,最終得到我們需要的開發/測試/生產 APK 包。

合并多個 module 到一個文件夾

studio 中的 module 我們在引用時都是用,項目名 + :冒號來表示的

1implementation?project(':basecomponents')2

注意這只是表示我們要引用這個名字的 module 了,而這個 module 的地址這里我們不管

那么就可以理解為 module 的地址可以隨我們任意配置,那么在哪里配置 module 的地址呢,答案就是在 setting.gradle 文件里,我們給 ':basecomponents' 這個 module 指定他的地址就行

比如我們想新建一個名字為 components 的文件夾存放我們的組件 module ,組件我們給2個 ( basecomponents,aaa ),然后我們在 setting.gradle 里指定每個項目的文件路徑

1include?':app',?':basecomponents',?':aaa'
2
3project(':basecomponents').projectDir?=?new?File(?'components/basecomponents'?)
4project(':aaa').projectDir?=?new?File(?'components/aaa'?)
16b847c2af2c609955e64487b80ad85b.png

一個好的組件化文檔是必須的

組件化是 android 開發步入新時代的未來,是代碼膨脹,支持快速開發的必然,一個好的組件化文檔在現今來看也是必須的了

下面貼個圖

089256017f6835b0cc84ec7dae3aef48.png
474fb5d9248418157ce338ceba759e51.png

組件化的坑

組件化是好,但是坑也是不少,不好填,尤其是 databinding,dagger,bufferkinft,這是源于 studio 編譯的問題。

studio 中 module 雖然是在代碼上獨立于殼工程的,但是在編譯時最后還是要合并到殼工程中的,要不怎么達成一個 APK 文件,要是多個 APK 文件把不成了插件化了嘛,插件化坑更多啊。合并 module 到殼工程就會產生一個根本問題,module 的 R 文件數值改變了。module 的 R文件數據不是固定的,只有殼工程的 R 文件才是常量值,時不變的,module 的 R 文件數值在把 modul 的資源合并到殼工程后才會確定下來,那么這就對依靠編譯時注解的技術造成了難題,你指定的 R 路徑最后找不到,并且據說這里面還涉及注解的 final ,不了解,看到有人這么說,所以大家在開發組件化時對于帶注解技術的框架要多注意,有坑要多看才能爬過去

組件化文章:
Android 模塊化探索與實踐 安居客的時間案例,對概念的解釋非常到位,適合初學者和概念混亂的同學看,特別是有提供詳細的 demo 哦

關于Android模塊化我有一些話不知當講不 這是我目前看到的最貼近實際的好文了,絕對值得一看的

Android組件化方案

https://blog.csdn.net/guiying712/article/details/55213884

這篇文章講的最好,還設計大量 gradle 配置的思考

android開發:由模塊化到組件化

https://blog.csdn.net/dd864140130/article/details/53645290)

優秀的組件化方案:

Android徹底組件化方案實踐

https://www.jianshu.com/p/1b1d77f58e84

Android徹底組件化demo發布

https://www.jianshu.com/p/59822a7b2fad

---END---

推薦閱讀:
2020年10月編程語言排行榜:C語言登頂,Java下滑~
“終于懂了” 系列:Android屏幕刷新機制—VSync、Choreographer 全面理解!
25歲程序員 VS 35歲程序員,你中了幾條?!
有同學這么設置Intellij IDEA,據說效率還不錯~
細數 2020 年官方對 Android 的那些重大更新!
Android Debug 調試原理!
再見!onActivityResult!你好,Activity Results API!
面試官邪魅一笑: 你說說 Java8 的 ConcurrentHashMap ?

597f50ffa80987409ffcd0197836d3d8.png

更文不易,點個“在看”支持一下?

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

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

相關文章

操作系統基礎

操作系統基礎一個完整的操作系統包括 ( kernel application)內核 應用程序而我們要學習操作系統:Linux操作系統我們平時所用的WINDOWS和MS-DOS都是微軟出的,而Linux不是微軟出的,Linux的最大好處是非商業軟件&#x…

leetcode1247. 交換字符使得字符串相同(貪心)

有兩個長度相同的字符串 s1 和 s2,且它們其中 只含有 字符 “x” 和 “y”,你需要通過「交換字符」的方式使這兩個字符串相同。 每次「交換字符」的時候,你都可以在兩個字符串中各選一個字符進行交換。 交換只能發生在兩個不同的字符串之間…

interop_如何在Blazor中實現JavaScript Interop

interop介紹 (Introduction) In this article, we will learn about JavaScript Interop in Blazor. We will understand what JavaScript Interop is and how we can implement it in Blazor with the help of a sample application.在本文中,我們將學習Blazor中Ja…

Centos 7和 Centos 6開放查看端口 防火墻關閉打開

Centos 7 firewall 命令: 查看已經開放的端口: firewall-cmd --list-ports 開啟端口 firewall-cmd --zonepublic --add-port80/tcp --permanent 命令含義: –zone #作用域 –add-port80/tcp #添加端口,格式為:端口/通訊…

和get redis_SpringBoot整合Redis,你get了嗎?

Our-task介紹本篇博客是我github上our-task:一個完整的清單管理系統的配套教程文檔,這是SpringBootVue開發的前后端分離清單管理工具,仿滴答清單。目前已部署在阿里云ECS上,可進行在線預覽,隨意使用(附詳細…

linux課程設計qq,仿QQ聊天系統課程設計.doc

目錄緒論1一.需求分析11.1軟件功能需求分析21.2 安全需求分析2二.總體設計32.1 軟件結構圖32.2 功能描述32.2.1注冊功能概要42.2.2登錄功能概要42.2.3聊天功能概要52.3 安全設計6三.數據庫設計63.1概念結構設計63.2邏輯結構設計73.3物理結構設…

ocp linux 基礎要點

基本命令: 創建/修改/刪除用戶 useradd/usermod/userdel 創建/修改/刪除用戶組 groupadd/groupmod/groupdel 修改所屬用戶/所屬用戶組 chown/chgrp 修改權限 chmod 創建文件夾 mkdir 創建文件 touch 切換目錄 …

leetcode1386. 安排電影院座位(貪心)

如上圖所示,電影院的觀影廳中有 n 行座位,行編號從 1 到 n ,且每一行內總共有 10 個座位,列編號從 1 到 10 。 給你數組 reservedSeats ,包含所有已經被預約了的座位。比如說,researvedSeats[i][3,8] &…

首席技術執行官_如何在幾分鐘內找到任何首席執行官的電子郵件地址

首席技術執行官by Theo Strauss由西奧斯特勞斯(Theo Strauss) 如何在幾分鐘內找到任何首席執行官的電子郵件地址 (How to find any CEO’s email address in minutes) 銀河電子郵件指南:第一部分 (The Emailer’s Guide To The Galaxy: Part I) I’m 17, so my net…

Linux 查看磁盤或文件夾及文件大小

當磁盤大小超過標準時會有報警提示,這時如果掌握df和du命令是非常明智的選擇。 df可以查看一級文件夾大小、使用比例、檔案系統及其掛入點,但對文件卻無能為力。 du可以查看文件及文件夾的大小。 兩者配合使用,非常有效。比如用df查看哪個…

Python列表基礎

列表:創建列表:list[] 注意:列表里面類型可以是不同的類型 取值:list[2]   替換:注意不要越界(下表超出了可表示范圍) 操作: 合并列表:   list3list2list1 列表的重復:   (list8*3)   判斷元素是否…

樹莓派 觸摸屏_如何用樹莓派搭建一個顆粒物(PM2.5)傳感器

用樹莓派、一個廉價的傳感器和一個便宜的屏幕監測空氣質量。-- Stephan Tetzel(作者)大約一年前,我寫了一篇關于如何使用樹莓派和廉價傳感器測量 空氣質量 的文章。我們這幾年已在學校里和私下使用了這個項目。然而它有一個缺點:由于它基于無線/有線網&a…

shell 25個常用命令

1.列出所有目錄使用量,并按大小排序。 ls|xargs du -h|sort -rn #不遞歸下級目錄使用du -sh2.查看文件排除以#開關和空白行,適合查看配置文件。 egrep -v "^#|^$" filenamesed /#.*$/d; /^ *$/d3.刪除空格和空行。 sed /^$/d filename #刪除空…

tensorflow入門_TensorFlow法律和統計入門

tensorflow入門by Daniel Deutsch由Daniel Deutsch TensorFlow法律和統計入門 (Get started with TensorFlow on law and statistics) What this is about 這是關于什么的 What we will use 我們將使用什么 Get started 開始吧 Shell commands for installing everything you …

centos7 nginx+php5.6+mysql安裝與配置

安裝與配置 php 56的安裝 php的配置寫在 php.ini,可在phpinfo()中查看 //查找已安裝 yum list installed | grep php // php卸載 yum -y remove php56* yum remove httpd* php* 可用的資源:centos 安裝php56nginx nginx php-fpm nginx安裝 sudo rpm -Uv…

leetcode337. 打家劫舍 III(dfs)

在上次打劫完一條街道之后和一圈房屋后,小偷又發現了一個新的可行竊的地區。這個地區只有一個入口,我們稱之為“根”。 除了“根”之外,每棟房子有且只有一個“父“房子與之相連。一番偵察之后,聰明的小偷意識到“這個地方的所有房…

c語言面試題東軟,2012東軟筆試題

1、下列變量定義錯誤的是Dint a;double b4.5;boolean btrue;float f9.8; (9.8f)2、65%32的值是 D 3%53219103、對于一個三位的正整數 n,取出它的十位數字k(k為整型)的表達式是k n / 10 % 10k ( n - n / 100 * 100 )k n % 10k n / 104、下列語句序列執…

matlab肌電信號平滑濾波_MATLAB圖像處理:43:用高斯平滑濾波器處理圖像

本示例說明了如何使用imgaussfilt來對圖像應用不同的高斯平滑濾波器。高斯平滑濾波器通常用于降低噪聲。將圖像讀入工作區。I imread(cameraman.tif);使用各向同性的高斯平滑核增加標準偏差來過濾圖像。高斯濾波器通常是各向同性的,也就是說,它們在兩個…

Github 簡明教程 - 添加遠程庫

現在的情景是,你已經在本地創建了一個Git倉庫后,又想在GitHub創建一個Git倉庫,并且讓這兩個倉庫進行遠程同步,這樣,GitHub上的倉庫既可以作為備份,又可以讓其他人通過該倉庫來協作,真是一舉多得…

githooks_使用Githooks改善團隊的開發工作流程

githooksby Daniel Deutsch由Daniel Deutsch 使用Githooks改善團隊的開發工作流程 (Improve your team’s development workflow with Githooks) Every product that is developed by more than one programmer needs to have some guidelines to harmonize the workflow.由多…