第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
6.2 FileOutputStream 實(shí)現(xiàn)類

我們同樣以最常用的FileOutputStream實(shí)現(xiàn)類為例進(jìn)行學(xué)習(xí)。其他實(shí)現(xiàn)類大同小異,如有需要可翻閱官方文檔。FileOutputStream就是向文件流中寫入數(shù)據(jù),下面我們向imooc目錄下的文本文檔Hello.txt輸入一段字符串HHH。完整實(shí)例如下:import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;public class FileOutputStreamDemo1 { public static void main(String[] args) throws IOException { FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Colorful\\Desktop\\imooc\\Hello.txt"); // 寫入 3 個(gè)H字符 fileOutputStream.write(72); fileOutputStream.write(72); fileOutputStream.write(72); fileOutputStream.close(); }}運(yùn)行代碼后,Hello.txt后面成功寫入了 3 個(gè)字符H。

1.1 整數(shù)

這里的整數(shù)包含十進(jìn)制,八進(jìn)制和十六進(jìn)制。八進(jìn)制前要加上前綴 0,十六進(jìn)制前要加上前綴 0x 或者 0X 。同時(shí)在這些整數(shù)的后面可以增加后綴 U 或者 L。這里和上面一樣帶小寫都可以。這兩個(gè)后綴分別代表著 unsigned 和 long,Tips: 請(qǐng)大家注意 C 語(yǔ)言對(duì)于大小寫是敏感的。所以在十六進(jìn)制的時(shí)候才會(huì)出現(xiàn)兩種前綴。比如:十進(jìn)制:1,2,3,4;八進(jìn)制:0345;十六進(jìn)制:0xef12。

3.7 人工智能

人工智能(Artificial Intelligence),英文縮寫為 AI,它是研究、開(kāi)發(fā)用于模擬、延伸和擴(kuò)展人的智能的理論、方法、技術(shù)及應(yīng)用系統(tǒng)的一門新的技術(shù)科學(xué)。人工智能的研究目標(biāo)是使計(jì)算機(jī)能夠勝任一些通常需要人類智能才能完成的復(fù)雜工作,例如:無(wú)人駕駛,通過(guò)車載傳感系統(tǒng)感知道路環(huán)境、自動(dòng)規(guī)劃行車路線并控制車輛到達(dá)預(yù)定目標(biāo)。機(jī)器翻譯,將一種自然語(yǔ)言(例如英文)轉(zhuǎn)換為另一種自然語(yǔ)言(例如中文)。語(yǔ)音合成,將文字信息轉(zhuǎn)變?yōu)榭梢月?tīng)得懂的、流利的人造語(yǔ)音。Python 提供了相關(guān)的庫(kù)用于快速開(kāi)發(fā)人工智能的應(yīng)用,用戶使用 Python 的 AI 庫(kù)時(shí),不需要深入了人工智能算法的細(xì)節(jié),極大的降低了人工智能開(kāi)發(fā)的門檻。TensorFlow 是一個(gè)機(jī)器學(xué)習(xí)框架,其前身是谷歌的神經(jīng)網(wǎng)絡(luò)算法庫(kù),在計(jì)算機(jī)視覺(jué)、語(yǔ)音處理、推薦系統(tǒng)和自然語(yǔ)言處理等場(chǎng)景下有著豐富的應(yīng)用,是目前最熱門的機(jī)器學(xué)習(xí)框架。TensorFlow 提供了 Python、C/C++、Java 等多種編程語(yǔ)言的接口,但是基于 Python 編程接口的 TensorFlow 框架進(jìn)行開(kāi)發(fā)是最常見(jiàn)的選擇。Python 語(yǔ)言的語(yǔ)法簡(jiǎn)潔、表達(dá)能力強(qiáng),能簡(jiǎn)單快速聚焦問(wèn)題本身而不是繁瑣底層細(xì)節(jié),成為了人工智能編程首選的編程語(yǔ)言。

4. 應(yīng)用場(chǎng)景

有了這些前置知識(shí),我們就可以分析一下 TypeScript 內(nèi)置的一些工具類型,就像在映射類型中介紹的可以通過(guò) Partial<T>,可以在項(xiàng)目中直接使用。Exclude<T, U> – 從 T 中剔除可以賦值給 U 的類型。Extract<T, U> – 提取 T 中可以賦值給 U 的類型。NonNullable<T> – 從 T 中剔除 null 和 undefined。ReturnType<T> – 獲取函數(shù)返回值類型。InstanceType<T> – 獲取構(gòu)造函數(shù)類型的實(shí)例類型。用第一個(gè)來(lái)舉例分析:type T00 = Exclude<'a' | 'b' | 'c' | 'd', 'a' | 'c' | 'f'> // 'b' | 'd'來(lái)看一下 Exclude<T, U> 的實(shí)現(xiàn)源碼:/** * Exclude from T those types that are assignable to U */type Exclude<T, U> = T extends U ? never : T;再看一個(gè)進(jìn)階的例子,定義一種方法,可以取出接口類型中的函數(shù)類型:type FunctionPropertyNames<T> = { [K in keyof T]: T[K] extends Function ? K : never }[keyof T]type FunctionProperties<T> = Pick<T, FunctionPropertyNames<T>>interface Part { id: number name: string subparts: Part[] firstFn: (brand: string) => void, anotherFn: (channel: string) => string}type FnNames = FunctionPropertyNames<Part>type FnProperties = FunctionProperties<Part>代碼解釋:倒數(shù)第二行,首先,遍歷整個(gè)接口,然后通過(guò)條件類型判斷接口的屬性值的類型是否是函數(shù)類型,如果是函數(shù)類型,取其屬性名。得到:type FnNames = 'firstFn' | 'anotherFn'倒數(shù)第一行,通過(guò)上一節(jié)介紹的工具函數(shù) Pick,拿到這個(gè)接口的所有函數(shù)類型成員集合:type FnProperties = { firstFn: (brand: string) => void anotherFn: (channel: string) => string}

3. 編寫路由

