@if 指令是在 @if 后跟一個表達式,然后再接 {} ,如果表達式為 true 則執(zhí)行 {} 里的代碼邏輯,寫為 @if { … } ,我們來舉例看下:@mixin avatar($size, $circle: false) { height: $size; @if $circle { width: $size / 2; }}.square { @include avatar(100px, $circle: true); }上面我們在 @mixin 中使用了 @if 指令,如果 @if 后面的表達式或變量為 true ,它將執(zhí)行 {} 里的代碼。上面的代碼在 .square 的樣式中使用了 @mixin ,它將會生成如下的 CSS 代碼:.square { height: 100px; width: 50px;}從上面兩段代碼的對比中我們看到,我們?yōu)?@mixin 傳入了 $size 并且 @if 后面的變量為 true,所以它執(zhí)行了 width: $size / 2 生成的 CSS 就是 width: 50px ,在這里你要重點關(guān)注 @if 指令的用法,關(guān)于 @mixin 在后面的章節(jié)我們會詳細講到,這里你可以先認識下就好。3.1.1 @else 和 @else if 指令如果你了解任何的編程語言,那么你一定知道有 if 就會有 else 和 else if ,如果 @if 后面的表達式為 false ,就會判斷 @else if 后面的表達式,如果還是 false 則會繼續(xù)往后走,如果所有表達式都為 false 則最終會執(zhí)行 @else 后面的 {} 中的代碼邏輯。當(dāng)然 @else if 和 @else是在你需要多條邏輯判斷的時候?qū)懙?,也可以不寫,就像上面的代碼一樣。說了這么多可能你不是很理解,一碼勝千言,我們直接將上面的代碼段改造下,實際體會一下:@mixin avatar($size, $circle: 1) { height: $size; @if $circle == 1 { width: $size / 2; } @else if $circle == 2 { width: $size / 5; } @else { width: $size; }}.a { @include avatar(100px); }.b { @include avatar(100px, $circle: 2); }.c { @include avatar(100px, $circle: 3); }上面的代碼中我有 3 條判斷邏輯對應(yīng)不同的代碼塊,然后我在 .a .b .c 中分別調(diào)用 @mixin 并傳入不同的參數(shù),轉(zhuǎn)換后的 CSS 代碼如下:.a { height: 100px; width: 50px;}.b { height: 100px; width: 20px;}.c { height: 100px; width: 100px;}通過上面的講解可以看到 @if 指令還是非常實用的,在你寫函數(shù)的時候很多地方會用到,所以這塊要好好記住。
使用查找功能我們需要進入普通模式,普通模式如何進入前面的小節(jié)已經(jīng)講了,這里不再過多贅述。下面我們來看下針對不同的如何執(zhí)行查找操作:Tips:通模式下按下 : ,這時你會看到窗口的左下角出現(xiàn)了一個 : ,這時我們就可以輸入我們要查找的內(nèi)容了。開啟高亮查找:在左下角的 : 后面輸入 set hls,即可高亮顯示查找內(nèi)容。開啟預(yù)覽查找:在左下角的 : 后面輸入 set incsearch,這時 Vim 會根據(jù)輸入內(nèi)容提前預(yù)覽匹配內(nèi)容,并且實時更新正向掃描:在左下角的 : 后面輸入/搜索內(nèi)容,開始從上向下搜索。反向掃描:在左下角的 : 后面輸入?搜索內(nèi)容,開始從下向上搜索。大小寫敏感查找:在左下角的 : 后面輸入/搜索內(nèi)容\c,查找的結(jié)果會大小寫不敏感。大小寫不敏感查找:在左下角的 : 后面輸入/搜索內(nèi)容\C,查找的結(jié)果會大小寫敏感。查找小實戰(zhàn)隨便打開一個文件查找 name/Name:
從原集合的第一項開始順序取集合的元素,取 n 個元素,最后返回取出這些元素的集合。換句話說就是取集合前 n 個元素組成新的集合返回。源碼定義public fun <T> Iterable<T>.take(n: Int): List<T> { require(n >= 0) { "Requested element count $n is less than zero." } if (n == 0) return emptyList()//n為0表示取0個元素的集合,返回空集合 if (this is Collection<T>) {//如果是只讀集合,可確定集合的size if (n >= size) return toList()//如果要取元素集合大小大于或等于原集合大小那么就直接返回原集合 if (n == 1) return listOf(first())//從第一項開始取1個元素,所以就是集合的first() } var count = 0 val list = ArrayList<T>(n)//創(chuàng)建一個n大小可變集合 for (item in this) {//遍歷原集合 if (count++ == n)//自增計數(shù)器count大小超過要取元素個數(shù),就跳出循環(huán) break list.add(item) } return list.optimizeReadOnlyList()}原理圖解使用場景適用于順序從第一項開始取集合中子集合:fun main(args: Array<String>) { val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala") strList.take(2).forEach { print("$it ") }}
本小節(jié)介紹了如何使用 LEFT JOIN、INNER JOIN、RIGHT JOIN 對表數(shù)據(jù)進行連接查詢,需要注意的是,ON 后面的表示對連表條件,并且還能對表連接查詢的結(jié)果集用 WHERE 進行篩選,例如:SELECT * FROM student a LEFT JOIN student_course b ON a.id=b.student_id RIGHT JOIN course c ON b.course_id=c.id INNER JOIN teacher d ON c.teacher_id=d.idWHERE a.age > 18 AND d.age < 55;以上 sql 語句后面使用了 WHERE 條件篩選,表示學(xué)生年齡大于 18,教師年齡小于 55。
本節(jié)內(nèi)容主要是為了讓大家了解 Sass 的一些高級玩法,比如自定義函數(shù)和自己設(shè)置存儲緩存,實際的工作中并不會用到,但如果你要加入到 Sass 的官方開發(fā)團隊中,這些東西就有必要去深入了解了。這些就不止是前端的范疇了,還會涉及到 Ruby 、Dart、C++ 等編碼語言,如果你對這些有著濃厚的興趣,可以去深入理解 Sass 的機制和擴展。
我們可以使用數(shù)組的內(nèi)置屬性length來獲取數(shù)組的長度,使用點操作符調(diào)用其內(nèi)置屬性:arrayName.length。實例如下:504數(shù)組arr的長度為:3有時我們想引用數(shù)組中最后一個元素,由于數(shù)組下標(biāo)從0開始,所以最后一個元素的下標(biāo)為數(shù)組的長度減去1,這時可以結(jié)合length屬性來進行引用。實例如下:505charArr數(shù)組的最后一個元素為:c
我們看到在字符串和數(shù)組中都有 includes() 方法,其有意設(shè)計為通用方法。它不要求 this 值是數(shù)組對象,所以它可以被用于其他類型的對象 (比如類數(shù)組對象)。下面的例子展示了 在函數(shù)的 arguments 對象上調(diào)用的 includes() 方法。function fn() { console.log([].includes.call(arguments, 'a')); console.log([].includes.call(arguments, 'd'));}fn('a', 'b', 'c');// true// false上面的代碼中,includes 方法接收 arguments 對象,并且正確地返回相應(yīng)的結(jié)果。
命令選項說明-t指定超時期限(秒)。–help輸出 dumpsys 工具的幫助文本。-l輸出可與 dumpsys 配合使用的系統(tǒng)服務(wù)的完整列表。–skip指定不希望包含在輸出中的服務(wù)。service指定希望輸出的服務(wù)。-c指定某些服務(wù)時,附加此選項能以計算機可讀的格式輸出數(shù)據(jù)。-h對于某些服務(wù),附加此選項可查看該服務(wù)的幫助文本和其他選項。
C 語言的編譯總結(jié)起來其實就是,用編譯器將源代碼,也就是我們可以讀懂的程序,翻譯成機器可以讀懂的機器碼。這個過程需要你做到幾點:準(zhǔn)備編譯器;準(zhǔn)備代碼編寫工具;編寫代碼;通過命令行,使用編譯器編譯。當(dāng)然這是最簡單的使用,后面隨著課程的深入,我們還會通過工具來進行編譯命令行的替代。
numpy.vdot() 函數(shù)是求兩個向量的點積,即對應(yīng)位置的元素乘積求和。案例創(chuàng)建大小為 3×2 的矩陣 C:C = np.array([[1, 2], [3, 4], [5, 6]])求解點積:np.vdot(B, C)out: 1001如果對于兩個維度不一致的矩陣進行點積運算:np.vdot(A, B)out: 1001觀察發(fā)現(xiàn),對于維度不一致的矩陣,如果其元素個數(shù)相等,則可以進行 vdot 點積運算;因為在 vdot運算過程中,會首先將矩陣展開。
Go 語言對 switch…case 的功能進行了擴展,它變得更加的通用。switch 之后可以什么都不帶。case 也無需是一個固定值,也可以是一個布爾表達式,而且每一個 case 都是一個 獨立的代碼塊,執(zhí)行完了之后立刻跳出 switch,不需要使用 break。所以可以把 if…else 完美的改寫成 switch…case 的形式。Tips:還有一種 switch 語句叫做 type switch,我們將在學(xué)習(xí)接口時介紹它switch…case 傳統(tǒng)用法代碼示例:package mainimport "fmt"func main() { a := "A" switch a { case "A", "a": fmt.Println("分數(shù)區(qū)間為90~100") case "B", "b": fmt.Println("分數(shù)區(qū)間為70~89") case "C", "c": fmt.Println("分數(shù)區(qū)間為0~70") default: fmt.Println("錯誤的評分") }}第 7 行:和傳統(tǒng)用法一致,去求變量 A 的值和那個 case 匹配;第 8 行:case 后面的值使用逗號隔開,用于表示匹配任意一個值;第 14 行:每一個 switch 中最多可以帶一個 default。輸出結(jié)果:switch…case Go 語言中的新用法:package mainimport "fmt"func main() { a := 50 switch { case a < 60: fmt.Println("不及格") case a < 80: fmt.Println("良好") case a <= 100: fmt.Println("優(yōu)秀") default: fmt.Println("分數(shù)最多為100分") }}第 7 行:switch 后不帶任何參數(shù),直接執(zhí)行第 1 個 case 的判定;第 8 行:case 后面帶的是一個布爾表達式,若值為 true ,則執(zhí)行其后代碼塊;第 14 行:default 在這里就充當(dāng) else 的角色。輸出結(jié)果:
sys.exit(code) 的功能是退出程序:參數(shù) code,退出代碼,通常 0 代表正常退出,其它值代碼異常退出返回值,無演示 sys.exit(code) 的例子如下:import sysprint('hello')sys.exit(0)print('world')在第 3 行,打印 hello在第 4 行,退出程序在第 5 行,打印 world已經(jīng)執(zhí)行 sys.exit(0) 退出了程序,不會執(zhí)行該行代碼運行程序:C:\> python exit.pyhelloC:\>可以看到,程序打印 hello 后即退出了。
制器和文件上傳界面方法如下: public function uploadExcel() { $data = $this->request->param(); $file_url = "./upload/" . $data['file_url']; $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file_url); $n = 2; while (true) { $name = $spreadsheet->getActiveSheet()->getCell('A' . $n)->getValue(); $age = $spreadsheet->getActiveSheet()->getCell('B' . $n)->getValue(); $id_number = $spreadsheet->getActiveSheet()->getCell('C' . $n)->getValue(); try { $studentModel = new StudentModel(); $studentModel->name = $name; $studentModel->age = $age; $studentModel->id_number = $id_number; $studentModel->created_at = time(); $studentModel->save(); } catch (\Exception $exception) { } if(empty($name) && empty($age) && empty($id_number)){ break; } $n++; } return $this->success('導(dǎo)入成功'); }
Markdown 塊引用像段落一樣,里面的文字同樣支持類似于加粗、代碼塊、列表、表格等。實例 7:### 塊引用的特殊樣式> #### 塊引用里的標(biāo)題>> 塊引用里的 **重點文字**>> 塊引用里的列表> - 項目1> - 項目2> - 項目3>> 塊引用里的表格>> |a|b|> |---|---|> |c|d|>> 塊引用里的分割線> ___>渲染結(jié)果如下:
Redis 中的列表和 Python 中的列表都是類似的。Redis 對于列表的數(shù)據(jù)類型也提供了很多操作指令,非常有意思。我們還是和上面一樣,先給出部分常用的操作指令,然后逐個進行實戰(zhàn)演示。來看看 Redis 中操作列表數(shù)據(jù)的指令:指令含義lpush將元素推入列表左端rpush將元素推入列表右端lpushx/rpushx只對已存在的列表執(zhí)行推入操作lpop彈出最左端的元素rpop彈出列表最右端的元素rpoplpush將右邊彈出的元素推入左邊llen獲取列表的長度lindex獲取指定索引上的元素lrange獲取指定索引范圍的元素lset為指定索引設(shè)置新元素linsert將元素插入列表ltrim修建列表。接收一個列表和一個索引范圍作為參數(shù),并移除列表中位于給定索引范圍之外的元素,只保留給定范圍之內(nèi)的元素lrem移除列表中指定元素blpop帶有阻塞功能的左彈出操作brpop阻塞式右彈出操作下面我們繼續(xù)在我們的 redis 客戶端命令行中進行操作,實踐這些指令:首先測試推入元素到列表的指令:lpush/rpush/lpushx/rpushx:# 127.0.0.1:6777> lpush companies baidu alibaba tencent(integer) 3# lrange用于列表顯示,先不用管它??吹揭恢弊蟛迦朐氐慕Y(jié)果如下127.0.0.1:6777> lrange companies 0 -11) "tencent"2) "alibaba"3) "baidu"# 右邊插入,需要把下面的列表橫過來看127.0.0.1:6777> rpush companies bytedance(integer) 4127.0.0.1:6777> lrange companies 0 -11) "tencent"2) "alibaba"3) "baidu"4) "bytedance"127.0.0.1:6777> lpushx companies chinatelecom (integer) 5127.0.0.1:6777> lrange companies 0 -11) "chinatelecom"2) "tencent"3) "alibaba"4) "baidu"5) "bytedance"#元素推進不存在的列表,失敗,返回為0127.0.0.1:6777> lpushx not-exist chinatelecom (integer) 0這里測試下列表元素的彈出功能,涉及的指令有 lpop/rpop/rpoplpush:# 127.0.0.1:6777> lrange companies 0 -11) "chinatelecom"2) "tencent"3) "alibaba"4) "baidu"5) "bytedance"# 左端彈出操作,返回結(jié)果為彈出元素127.0.0.1:6777> lpop companies"chinatelecom"127.0.0.1:6777> lrange companies 0 -11) "tencent"2) "alibaba"3) "baidu"4) "bytedance"# 右端彈出操作127.0.0.1:6777> rpop companies"bytedance"127.0.0.1:6777> lrange companies 0 -11) "tencent"2) "alibaba"3) "baidu"# 右端彈出左端推入127.0.0.1:6777> lpush list1 a1 a2 a3(integer) 3127.0.0.1:6777> lpush list2 b1 b2 b3(integer) 3127.0.0.1:6777> lrange list1 0 -11) "a3"2) "a2"3) "a1"127.0.0.1:6777> lrange list2 0 -11) "b3"2) "b2"3) "b1"127.0.0.1:6777> rpoplpush list1 list2"a1"# 從list1的右端彈出,推入到list2的左端127.0.0.1:6777> lrange list1 0 -11) "a3"2) "a2"127.0.0.1:6777> lrange list2 0 -11) "a1"2) "b3"3) "b2"4) "b1"llen、lrange 和 lindex 指令:# 127.0.0.1:6777> llen companies(integer) 3127.0.0.1:6777> lrange companies 0 -11) "tencent"2) "alibaba"3) "baidu"127.0.0.1:6777> lrange companies 0 11) "tencent"2) "alibaba"# 超出列表索引范圍,返回nil127.0.0.1:6777> lindex companies 3(nil)127.0.0.1:6777> lindex companies 2"baidu"127.0.0.1:6777> lindex companies 0"tencent"# 支持負數(shù),倒著數(shù)127.0.0.1:6777> lindex companies -2"alibaba"測試 lset/linsert/ltrim/lrem 指令:# 127.0.0.1:6777> lset companies 2 meituanOK# 設(shè)置第三個元素為美團127.0.0.1:6777> lrange companies 0 -11) "tencent"2) "alibaba"3) "meituan"127.0.0.1:6777> linsert companies after meituan xiaomi(integer) 4127.0.0.1:6777> lrange companies 0 -11) "tencent"2) "alibaba"3) "meituan"4) "xiaomi"# 插入指令:insert list before|after 目標(biāo)元素 插入元素127.0.0.1:6777> linsert companies before xiaomi jingdong(integer) 5127.0.0.1:6777> lrange companies 0 -11) "tencent"2) "alibaba"3) "meituan"4) "jingdong"5) "xiaomi"# 只保留1-3的值,其余全部去掉127.0.0.1:6777> ltrim companies 1 3OK127.0.0.1:6777> lrange companies 0 -11) "alibaba"2) "meituan"3) "jingdong"127.0.0.1:6777> lpush test_rem a a a b a c a a a(integer) 9# 0 表示的是刪除所有a元素127.0.0.1:6777> lrem test_rem 0 a(integer) 7127.0.0.1:6777> lrange test_rem 0 -11) "c"2) "b"127.0.0.1:6777> rpop test_rem"b"127.0.0.1:6777> rpop test_rem"c"# 重新賦值127.0.0.1:6777> lpush test_rem a a a b a c a a a(integer) 9# 正數(shù)3表示從左向右,刪除3個a127.0.0.1:6777> lrem test_rem 3 a(integer) 3127.0.0.1:6777> lrange test_rem 0 -11) "c"2) "a"3) "b"4) "a"5) "a"6) "a"# 負數(shù)3表示從右向左,刪除3個a127.0.0.1:6777> lrem test_rem -3 a(integer) 3127.0.0.1:6777> lrange test_rem 0 -11) "c"2) "a"3) "b"這種命令行式的操作是不是非常簡單?我們通過幾次實驗就能大致理解和掌握相關(guān)的指令含義。
從集合的第一項開始取出滿足條件元素,這樣操作一直持續(xù)到出現(xiàn)第一個不滿足條件元素出現(xiàn)為止,暫停取元素,返回取出元素的集合。源碼定義public inline fun <T> Iterable<T>.takeWhile(predicate: (T) -> Boolean): List<T> { val list = ArrayList<T>()//創(chuàng)建一個可變集合 for (item in this) {//遍歷原集合 if (!predicate(item))//不符合傳入條件就直接跳出訓(xùn)練 break list.add(item)//符合條件的直接加入到新集合 } return list//最后返回新集合}源碼解析takeWhile 操作符是一個集合的擴展內(nèi)聯(lián)函數(shù),也是一個高階函數(shù),它接收一個以接收T泛型參數(shù)返回一個 Boolean 類型的 Lambda 表達式,也是即是 takeWhile 取元素的條件的實現(xiàn)。遍歷整個原集合,符合條件的加入到新集合中,一旦遇到不符合條件元素直接跳出循環(huán),也就是遇到第一個不符合條件的就終止取元素的操作,最后返回這個新集合。原理圖解使用場景適用于取出集合中前半部分具有相同特征的元素場景。fun main(args: Array<String>) { val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala") strList.takeWhile { it.startsWith("java") }.forEach { print("$it ") }}
通過關(guān)鍵字 in 檢查字典中是否包含指定元素,示例如下:>>> x = {'a':'A', 'b':'B'}>>> 'a' in xTrue>>> 'c' in xFalse在第 1 行,創(chuàng)建一個具有 2 個鍵值對的字典;在第 2 行,使用表達式 key in dictionary,檢測鍵 ‘a(chǎn)’ 是否在字典 x 中;在第 3 行,結(jié)果為真,表示鍵 ‘a(chǎn)’ 在字典 x 中;在第 3 行,使用表達式 key in dictionary,檢測鍵 ‘b’ 是否在字典 x 中;在第 4 行,結(jié)果為假,表示鍵 ‘b’ 不在字典 x 中。
要實例化File對象,需要傳入一個文件或目錄的路徑。File 類提供了如下 4 個構(gòu)造方法:File(File parent, String child):從父抽象路徑名和子路徑名字符串創(chuàng)建新的文件實例;File(String pathName):通過將給定的路徑名字符串轉(zhuǎn)換為抽象路徑名,創(chuàng)建一個新的文件實例(最常用);File(String parent, String child):從父路徑名字符串和子路徑名字符串創(chuàng)建新的文件實例;File(URI uri):通過將給定的文件: URI轉(zhuǎn)換為抽象路徑名,創(chuàng)建一個新的文件實例。以Windows系統(tǒng)為例,在桌面下有一個imooc目錄,該目錄下有一個Hello.java文件和一個空的images目錄,截圖如下:我們可以單擊Windows的路徑欄,來獲取imooc目錄的絕對路徑:有了目錄和文件以及路徑。我們分別實例化兩個File對象,實例如下:import java.io.File;public class FileDemo1 { public static void main(String[] args) { // 傳入目錄絕對路徑 File dir = new File("C:\\Users\\Colorful\\Desktop\\imooc\\images"); // 傳入文件絕對路徑 File file = new File("C:\\Users\\Colorful\\Desktop\\imooc\\Hello.java"); // 打印兩個File對象 System.out.println(dir); System.out.println(file); }}我們可以直接打印File對象,F(xiàn)ile類重寫了toString()方法,查看 Java 源碼,toString()方法直接返回了getPath()實例方法,此方法返回構(gòu)造方法傳入的路徑字符串:運行結(jié)果:C:\Users\Colorful\Desktop\imooc\imagesC:\Users\Colorful\Desktop\imooc\Hello.java上面代碼中,使用\\表示W(wǎng)indows下的路徑分隔符\,Linux和MacOS下使用正斜杠/作為路徑分隔符。假設(shè)是同樣的目錄結(jié)構(gòu),在MacOS和Linux下是這樣表示的:File dir = new File("/Users/Colorful/Desktop/imooc/images");因為Windows平臺和其他平臺路徑分隔符不同,使用不同平臺的開發(fā)者就難以保證路徑分隔符的統(tǒng)一。為了保證代碼更好的兼容性,F(xiàn)ile類下提供了一個靜態(tài)變量separator,用于表示當(dāng)前平臺的系統(tǒng)分隔符:// 根據(jù)當(dāng)前平臺輸出 / 獲取 \System.out.println(File.separator);
Delegate.notNull() 代理主要用于可以不在構(gòu)造器初始化時候初始化而是可以延遲到之后再初始化這個var 修飾的屬性,它和 lateinit 功能類似,但是也有一些不同,不過它們都需要注意的一點是屬性的生命周期,開發(fā)者要做到可控,也就是一定要確保屬性初始化是在屬性使用之前,否則會拋出一個IllegalStateException。package com.imooc.kotlin.delegateimport kotlin.properties.Delegatesclass Teacher { var name: String by Delegates.notNull()}fun main(args: Array<String>) { val teacher = Teacher().apply { name = "Mikyou" } println(teacher.name)}可能有的人并沒有看到 notNull() 有什么大的用處在 Kotlin 開發(fā)中與 Java 不同的是在定義和聲明屬性時必須要做好初始化工作,否則編譯器會提示報錯的,不像 Java 只要定義就 OK 了,管你是否初始化呢。我解釋下這也是 Kotlin 優(yōu)于 Java 地方之一,沒錯就是空類型安全,就是 Kotlin 在寫代碼時就讓你明確一個屬性是否初始化,不至于把這樣的不明確定義拋到后面運行時。如果在 Java 你忘記了初始化,那么恭喜你在運行時你就會拿到空指針異常。相比 Java,Kotlin 屬性定義時多出了額外的屬性初始化的工作。但是可能某個屬性的值在開始定義的時候你并不知道,而是需要執(zhí)行到后面的邏輯才能拿到。這時候解決方式大概有這么幾種:方式A:開始初始化的時給屬性賦值個默認值;方式B:使用Delegates.notNull()屬性代理;方式C:使用lateinit修飾屬性。以上三種方式有局限性,方式 A 就是很直接賦默認值,對于基本類型還可以,但是對于引用類型的屬性,賦值一個默認引用類型對象就感覺不太合適了。方式 B 適用于基本數(shù)據(jù)類型和引用類型,但是存在屬性初始化必須在屬性使用之前為前提條件。方式 C 僅僅適用于引用類型,但是也存在屬性初始化必須在屬性使用之前為前提條件。優(yōu)缺點分析:屬性使用方式優(yōu)點缺點方式A(初始化賦默認值)使用簡單,不存在屬性初始化必須在屬性使用之前的問題僅僅適用于基本數(shù)據(jù)類型方式B(Delegates.notNull()屬性代理)適用于基本數(shù)據(jù)類型和引用類型2、不支持外部注入工具將它直接注入到Java字段中方式C(lateinit修飾屬性)僅適用于引用類型1、存在屬性初始化必須在屬性使用之前的問題;2、不支持基本數(shù)據(jù)類型Tips: 如果能對屬性生命周期做很好把控的話,且不存在注入到外部字段需求,建議使用方式 B;此外還有一個不錯建議就是方式 A+ 方式 C組合,或者方式 A+ 方式 B 組合。具體看實際場景需求。
Django 中的視圖是 MTV 架構(gòu)模式中的 V 層,主要處理客戶端的請求并生成響應(yīng)數(shù)據(jù)返回。它其實類似于 MVC 架構(gòu)模式中的 C 層,用于處理項目的業(yè)務(wù)邏輯部分。Django 的視圖函數(shù)就是 Django 項目中專門處理對應(yīng) path 的 python 函數(shù),這也是整個項目開發(fā)中最核心的業(yè)務(wù)處理部分。當(dāng)然,在 Django 中處理 path 路徑的不只有視圖函數(shù)(FBV),還有視圖類(CBV)。
JAAS 是 Java 早期的安全框架,重點用于驗證代碼的來源或者開發(fā)者,避免代碼被偽造或遭到篡改。JAAS 主要用在 C / S 應(yīng)用中,其驗證的對象是啟動程序的用戶。JAAS 的特點是實現(xiàn)了「可插入認證」。應(yīng)用程序與底層認證相互獨立,也就是說在調(diào)整底層認證方法的時候,不需要修改應(yīng)用程序本身。應(yīng)用程序通過配置文件,決定使用何種認證方法。
Zookeeper 是一個 C/S 架構(gòu)的服務(wù),也就是 Client — Server 的形式。在我們使用 Zookeeper 時,都是使用 Zookeeper 的客戶端向服務(wù)端發(fā)送請求,然后由服務(wù)端做出響應(yīng)返回到客戶端。在這個過程中,Zookeeper 的客戶端需要與 Zookeeper 服務(wù)端建立連接,建立一個連接就是新建一個會話,那么會話的狀態(tài)也就是 Zookeeper 客戶端與 Zookeeper 服務(wù)端的連接狀態(tài)。接下來我們從會話的結(jié)構(gòu)開始進行講解:
numpy.reshape 函數(shù)可以在不改變數(shù)據(jù)的條件下修改形狀,其函數(shù)原型如下:numpy.reshape(arr, newshape, order='C')參數(shù)說明arr待修改形狀的數(shù)組newshape整數(shù)或者整數(shù)數(shù)組,新的形狀應(yīng)當(dāng)兼容原有形狀order‘C’ – 按行,‘F’ – 按列,‘A’ – 原順序,‘k’ – 元素在內(nèi)存中的出現(xiàn)順序。案例生成一維數(shù)組,并利用 reshape 進行數(shù)組形狀的重整:arr0 = np.arange(8).reshape(2,4)輸出結(jié)果為:array([[0, 1, 2, 3], [4, 5, 6, 7]])
下面列舉了一些 fdisk 命令參數(shù)作用:fdisk 命令參數(shù)名稱功能與作用描述-a設(shè)置活動分區(qū)標(biāo)志-b編輯 BSD Unix 系統(tǒng)用的磁盤標(biāo)簽-c設(shè)置 DOS 兼容標(biāo)志-d刪除分區(qū)-l顯示可用的分區(qū)類型-m顯示命令選項-n添加一個新分區(qū)-o創(chuàng)建 DOS 分區(qū)表-p顯示當(dāng)前分區(qū)表-q退出,不保存更改-s為 Sun Unix 系統(tǒng)創(chuàng)建一個新磁盤標(biāo)簽-t修改分區(qū)的系統(tǒng) ID-u改變使用的存儲單位-v驗證分區(qū)表-w將分區(qū)表寫入磁盤-x高級功能
常用參數(shù)作用-vNginx版本信息-V詳細信息,包括已編譯的模塊-t后面跟配置文件地址,檢查配置文件的語法是否正確-c指定Nginx配置文件-s最重要的選項, stop|quit: 停止Nginx服務(wù),reload: 熱加載啟動 Nginx 服務(wù), reopen:重新打開日志文件上面說到 nginx -s stop 可以停止 Nginx 服務(wù),但是 stop 是快速停止命令,意味著不會保存某些信息而是立即退出。要停止 Nginx 還有另一種方法,那就是 quit 參數(shù)。quit 會優(yōu)雅并有序的停止 Nginx 服務(wù)。實例:
在開始記錄跟蹤信息之前,請為要捕獲的分析信息選擇適當(dāng)?shù)挠涗浥渲茫簩?Java 方法采樣:在應(yīng)用的 Java 代碼執(zhí)行期間,頻繁捕獲應(yīng)用的調(diào)用堆棧。分析器會比較捕獲的數(shù)據(jù)集,以推導(dǎo)與應(yīng)用的 Java 代碼執(zhí)行有關(guān)的時間和資源使用信息;跟蹤 Java 方法:在運行時檢測應(yīng)用,以在每個方法調(diào)用開始和結(jié)束時記錄一個時間戳。系統(tǒng)會收集并比較這些時間戳,以生成方法跟蹤數(shù)據(jù),包括時間信息和 CPU 使用率;對 C/C++ 函數(shù)采樣:捕獲應(yīng)用的原生線程的采樣跟蹤數(shù)據(jù)。要使用此配置,我們必須將應(yīng)用部署到搭載 Android 8.0(API 級別 26)或更高版本的設(shè)備上;跟蹤系統(tǒng)調(diào)用:捕獲非常翔實的細節(jié),以便我們檢查應(yīng)用與系統(tǒng)資源的交互情況。我們可以檢查線程狀態(tài)的確切時間和持續(xù)時間、直觀地查看所有內(nèi)核的 CPU 瓶頸在何處,并添加要分析的自定義跟蹤事件。 當(dāng)我們排查性能問題時,此類信息至關(guān)重要。要使用此配置,我們必須將應(yīng)用部署到搭載 Android 7.0(API 級別 24)或更高版本的設(shè)備上。
優(yōu)化應(yīng)用的 CPU 使用率能帶來諸多好處,如提供更快、更順暢的用戶體驗,以及延長設(shè)備電池續(xù)航時間。我們可以使用 CPU Profiler 在與應(yīng)用交互時實時檢查應(yīng)用的 CPU 使用率和線程活動,也可以檢查記錄的方法跟蹤數(shù)據(jù)、函數(shù)跟蹤數(shù)據(jù)和系統(tǒng)跟蹤數(shù)據(jù)的詳細信息。CPU Profiler 記錄和顯示的特定信息類型由我們選擇的記錄配置確定:系統(tǒng)跟蹤數(shù)據(jù)捕獲精細的詳細信息,以便我們檢查應(yīng)用與系統(tǒng)資源的交互情況。方法和函數(shù)跟蹤數(shù)據(jù)對于應(yīng)用進程中的每個線程,我們可以了解一段時間內(nèi)執(zhí)行了哪些方法 (Java) 或函數(shù) (C/C++),以及每個方法或函數(shù)在其執(zhí)行期間消耗的 CPU 資源。我們還可以使用方法和函數(shù)跟蹤數(shù)據(jù)來識別調(diào)用方和被調(diào)用方。調(diào)用方是指調(diào)用其他方法或函數(shù)的方法或函數(shù),而被調(diào)用方是指被其他方法或函數(shù)調(diào)用的方法或函數(shù)。我們可以使用此信息來確定哪些方法或函數(shù)負責(zé)調(diào)用常常會消耗大量資源的特定任務(wù),并優(yōu)化應(yīng)用的代碼以避免不必要的工作。
#include <stdio.h>int main(){ enum Score { A = 5, B = 4, C = 3, D = 2, E = 1, F = 0 }; enum Score score1, score2, score3; score1 = A; score2 = F; score3 = D; printf("score1: %d, score2: %d, score3: %d\n", score1, score2, score3); return 0;}運行結(jié)果:score1: 5, score2: 0, score3: 2程序中聲明了一個枚舉類型,用來映射不同的成績。使用過程中聲明了 3 個變量,然后對變量賦值。這個過程就是一個映射的過程。當(dāng)對變量賦值后,變量中存儲的就是整數(shù)。最后,我們將變量中的值輸出。
DateTime 類是 Date 的子類,它可以存儲除日期以外的秒數(shù)。實例:require 'date'DateTime.superclass# Datedatetime = DateTime.new(2020, 4, 1, 12, 30, 20, '+08:00')#<DateTime: 2020-04-01T12:30:20+08:00 ((2458941j,16220s,0n),+28800s,2299161j)>我們可以通過year、month、day、hour、minute、second和zone來訪問它的屬性。datetime.year # 2020datetime.month # 4datetime.day # 1datetime.hour # 12datetime.minute # 30datetime.second # 20datetime.zone # +08:00我們還可以通過調(diào)用類方法now獲取當(dāng)前的時間。now = DateTime.nowTips:Time和DateTime都可以完成相同的工作,主要區(qū)別是Time是用C實現(xiàn)的,因此速度會更快。Comparison: Time: 2644596.6 i/s DateTime: 231634.8 i/s - 11.42x slower
其引用 C 語言中的 printf 命令,但 也有一些區(qū)別,需要注意:printf 默認情況下末尾不加換行符號,所以如果需要換行,需要顯示手動添加 \n;printf 為格式化輸出不對內(nèi)容做改變操作,尤其在浮點數(shù)輸出的時候,對其結(jié)果不進行改變,這是現(xiàn)實結(jié)果有差異;在 printf 中 arguments 為參數(shù)列表,例如字符串或者變量,建議個數(shù)與 format-string 要求的數(shù)量相同;printf 不用加括號,arguments 使用空格分隔,不用逗號。