服務(wù)已經(jīng)啟動(dòng)了,接下來(lái)看看如何創(chuàng)建 gin 的路由。和前文一樣,我們先來(lái)創(chuàng)建一個(gè)處理 GET 請(qǐng)求的路由/index。代碼示例:package mainimport ( "net/http" "github.com/gin-gonic/gin")func main() { router := gin.Default() //創(chuàng)建get請(qǐng)求 router.GET("/index", func(c *gin.Context) { c.String(http.StatusOK, "<h1>Hello Codey!</h1>") }) router.Run("127.0.0.1:9300")}執(zhí)行上述代碼之后,在瀏覽器中輸入127.0.0.1:9300/index。你會(huì)發(fā)現(xiàn)**<h1>這個(gè)標(biāo)簽沒(méi)有被瀏覽器識(shí)別,而是以字符串的形式輸出了**。這是因?yàn)?gin 框架中對(duì)輸出做出了嚴(yán)格的分類,在 c.String() 函數(shù)中輸出的值只會(huì)是字符串的形式輸出,這是在原生函數(shù)之上為了**防止XSS(****跨站腳本攻擊)**而做的優(yōu)化。所以它無(wú)法直接打印 html 腳本來(lái)渲染頁(yè)面,必須要使用 c.HTML() 函數(shù)來(lái)加載 html 文件。代碼示例:package mainimport ( "net/http" "github.com/gin-gonic/gin")func main() { router := gin.Default() router.LoadHTMLGlob("view/*")//設(shè)定html存放的文件目錄 router.GET("/index", func(c *gin.Context) { c.HTML(http.StatusOK, "index.html", nil)//打開(kāi)view.index.html }) router.Run("127.0.0.1:9300")}目錄結(jié)構(gòu)如下index.html 代碼如下:<!DOCTYPE html><html><head> <meta charset="utf-8"> <title>Go語(yǔ)言實(shí)戰(zhàn)2</title></head><body> <div> <h3>登錄</h3> <form action="check" method="POST"> <div> <div> <input type="text" id="username" name="username" placeholder="請(qǐng)輸入賬號(hào)"> </div> </div> <div> <div> <input type="password" class="form-control" id="password" name="password" placeholder="請(qǐng)輸入密碼"> </div> </div> <div > <div > <button id="loginbtn" type="submit" >登錄</button> </div> </div> </form> </div></body></html>執(zhí)行上述代碼之后,在瀏覽器中輸入127.0.0.1:9300/index。此處可以結(jié)合函數(shù)式編程的思想,將 index 的處理函數(shù)拿出來(lái)作為一個(gè)變量,代碼修改后如下所示:package mainimport ( "net/http" "github.com/gin-gonic/gin")func main() { router := gin.Default() router.LoadHTMLGlob("view/*") router.GET("/index", index) router.Run("127.0.0.1:9300")}func index(c *gin.Context) { c.HTML(http.StatusOK, "index.html", nil)}

3. Android 各個(gè)版本、代號(hào)及 API 級(jí)別

從 Android 1.5 開(kāi)始,Google 發(fā)型每一個(gè) Android 版本都用一個(gè)甜品的名稱作為代號(hào),而代號(hào)首字母是從 C 開(kāi)始以此按照字母順序排列,而直到 19 年發(fā)布的 Android Q 開(kāi)始,Google 棄用了這一傳統(tǒng),改名為 Android 10。名稱版本號(hào)API等級(jí)發(fā)布時(shí)間BuildVersionQ10.0292019-09BuildVersionCodes.QPie9.0282018-08BuildVersionCodes.POreo8.1272017-12BuildVersionCodes.OMr1Oreo8.0262017-08BuildVersionCodes.ONougat7.1252016-12BuildVersionCodes.NMr1Nougat7.0242016-08BuildVersionCodes.NMarshmallow6.0232015-08BuildVersionCodes.MLollipop5.1222015-03BuildVersionCodes.LollipopMr1Lollipop5.0212014-11BuildVersionCodes.LollipopKitkat Watch4.4W202014-06BuildVersionCodes.KitKatWatchKitkat4.4192013-10BuildVersionCodes.KitKatJelly Bean4.3182013-07BuildVersionCodes.JellyBeanMr2Jelly Bean4.2-4.2.2172012-11BuildVersionCodes.JellyBeanMr1Jelly Bean4.1-4.1.1162012-06BuildVersionCodes.JellyBeanIce Cream Sandwich4.0.3-4.0.4152011-12BuildVersionCodes.IceCreamSandwichMr1Ice Cream Sandwich4.0-4.0.2142011-10BuildVersionCodes.IceCreamSandwichHoneycomb3.2132011-06BuildVersionCodes.HoneyCombMr2Honeycomb3.1.x122011-05BuildVersionCodes.HoneyCombMr1Honeycomb3.0.x112011-02BuildVersionCodes.HoneyCombGingerbread2.3.3-2.3.4102011-02BuildVersionCodes.GingerBreadMr1Gingerbread2.3-2.3.292010-11BuildVersionCodes.GingerBreadFroyo2.2.x82010-06BuildVersionCodes.FroyoEclair2.1.x72010-01BuildVersionCodes.EclairMr1Eclair2.0.162009-12BuildVersionCodes.Eclair01Eclair2.052009-11BuildVersionCodes.EclairDonut1.642009-09BuildVersionCodes.DonutCupcake1.532009-05BuildVersionCodes.CupcakeBase1.122009-02BuildVersionCodes.Base11Base1.012008-10BuildVersionCodes.Base

4. tail 命令查看文件內(nèi)容

tail 命令也用來(lái)查看文件內(nèi)容,下面列舉一些 tail 命令的參數(shù):tail 命令參數(shù)名稱功能與作用描述-f表示 --follow[={name|descriptor}],該參數(shù)用于監(jiān)聽(tīng)文件新增內(nèi)容。-c表示 --bytes=[+]NUM,從 num 字節(jié)位置讀取指定文件-n表示 --lines=[+]NUM,從 num 行位置讀取指定文件。-F同 -f-q表示 --quiet,從不輸出給出文件名的首部-s表示 --sleep-interval=N,與-f合用,表示在每次反復(fù)的間隔休眠S秒

2.4 filterIsInstance 和 filterIsInstanceTo 操作符

filterIsInstance 操作符是 filter 操作符一個(gè)特定應(yīng)用,從集合中篩選出 instance 某個(gè)特定類型元素并把該元素強(qiáng)轉(zhuǎn)成該類型,最后返回這些元素集合。源碼定義public inline fun <reified R> Iterable<*>.filterIsInstance(): List<@kotlin.internal.NoInfer R> { return filterIsInstanceTo(ArrayList<R>())}public inline fun <reified R, C : MutableCollection<in R>> Iterable<*>.filterIsInstanceTo(destination: C): C { for (element in this) if (element is R) destination.add(element) return destination}源碼解析首先,filterIsInstance 是一個(gè)擴(kuò)展函數(shù),它的主要實(shí)現(xiàn)是借助于 filterIsInstanceTo,通過(guò)外部傳入的R泛型,創(chuàng)建一個(gè) R 泛型的 ArrayList 可變集合,用于收集原集合中 instance R 類型的元素.可以看出在filterIsInstanceTo 內(nèi)部是遍歷集合然后利用is判斷屬于 R 類型的元素就加入到集合中,最后返回該集合。使用場(chǎng)景filterInstance使用場(chǎng)景:適用于一個(gè)抽象類集合中還有多種子類型的元素,可以很方便篩選對(duì)應(yīng)子類型的元素,并組成一個(gè)集合返回。filterInstanceTo使用場(chǎng)景:基本作用和 filterInstance 一致,不過(guò)唯一的區(qū)別就是這個(gè)可變集合 ArrayList<R> 不是在內(nèi)部創(chuàng)建,而是由外部創(chuàng)建,非常適合篩選多個(gè)集合的情況。下面看個(gè)例子,我們來(lái)看下不使用 filterInstance 和使用 filterInstance 情況對(duì)比。沒(méi)有使用 filterInstance,而是使用 filter 和 map 集合相結(jié)合(當(dāng)你不知道有 filterInstance 操作符,估計(jì)都是這種方法實(shí)現(xiàn)的)。abstract class Animal(var name: String, var age: Int){ abstract fun eatFood(): String}class Bird(name: String, age: Int): Animal(name, age){ override fun eatFood() = "bird eat worm"}class Cat(name: String, age: Int) : Animal(name, age) { override fun eatFood() = "Cat eat Fish"}class Dog(name: String, age: Int) : Animal(name, age) { override fun eatFood() = "dog eat bone"}fun main(args: Array<String>) { val animalList: List<Animal> = listOf(Bird(name = "Bird1", age = 12), Cat(name = "Cat1", age = 18), Cat(name = "Cat3", age = 20), Dog(name = "Dog2", age = 8), Cat(name = "Cat2", age = 8), Bird(name = "Bird2", age = 14), Bird(name = "Bird3", age = 16), Dog(name = "Dog1", age = 18) ) //篩選出個(gè)所有Dog的信息,借助filter和map操作符 animalList.filter { it is Dog }.map { it as Dog }.forEach { println("${it.name} is ${it.age} years old, and ${it.eatFood()}") }}使用 filterInstance 操作符實(shí)現(xiàn)fun main(args: Array<String>) { val animalList: List<Animal> = listOf(Bird(name = "Bird1", age = 12), Cat(name = "Cat1", age = 18), Cat(name = "Cat3", age = 20), Dog(name = "Dog2", age = 8), Cat(name = "Cat2", age = 8), Bird(name = "Bird2", age = 14), Bird(name = "Bird3", age = 16), Dog(name = "Dog1", age = 18) ) //篩選出個(gè)所有Dog的信息,借助filterIsInstance操作符 animalList.filterIsInstance<Dog>().forEach { println("${it.name} is ${it.age} years old, and ${it.eatFood()}") }}

4. 可達(dá)性分析法示例

上文中提到了,可達(dá)性分析法是通過(guò) GC Roots 為起點(diǎn)的搜索,有四種對(duì)象可以作為 GC Roots,那么我們通過(guò)如下示意圖來(lái)理解下,何為不可達(dá)對(duì)象。GC Roots 四種類型解釋:從上圖中,我們可以看到四種 GC Roots。這里我們對(duì)這四種 GC Roots 做一下更為細(xì)致的解釋。虛擬機(jī)棧中的引用的對(duì)象:我們?cè)诔绦蛑姓?chuàng)建一個(gè)對(duì)象,對(duì)象會(huì)在堆上開(kāi)辟一塊空間,同時(shí)會(huì)將這塊空間的地址作為引用保存到虛擬機(jī)棧中,如果對(duì)象生命周期結(jié)束了,那么引用就會(huì)從虛擬機(jī)棧中出棧,因此如果在虛擬機(jī)棧中有引用,就說(shuō)明這個(gè)對(duì)象還是有用的,這種情況是最常見(jiàn)的;全局的靜態(tài)的對(duì)象:也就是使用了 static 關(guān)鍵字,由于虛擬機(jī)棧是線程私有的,所以這種對(duì)象的引用會(huì)保存在共有的方法區(qū)中,顯然將方法區(qū)中的靜態(tài)引用作為 GC Roots 是必須的;常量引用:就是使用了 static final 關(guān)鍵字,由于這種引用初始化之后不會(huì)修改,所以方法區(qū)常量池里的引用的對(duì)象也應(yīng)該作為 GC Roots;Native 方法引用對(duì)象:這一種是在使用 JNI 技術(shù)時(shí),有時(shí)候單純的 Java 代碼并不能滿足我們的需求,我們可能需要在 Java 中調(diào)用 C 或 C++ 的代碼,因此會(huì)使用 native 方法,JVM 內(nèi)存中專門有一塊本地方法棧,用來(lái)保存這些對(duì)象的引用,所以本地方法棧中引用的對(duì)象也會(huì)被作為 GC Roots。從上圖來(lái)理解可達(dá)性分析法就會(huì)非常簡(jiǎn)單,四種 GC Roots 無(wú)非是 Java 中的引用對(duì)象,從GC Roots 出發(fā),類似于我們使用開(kāi)發(fā)工具看代碼,發(fā)現(xiàn)某部分代碼用不到了,我們就會(huì)刪除這部分代碼。其實(shí)可達(dá)性分析法也是如此,發(fā)現(xiàn)某些對(duì)象不可達(dá)了,就會(huì)被垃圾回收器收集。從上圖中來(lái)看,對(duì)象 A,B,C,D,E,F(xiàn) 為可達(dá)對(duì)象;而對(duì)象 G,H,I,J,K 為不可達(dá)對(duì)象,會(huì)被標(biāo)記為垃圾對(duì)象,最終被垃圾回收器回收。

7. 運(yùn)算符的優(yōu)先級(jí)

當(dāng)多種運(yùn)算符在一同使用的時(shí)候,會(huì)有一個(gè)執(zhí)行先后順序的問(wèn)題。下表中的運(yùn)算符按優(yōu)先順序排序。運(yùn)算符越靠近表格頂部,其優(yōu)先級(jí)越高。具有較高優(yōu)先級(jí)的運(yùn)算符將在具有相對(duì)較低優(yōu)先級(jí)的運(yùn)算符之前計(jì)算。同一行上的運(yùn)算符具有相同的優(yōu)先級(jí)。類別操作符關(guān)聯(lián)性后綴() [] . (點(diǎn)操作符)左到右一元+ + - !?從右到左乘性* /%左到右加性+ -左到右移位>> >>> <<左到右關(guān)系>> = << =左到右相等== !=左到右按位與&左到右按位異或^左到右按位或|左到右邏輯與&&左到右邏輯或| |左到右條件?:從右到左賦值= + = - = * = / =%= >> = << =&= ^ = | =從右到左逗號(hào),左到右當(dāng)相同優(yōu)先級(jí)的運(yùn)算符出現(xiàn)在同一表達(dá)式中時(shí),如何控制它們計(jì)算的先后呢。我們來(lái)看一個(gè)實(shí)例:445在計(jì)算result的語(yǔ)句的右側(cè),+ 、-兩個(gè)運(yùn)算符優(yōu)先級(jí)相同,如果我們不加以控制,將按照從左到右順序計(jì)算,打印結(jié)果為result = 2;但是如果我們想先計(jì)算a + b和c + a的值,再計(jì)算兩者之差,我們可以使用括號(hào)()將其順序進(jìn)行控制:(a + b) - (c + a),再執(zhí)行代碼將打印我們想要的結(jié)果:result = -2。

4. 類的構(gòu)造器函數(shù)

在 Kotlin 中構(gòu)造器函數(shù)是存在 “主從” 關(guān)系,這點(diǎn)是 Java 中不存在的,也就是常說(shuō)的主構(gòu)造器函數(shù)和從構(gòu)造器函數(shù)。比如在上述 Bird 類中需要新增一個(gè)帶類型 (type) 屬性的構(gòu)造器,就可以定義從構(gòu)造器,從構(gòu)造器是利用 constructor 關(guān)鍵字聲明。class Bird(val color: String = "green", val age: Int = 3) { //主構(gòu)造器 constructor( color: String = "green", age: Int = 3, type: String ) : this(color, age) {//使用constructor聲明從構(gòu)造器,:this(color, age)從構(gòu)造器直接委托調(diào)用主構(gòu)造器函數(shù) //do logical } fun fly() { println("I can fly!") }}fun main() { val smallBird = Bird(color = "blue", age = 8, type = "small")}需要注意的是,在 Kotlin 中默認(rèn)類都會(huì)存在一個(gè)無(wú)參主構(gòu)造器函數(shù),除非我們手動(dòng)指定。此外如果一個(gè)存在主構(gòu)造器,那么從構(gòu)造器函數(shù)就會(huì)直接或間接委托調(diào)用主構(gòu)造器,直接委托給主構(gòu)造器就類似上述例子中的 : this(color, age) ,當(dāng)然可以通過(guò)從構(gòu)造器 A 委托從構(gòu)造器 B,然后從構(gòu)造器 B 委托給主構(gòu)造器,從而達(dá)到間接委托作用。class CustomView : View { constructor(context: Context) : this(context, null)//從構(gòu)造器A委托調(diào)用從構(gòu)造器B constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)//從構(gòu)造器B委托調(diào)用從構(gòu)造器C constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super(context, attrs, defStyle) {//從構(gòu)造器C委托調(diào)用主構(gòu)造器 }}

1.4 與其他語(yǔ)言對(duì)比

在 Java 中,您需要調(diào)用一個(gè)單獨(dú)的函數(shù)并傳入該數(shù)字來(lái)找到某個(gè)數(shù)字的絕對(duì)值,您可能會(huì)寫:number = Math.abs(number) // Java code 而 Ruby,獲得絕對(duì)值的能力內(nèi)置于數(shù)字中,它們內(nèi)部會(huì)將細(xì)節(jié)進(jìn)行處理,您只需要將abs的消息發(fā)送給一個(gè)數(shù)字對(duì)象,然后讓它完成工作即可。number = number.abs 這同樣適用于所有 Ruby 對(duì)象,比如說(shuō),獲取一個(gè)字符串長(zhǎng)度,在 C 語(yǔ)言中,您會(huì)使用strlen(name),而在 Ruby 里,它是name.length,以此類推。因此,Ruby 是一種真正的 OO Language。

1. for 循環(huán)

for 循環(huán) 可以對(duì)任何提供迭代器(iterator)的對(duì)象進(jìn)行遍歷,for 循環(huán)僅以唯一一種形式存在, 和 Java的 for-each 循環(huán)一致。其寫法for <item> in <elements>和 C# 一樣。和 Java 類似,循環(huán)最常見(jiàn)的應(yīng)用就是迭代集合,具體語(yǔ)法如下:for (item in list) println(item)//循環(huán)體還可以是個(gè)代碼塊for (item in list) { //...}val items = listOf("java", "kotlin", "android")//for-in遍歷for (item in items) {//for遍歷集合 println("lang $item")}//遍歷索引for (index in items.indices) {//類似于java中的數(shù)組的length-index的遍歷 println("The $index index is ${items[index]}")}

7.6 在商品頁(yè)面通過(guò)模板引擎規(guī)則顯示商品信息

此時(shí)我們可以根據(jù) JSP 模板引擎,按模板規(guī)則顯示商品信息了。實(shí)例:<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%><!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>商品列表</title></head><body> <div>商品列表:</div> <c:forEach var="item" items="${goodsList}"> ${item.name}--${item.price}--${item.pic} </c:forEach></body></html>注意我們通過(guò) JSP 的模板語(yǔ)法,輸出了商品列表信息。關(guān)于 JSP 模板引擎更多的語(yǔ)法規(guī)則,感興趣的同學(xué)可以后續(xù)查閱更多資料。

5. 小結(jié)

編程語(yǔ)言中的變量是用來(lái)存儲(chǔ)中間結(jié)果與最終得到的計(jì)算結(jié)果的存儲(chǔ)單元。在 C 語(yǔ)言中,變量的使用要經(jīng)歷變量類型和變量名稱的指定,也就是聲明,和變量給與一個(gè)初始值,也就是變量的初始化,這兩個(gè)過(guò)程后才能使用變量。由于變量是可以隨時(shí)經(jīng)過(guò)再次賦值而發(fā)生變化的。因此,在使用變量的時(shí)候要特別注意每次是不是按照我們的預(yù)想進(jìn)行賦值。因?yàn)榉穷A(yù)想的賦值是程序中最容易出錯(cuò)的地方。

3.1 指定可選配置

我們可以在模塊級(jí) build.gradle 文件的 defaultConfig 塊中配置另一個(gè) externalNativeBuild 塊,為 CMake 或 ndk-build 指定可選參數(shù)和標(biāo)記。與 defaultConfig 塊中的其他屬性類似,我們也可以在構(gòu)建配置中為每種產(chǎn)品特性重寫這些屬性。例如,如果我們的 CMake 或 ndk-build 項(xiàng)目定義多個(gè)原生庫(kù)和可執(zhí)行文件,我們可以使用 targets 屬性為指定產(chǎn)品特性構(gòu)建和打包其中的部分工件。以下代碼示例說(shuō)明了我們可以配置的部分屬性:android { ... defaultConfig { ... // This block is different from the one you use to link Gradle // to your CMake or ndk-build script. externalNativeBuild { // For ndk-build, instead use the ndkBuild block. cmake { // Passes optional arguments to CMake. arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang" // Sets a flag to enable format macro constants for the C compiler. cFlags "-D__STDC_FORMAT_MACROS" // Sets optional flags for the C++ compiler. cppFlags "-fexceptions", "-frtti" } } } buildTypes {...} productFlavors { ... demo { ... externalNativeBuild { cmake { ... // Specifies which native libraries or executables to build and package // for this product flavor. The following tells Gradle to build only the // "native-lib-demo" and "my-executible-demo" outputs from the linked // CMake project. If you don't configure this property, Gradle builds all // executables and shared object libraries that you define in your CMake // (or ndk-build) project. However, by default, Gradle packages only the // shared libraries in your APK. targets "native-lib-demo", // You need to specify this executable and its sources in your CMakeLists.txt // using the add_executable() command. However, building executables from your // native sources is optional, and building native libraries to package into // your APK satisfies most project requirements. "my-executible-demo" } } } paid { ... externalNativeBuild { cmake { ... targets "native-lib-paid", "my-executible-paid" } } } } // Use this block to link Gradle to your CMake or ndk-build script. externalNativeBuild { cmake {...} // or ndkBuild {...} }}

3.1 分治算法求解思路

在這里,我們用分治算法求解最大子數(shù)組問(wèn)題,主要思路如下:步驟 1:找到數(shù)組 A 的中間元素,其下標(biāo)記為 mid,根據(jù)分治策略,將數(shù)組 A [low,high] 根據(jù)中間元素劃分為 A [low,mid], A [mid+1,high] 兩個(gè)部分;步驟 2:假設(shè)數(shù)組 A 的最大子數(shù)組為 A [i, j],那么 A [i, j] 只有以下三種可能:a: 最大子數(shù)組 A [i, j] 完全位于 A [low, mid] 中,此時(shí)有 low <= i <= j <= mid;b: 最大子數(shù)組 A [i, j] 完全位于 A [mid+1, high] 中,此時(shí)有 mid+1 <= i <= j <= high;c: 最大子數(shù)組 A [i, j] 跨域了中間元素,則 low <= i <= mid <= j <= high。分別計(jì)算上述三種對(duì)應(yīng)的最大子數(shù)組的結(jié)果;Tips: 在這里,情況 a 和情況 b 這兩種情況所得的子問(wèn)題和之前求解數(shù)組 A 的最大子數(shù)組的問(wèn)題形式完全一樣,這里是分治思想的主要體現(xiàn),將大的問(wèn)題拆分成了兩個(gè)相同形式的小問(wèn)題;情況 c 這時(shí)候可以直接求解,在 3.2 節(jié)中會(huì)具體介紹其求解過(guò)程。步驟 3對(duì)步驟 2 三種情況的求解結(jié)果進(jìn)行比較,其中最大子數(shù)組的結(jié)果為最大值的情況就是我們的所求結(jié)果。

1.18 make_list

將輸入的 value 值轉(zhuǎn)成列表形式。如果輸入的是字符串,則轉(zhuǎn)成字符列表。如果輸入的是整數(shù),會(huì)首先轉(zhuǎn)成字符串形式,然后在轉(zhuǎn)成列表。用法如下:{{ value|make_list }}假設(shè)輸入的 value 值為 “imooc”,輸出結(jié)果為 [‘i’, ‘m’, ‘o’, ‘o’, ‘c’]。如果輸入的是 123,那么輸出為 [‘1’, ‘2’, ‘3’]。它的實(shí)現(xiàn)過(guò)程非常簡(jiǎn)單,對(duì)輸入的文本直接使用 list() 方法并返回。@register.filter(is_safe=False)@stringfilterdef make_list(value): """ Return the value turned into a list. For an integer, it's a list of digits. For a string, it's a list of characters. """ return list(value)

3.3 使用模塊

編寫主程序 main.py,注意:將 main.py 和 utils.py 放置在相同目錄下:import utilsprint(utils.PI)print(utils.max(11, 22))from utils import minprint(min(11, 22))在第 1 行,引入模塊 utils在第 2 行,訪問(wèn)模塊的導(dǎo)出變量 PI在第 3 行,訪問(wèn)模塊的導(dǎo)出函數(shù) max在第 5 行,引入模塊 utils 中的導(dǎo)出函數(shù) min在第 6 行,訪問(wèn)模塊的導(dǎo)出函數(shù) min運(yùn)行程序 main.py,輸出結(jié)果如下:C:\> python main.py3.142211在第 2 行,輸出 PI 的值在第 3 行,輸出 max(11, 22) 的結(jié)果在第 4 行,輸出 min(11, 22) 的結(jié)果

3.4 編輯系統(tǒng)變量Path

最后,將我們剛剛添加的 JAVA_HOME 的 bin 目錄附加到系統(tǒng)變量 PATH 上。首先找到系統(tǒng)變量列表中的 Path 變量,選中后點(diǎn)擊編輯按鈕。新建一個(gè)值為 %JAVA_HOME%\bin的變量,這里 %JAVA_HOME% 的寫法表示調(diào)用我們剛剛定義的環(huán)境變量JAVA_HOME。也就是說(shuō),這里我們新建的變量實(shí)際上就是C:\Program Files\Java\jdk-15.0.1\bin目錄,這樣寫是為了更直觀,容易維護(hù),如果你需要修改Java的安裝目錄,直接編輯JAVA_HOME變量即可完成修改。

3.2 例子

編寫程序 nest.py 如下:14在第 1 行,用戶輸入性別 sex在第 2 行,用戶輸入年齡 age,注意:使用函數(shù) int() 將用戶輸入的字符串轉(zhuǎn)換為整數(shù)在第 3 行,判斷用戶性別如果為真則執(zhí)行第 4 行的 if 語(yǔ)句如果為假則執(zhí)行第 9 行的 if 語(yǔ)句運(yùn)行程序 nest.py,結(jié)果如下:C:\> python nest.pyfemale20young female首先,用戶輸入性別為 female然后,用戶輸入年齡 20經(jīng)過(guò)第 3 行的條件判斷 sex == male 和 第 9 行的條件判斷 age > 50執(zhí)行第 12 行的語(yǔ)句輸出 young female

2.1 Windows 下配置 JDK 環(huán)境變量

假設(shè)你的 JDK 安裝目錄是 D:\java\jdk1.8,可以右鍵單擊"我的電腦",選擇"屬性"->“高級(jí)”->“環(huán)境變量”,新增環(huán)境變量:變量名:JAVA_HOME變量值:D:\java\jdk1.8如圖所示:配置 JDK 環(huán)境變量完成之后在找到 PATH 變量,在 PATH 上追加:%JAVA_HOME%\bin;”將 JDK 路徑添加的 PATH 當(dāng)中,一定要記得最后的分號(hào):記得最后的分號(hào)另外也可以通過(guò) Windows 的終端命令行來(lái)完成配置,方法很簡(jiǎn)單,使用記事本打開(kāi) C:\autoexec.bat 文件并添加以下內(nèi)容:set JAVA_HOME=D:\java\jdk1.8set PATH=D:\java\jdk1.8\bin;%PATH%

2.4 sbin 目錄

最最重要的文件了,C 編譯的工作,最后就是為了得到這樣一個(gè)二進(jìn)制文件。Nginx 的啟動(dòng)、重新加載、停止等都是靠該命令完成。我們一般會(huì)將該目錄放到系統(tǒng)的 PATH 變量中,這樣是為了方便直接使用 Nginx 命令,系統(tǒng)能找到該二進(jìn)制文件。不然的話,我們使用該命令就必須輸入全路徑,類似下面這樣:# 指定全路徑$ /root/nginx/sbin/nginx # 將/root/Nginx/sbin/添加到了系統(tǒng)的PATH變量中,就可以直接使用$ nginx # 或者進(jìn)入sbin目錄$ cd /root/nginx/sbin$ ./nginx

2. 什么是服務(wù)快速失敗

在介紹服務(wù)快速失敗之前,我們需要首先了解一個(gè)概念,那就是雪崩效應(yīng),那么什么是雪崩效應(yīng)呢?雪崩效應(yīng),是一種微服務(wù)項(xiàng)目間出現(xiàn)的一種不良現(xiàn)象,一般是指:由一個(gè)微服務(wù)發(fā)生故障之后,影響到了其他微服務(wù)的正常運(yùn)行,或者說(shuō),當(dāng)一個(gè)微服務(wù)發(fā)生故障不能正常運(yùn)行時(shí),所導(dǎo)致的其他微服務(wù)也跟著受影響,導(dǎo)致其他的微服務(wù)也不能正常運(yùn)行。假設(shè)現(xiàn)在有 4 個(gè)微服務(wù),分別用服務(wù) A 、服務(wù) B 、服務(wù) C 、服務(wù) D 表示,并且,服務(wù) B 的運(yùn)行依賴于服務(wù) A ,服務(wù) C 的運(yùn)行依賴于服務(wù) B ,服務(wù) D 的運(yùn)行也依賴于服務(wù) B , 這 4 個(gè)微服務(wù)之間的正常運(yùn)行關(guān)系如下圖所示:假想微服務(wù)架構(gòu)為了驗(yàn)證雪崩效應(yīng),現(xiàn)在,我們假設(shè)服務(wù) B 由于外界因素發(fā)生了宕機(jī)現(xiàn)象,那么此時(shí)的服務(wù) B 由于沒(méi)有任何保護(hù)措施,所以服務(wù) B 無(wú)法正常運(yùn)行。由于服務(wù) B 不能正常運(yùn)行,所以,導(dǎo)致依賴于服務(wù) B 的服務(wù) C 和服務(wù) D 都不能繼續(xù)正常運(yùn)行了,如下圖所示:雪崩效應(yīng)產(chǎn)生原理Tips: 1. 在實(shí)際工作中,在正式開(kāi)發(fā)項(xiàng)目之前,應(yīng)該就可能會(huì)出現(xiàn)雪崩現(xiàn)象的因素展開(kāi)集中討論,并將討論結(jié)果以書(shū)面文件形式進(jìn)行存儲(chǔ),這樣一來(lái),在真正發(fā)生雪崩現(xiàn)象時(shí),可以及時(shí)啟用應(yīng)急方案; 2. 在開(kāi)發(fā)微服務(wù)項(xiàng)目時(shí),我們應(yīng)該盡最大可能的去避免雪崩現(xiàn)象的發(fā)生,因?yàn)檠┍垃F(xiàn)象除了會(huì)影響業(yè)務(wù)的正常開(kāi)展之外,也會(huì)影響我們的資源消耗。在了解了什么是雪崩效應(yīng)之后,接下來(lái)我們來(lái)看一下什么是服務(wù)快速失敗。服務(wù)快速失敗,就微服務(wù)而言,是指:當(dāng)微服務(wù)之間發(fā)生雪崩現(xiàn)象時(shí),在程序中通過(guò)采用某種技術(shù)方法或手段,來(lái)將引起雪崩效應(yīng)的微服務(wù)快速處理,其處理的最終目的是要保證該微服務(wù)不會(huì)導(dǎo)致其他后續(xù)的微服務(wù)出現(xiàn)故障。說(shuō)白了,服務(wù)快速失敗就是當(dāng)微服務(wù)發(fā)生故障時(shí),所采取的一個(gè)兜底的方案,該方案的執(zhí)行會(huì)迅速終止發(fā)生故障的微服務(wù)的繼續(xù)運(yùn)行,且可以保證后續(xù)微服務(wù)的正常運(yùn)行,具體如下圖所示:服務(wù)快速失敗的作用在上圖中,我們可以看到,發(fā)生故障的服務(wù) B,由于采用了服務(wù)快速失敗機(jī)制,導(dǎo)致在發(fā)生故障時(shí)采取了快速失敗措施,且同時(shí)也保證了服務(wù) C 和服務(wù) D 的正常運(yùn)行(至于如何保證的服務(wù) C 和服務(wù) D 的正常運(yùn)行,就涉及到了源碼層面,由于該知識(shí)不符合本套課程的初衷,所以這里不予介紹)。Tips: 1. 服務(wù)快速失敗幾乎稱為了每個(gè)微服務(wù)項(xiàng)目中必不可少的措施,所以,我們?cè)陂_(kāi)發(fā)微服務(wù)項(xiàng)目時(shí),一定要采用服務(wù)快速失敗機(jī)制,來(lái)保證我們項(xiàng)目的正常運(yùn)行; 2. 理解什么是雪崩效應(yīng)是理解什么是服務(wù)快速失敗的前提概念,同學(xué)們一定要對(duì)這兩個(gè)概念有所了解才行。

3.將數(shù)據(jù)寫入 Excel 處理對(duì)象

//設(shè)置 excel 信息 $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); $sheet->getDefaultRowDimension()->setRowHeight(20);//設(shè)置默認(rèn)行高 $sheet->getDefaultColumnDimension()->setWidth(10);//設(shè)置默認(rèn)寬度 $sheet->getStyle("A1:Z1")->getFont()->setSize(10)->setBold(true);//設(shè)置第一行字體 $sheet->getStyle("A1:Z1")->getFont()->getColor()->setRGB("FFFFFF");//設(shè)置第一行字體顏色 $sheet->setCellValue('A1', 'ID'); $sheet->setCellValue('B1', '學(xué)生姓名'); $sheet->setCellValue('C1', '年齡'); $sheet->setCellValue('D1', '身份證號(hào)'); $n = 2; foreach ($students as $student) { $sheet->setCellValue('A' . $n, $student->id);//客戶名稱 $sheet->setCellValue('B' . $n, $student->name);//客戶編號(hào) $sheet->setCellValue('C' . $n, $student->age);// $sheet->setCellValue('D' . $n, $student->id_number); $n++; }

2.1 對(duì)象的例子

在 Python 中,對(duì)象的例子如下:字符串 ‘Hello’列表 [‘www’, ‘imooc’, ‘com’]元組 (‘www’, ‘imooc’, ‘com’)字典 {‘name’: ‘tom’, ‘a(chǎn)ge’: 123}2.2 對(duì)象的屬性對(duì)象的屬性示例如下:>>> string = 'Hello'>>> print(string.__doc__)str(object='') -> strstr(bytes_or_buffer[, encoding[, errors]]) -> strCreate a new string object from the given object. >>> list = ['a', 'b', 'c']>>> print(list.__doc__)list() -> new empty listlist(iterable) -> new list initialized from iterable's items在第 1 行,創(chuàng)建字符串對(duì)象 ‘Hello’在第 2 行,打印字符串 ‘Hello’ 的屬性 __doc__,該屬性描述了字符串對(duì)象的用法在第 6 行,創(chuàng)建列表對(duì)象 list在第 7 行,打印列表 list 的屬性 __doc__,該屬性描述了列表對(duì)象的用法

2.2 裝飾器組合

多個(gè)裝飾器可以同時(shí)應(yīng)用到一個(gè)聲明上,就像下面的示例:書(shū)寫在同一行上:@f @g x書(shū)寫在多行上:@f@gx在 TypeScript 里,當(dāng)多個(gè)裝飾器應(yīng)用在一個(gè)聲明上時(shí)會(huì)進(jìn)行如下步驟的操作:由上至下依次對(duì)裝飾器表達(dá)式求值求值的結(jié)果會(huì)被當(dāng)作函數(shù),由下至上依次調(diào)用通過(guò)下面的例子來(lái)觀察它們求值的順序:function f() { console.log('f(): evaluated'); return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { console.log('f(): called'); }}function g() { console.log('g(): evaluated'); return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { console.log('g(): called'); }}class C { @f() @g() method() {}}在控制臺(tái)里會(huì)打印出如下結(jié)果:f(): evaluatedg(): evaluatedg(): calledf(): called

8. 小結(jié)

運(yùn)算符作為編程語(yǔ)言的基本組成部分,肩負(fù)著非常重要的作用。因此能夠熟練掌握運(yùn)算符是基本的技能。C 語(yǔ)言中的運(yùn)算符根據(jù)作用不同,分為算數(shù),關(guān)系,邏輯,位,復(fù)合賦值,指針,和其它類型等七種運(yùn)算符。這些運(yùn)算符中,有些運(yùn)算符是比較相近的。比如算數(shù)運(yùn)算符中的賦值運(yùn)算符 = 和關(guān)系運(yùn)算符中的相等判斷運(yùn)算符 == 之間,只是相差了一個(gè)等號(hào)。但是這兩個(gè)運(yùn)算符的意義卻截然不同。不過(guò)隨著大家的使用,這些運(yùn)算符會(huì)被大家所牢記。

3. 通道上的注意力機(jī)制的實(shí)現(xiàn) ——SELayer

SENet 是一個(gè)使用通道注意力的模型,它可以對(duì)不同的通道求得不同的權(quán)重,進(jìn)而對(duì)他們加權(quán),從而實(shí)現(xiàn)通道域上的注意力機(jī)制。SELayer 是 SENet 之中的一個(gè)網(wǎng)絡(luò)層,是 SENet 的核心部分,我們可以將其單獨(dú)摘出來(lái)作為一個(gè)通道域上的注意力。SELayer 的網(wǎng)絡(luò)圖如下圖所示:在上圖之中,我們可以發(fā)現(xiàn),對(duì)于已經(jīng)求得的特征(第二個(gè)正方體),SELayer 首先使用卷積網(wǎng)絡(luò),將其變?yōu)?1 * 1 * C 的特征,然后對(duì)于該特征進(jìn)行一定的處理,處理結(jié)束之后的每一個(gè)通道的一個(gè)數(shù)字就代表著原特征圖的相應(yīng)通道的權(quán)重。最后我們將求得的權(quán)重乘到原特征上去便可以得到加權(quán)后的特征,這就表示我們已經(jīng)在通道域上實(shí)現(xiàn)了注意力機(jī)制。在 TensorFlow 之中,我們可以通過(guò)繼承 tf.keras.laysers.Layer 類來(lái)定義自己的網(wǎng)絡(luò)層,于是我們可以將我們的 SELayer 定義為如下:class SELayer(tf.keras.Model): def __init__(self, filters, reduction=16): super(SELayer, self).__init__() self.filters = filters self.reduction = reduction self.GAP = tf.keras.layers.GlobalAveragePooling2D() self.FC = tf.keras.models.Sequential([ tf.keras.layers.Dense(units=self.filters // self.reduction, input_shape=(self.filters, )), tf.keras.layers.Dropout(0.5), tf.keras.layers.BatchNormalization(), tf.keras.layers.Activation('relu'), tf.keras.layers.Dense(units=filters), tf.keras.layers.Dropout(0.5), tf.keras.layers.BatchNormalization(), tf.keras.layers.Activation('sigmoid') ]) self.Multiply = tf.keras.layers.Multiply() def call(self, inputs, training=None, mask=None): x = self.GAP(inputs) x = self.FC(x) x = self.Multiply([x, inputs]) return x在初始化的函數(shù)之中,我們定義了我們需要用到的網(wǎng)絡(luò)層以及相應(yīng)的結(jié)構(gòu),通過(guò) call 函數(shù)與初始化函數(shù),我們可以得到該層的執(zhí)行方式:首先數(shù)據(jù)會(huì)經(jīng)過(guò)一個(gè)全局平均池化,來(lái)變成一個(gè) 1* 1 * c 形狀的特征;然后經(jīng)過(guò)我們定義的 FC 層,來(lái)計(jì)算出一個(gè) 1 * 1 * c 的權(quán)重,其中 FC 層包括;一個(gè)全連接層;一個(gè) DropOut 層用于避免過(guò)擬合;一個(gè)批次正則化層,這是便于更好地進(jìn)行訓(xùn)練;一個(gè) relu 激活函數(shù);另外一個(gè)全連接層;另外一個(gè) DropOut 層;另外一個(gè)批次正則化層;一個(gè) sigmoid 激活函數(shù);在得到權(quán)重之后,我們便使用矩陣的乘法,將原來(lái)的輸出與權(quán)重相乘,從而得到在最終的結(jié)果。

3.4 按條件查詢

按條件查詢是查詢數(shù)據(jù)符合一定條件的數(shù)據(jù)集,包括大于(>)、小于(<)、大于等于(>=)、小于等于(<=)、等于(==)、不等于(!=)等條件。# 這里的 data 是上面我們從 Excel 中解析出來(lái)的數(shù)據(jù)print(data.loc[data["價(jià)格"]<60])# --- 輸出結(jié)果 --- 編程語(yǔ)言 推出時(shí)間 價(jià)格 主要?jiǎng)?chuàng)始人0 java 1995年 45.6 James Gosling2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js 1995年 59.5 Brendan Eich輸出解析:這里的查詢條件為價(jià)格小于60的數(shù)據(jù),可以看到結(jié)果查詢出了所有在價(jià)格上滿足該條件的數(shù)據(jù)。Tips:注意條件等于,要用雙等于號(hào) “ == ”,在程序中單個(gè)等于表示賦值,雙等于表示運(yùn)算。除了單個(gè)條件,還可以傳入多個(gè)條件,并通過(guò)運(yùn)算符 &(與)表示兩邊條件都要滿足、| (或)表示兩邊條件有一個(gè)滿足就可以,進(jìn)行多條件組合查詢:# 這里的 data 是上面我們從 Excel 中解析出來(lái)的數(shù)據(jù)print(data.loc[(data["價(jià)格"]<=69.9) & (data["推出時(shí)間"]=="1972年") ])# --- 輸出結(jié)果 --- 編程語(yǔ)言 推出時(shí)間 價(jià)格 主要?jiǎng)?chuàng)始人2 C 1972年 33.9 Dennis MacAlistair Ritchie輸出解析:我們這里設(shè)置了兩個(gè)條件,一個(gè)是價(jià)格小于等于69.9,另一個(gè)是推出時(shí)間等于1972年,這兩個(gè)數(shù)據(jù)進(jìn)行與運(yùn)算,表示這兩個(gè)條件都滿足的數(shù)據(jù)??梢钥吹綌?shù)據(jù)結(jié)果是同時(shí)滿足了這兩個(gè)條件的所有數(shù)據(jù)集。

直播
查看課程詳情
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)