回一下前面的章節(jié)中我們講解的 Sass 嵌套,很常用的功能。在使用嵌套的時(shí)候你可以使用 @at-root 取消嵌套規(guī)則,我們舉個(gè)例子看下:.a { width: 300px; .b { width: 200px; } .c { width: 100px; // 取消嵌套規(guī)則 @at-root .f { width: 20px; } } // 取消嵌套規(guī)則 @at-root .e { width: 50px; }}上面這段代碼將會(huì)被轉(zhuǎn)換為如下的 CSS 代碼:.a { width: 300px;}.a .b { width: 200px;}.a .c { width: 100px;}.f { width: 20px;}.e { width: 50px;}通過(guò)上面的代碼我們可以看出來(lái),在 .f 和 .e 處我使用了 @at-root ,那么就不會(huì)對(duì)它們倆應(yīng)用嵌套規(guī)則,@at-root 的使用場(chǎng)景視情況而定,靈活使用。
由于不同品牌的手機(jī),USB 驅(qū)動(dòng)程序也是不同的,所以推薦大家從品牌廠商的官網(wǎng)下載 USB 驅(qū)動(dòng)程序。設(shè)備制造商驅(qū)動(dòng)程序網(wǎng)址宏碁http://www.acer.com/worldwide/support/華碩https://www.asus.com/support/Download-Center/BlackBerryhttps://swdownloads.blackberry.com/Downloads/entry.do?code=4EE0932F46276313B51570F46266A608Dellhttp://support.dell.com/support/downloads/index.aspx?c=us&cs=19&l=en&s=dhs&~ck=anavmlFujitsuhttp://www.fmworld.net/product/phone/sp/android/develop/HTChttp://www.htc.com/support華為http://consumer.huawei.com/en/support/index.htmIntelhttp://www.intel.com/software/androidKyocerahttp://www.kyocera-wireless.com/support/phone_drivers.htm聯(lián)想http://support.lenovo.com/us/en/GlobalProductSelectorLGEhttp://www.lg.com/us/support/software-firmwareMotorolahttps://motorola-global-portal.custhelp.com/app/answers/detail/a_id/88481/MTKhttp://online.mediatek.com/Public Documents/MTK_Android_USB_Driver.zipSamsunghttp://developer.samsung.com/galaxy/others/android-usb-driver-for-windows夏普http://k-tai.sharp.co.jp/support/Sonyhttp://developer.sonymobile.com/downloads/drivers/小米http://www.xiaomi.com/c/driver/index.html中興http://support.zte.com.cn/support/news/NewsDetail.aspx?newsId=1000442
//1.定義一個(gè)集合存放數(shù)據(jù)(真實(shí)項(xiàng)目可以存放數(shù)據(jù)庫(kù)或者redis緩存),這樣數(shù)據(jù)比較安全。private List<Map<Integer,String>> datas=new ArrayList<Map<Integer,String>>();//2.服務(wù)端推送消息private void pushMsg(MsgReqBean bean,Channel channel){ Integer touserid=bean.getTouserid(); Channel c=map.get(touserid); if(c==null){//對(duì)方不在線 //2.1存放到list集合 Map<Integer,String> data=new HashMap<Integer, String>(); data.put(touserid,bean.getMsg()); datas.add(data); //2.2.給消息“發(fā)送人”響應(yīng) MsgResBean res=new MsgResBean(); res.setStatus(1); res.setMsg(touserid+">>>不在線"); channel.writeAndFlush(res); }else{//對(duì)方在線 //2.3.給消息“發(fā)送人”響應(yīng) MsgResBean res=new MsgResBean(); res.setStatus(0); res.setMsg("發(fā)送成功); channel.writeAndFlush(res); //2.4.給接收人推送消息 MsgRecBean res=new MsgRecBean(); res.setFromuserid(bean.getFromuserid()); res.setMsg(bean.getMsg()); c.writeAndFlush(res); }}
os.getcwd 的功能是獲取當(dāng)前工作目錄。該函數(shù)的使用示例:>>> import os>>> os.getcwd()'C:\\Users\\Administrator\\Downloads'注意,在 windows 中,路徑分隔符 \ 和 Python 的轉(zhuǎn)義字符 \ 相同,需要對(duì)路徑中的字符 \ 進(jìn)行轉(zhuǎn)義。
多維數(shù)組和一維數(shù)組一樣,可以將全部的值一次完全賦給數(shù)組,也可以只初始化部分內(nèi)容。你可以如同之前的一維數(shù)組一樣,在大括號(hào)中以此寫入初始化的數(shù)值。但是出于可讀性的考慮,你最好按照數(shù)組的維數(shù),用大括號(hào)對(duì)應(yīng)。就如同下面的例子中一樣。short a[2][2] = { 1, 2, 3, 4};short b[2][2] = { {1, 2}, {3, 4}};short c[2][2] = { 3, 4};short d[2][2] = { {}, {3, 4}};上面這些變量初始化中,數(shù)組 a 的初始化方式和之前我們介紹過(guò)的一樣。但是這樣在多維數(shù)組中是我們不推薦的。因?yàn)樵趯?duì)應(yīng)關(guān)系顯示不明顯。數(shù)組 b 的初始化方式是我們推薦的,這種初始化看上去對(duì)應(yīng)關(guān)系比較明了。當(dāng)然缺點(diǎn)是我們要輸入很多個(gè)括號(hào)。數(shù)組 C 是進(jìn)行了部分初始化,將 c[0][0] 和 c[0][1] 兩個(gè)位置賦值為 3 和 4,其它位置會(huì)自動(dòng)賦值為 0 。多維數(shù)組與一維數(shù)組一樣,一定要先初始化或者賦值后才能使用。否則也會(huì)產(chǎn)生未知的錯(cuò)誤。數(shù)組 d 展示了采用對(duì)應(yīng)維數(shù)的大括號(hào)的便捷之處。我們這里只給 d[1][0] 和 d[1][1] 賦值,而沒(méi)有給前面的兩個(gè)位置賦值。
命令 pip3 list 列出所有已經(jīng)安裝的包,示例如下:C:\> pip3 listcertifi (2020.4.5.1)chardet (3.0.4)idna (2.9)numpy (1.18.4)pip3 (9.0.1)pygame (1.9.4)requests (2.23.0)setuptools (28.8.0)urllib3 (1.25.9)pip3 list 輸出了已經(jīng)安裝的包的名稱和版本。
Pandas 中我們有時(shí)候需要將兩個(gè)數(shù)據(jù)集的數(shù)據(jù)進(jìn)行連接,根據(jù)一個(gè)或多個(gè)鍵進(jìn)行數(shù)據(jù)的連接,返回一個(gè)新的數(shù)據(jù)集供進(jìn)一步的數(shù)據(jù)分析。針對(duì)數(shù)據(jù)連接操作,Panda 庫(kù)中提供了 merge () 函數(shù)進(jìn)行操作。在講解函數(shù)功能之前,我們這里準(zhǔn)備了兩個(gè) Excel 數(shù)據(jù),數(shù)據(jù)內(nèi)容分別如下圖:數(shù)據(jù)文件:execl 數(shù)據(jù) demo01.xlsx數(shù)據(jù)文件:execl 數(shù)據(jù) demo02.xlsx我們通過(guò) Pandas 進(jìn)行數(shù)據(jù)解析:# 導(dǎo)入pandas包import pandas as pddata_path_01="C:/Users/13965/Documents/myFuture/IMOOC/pandasCourse-progress/data_source/第14小節(jié)/execl數(shù)據(jù)demo01.xlsx"data_path_02="C:/Users/13965/Documents/myFuture/IMOOC/pandasCourse-progress/data_source/第14小節(jié)/execl數(shù)據(jù)demo02.xlsx"# 解析數(shù)據(jù)data_01 = pd.read_excel(data_path_01)data_02 = pd.read_excel(data_path_02)print(data_01)print(data_02)# --- 輸出結(jié)果 data_01 --- 編程語(yǔ)言 編號(hào) 推出時(shí)間 價(jià)格 主要?jiǎng)?chuàng)始人0 java 1995010302 1995年 45.6 James Gosling1 python 1991110502 1991年 67.0 Guido van Rossum2 C 1972021222 1972年 33.9 Dennis MacAlistair Ritchie3 js 1995040903 1995年 59.5 Brendan Eich4 php 2012092312 2012年 69.9 Rasmus Lerdorf5 C++ 1983070316 1983年 75.0 Bjarne Stroustrup# --- 輸出結(jié)果 data_02 --- 編號(hào) 推出時(shí)間 月平均銷售數(shù)量 主要銷售區(qū)域0 1995010302 1995年 134 成都1 1991110506 2006年 231 北京2 1972021222 1972年 67 天津3 1995040903 1995年 199 上海4 2012092313 2013年 23 深圳5 1983070316 1983年 323 合肥輸出解析:通過(guò)上面的描述可以看到,我們的數(shù)據(jù)集 data_01 和 data_02 他們都有 “編號(hào)” 和 “推出時(shí)間” 這兩列,對(duì)應(yīng)這兩列兩個(gè)數(shù)據(jù)集中有相同的數(shù)據(jù),也有不同數(shù)據(jù)。
由于 Zookeeper 是 C/S 架構(gòu),所以 Zookeeper ACL 的實(shí)現(xiàn)原理也分為兩部分,Zookeeper 客戶端和 Zookeeper 服務(wù)端。我們首先從 Zookeeper 客戶端開始介紹。
2.3.1 潔凈室上述處理方法中,不同事件頂級(jí)實(shí)例變量會(huì)存在一個(gè)共享的問(wèn)題,處理這個(gè)問(wèn)題之前,首先讓我了解一下潔凈室(Clean Room)的概念。潔凈室是一個(gè)用來(lái)執(zhí)行塊的環(huán)境。理想的潔凈室是不應(yīng)該有任何的方法以及實(shí)例變量的,所以不會(huì)產(chǎn)生任何方法名或者變量名的沖突。因此BasicObject和Object往往被用來(lái)充當(dāng)潔凈室。實(shí)例:obj = Object.newobj.instance_eval do @a = 1 @b = 2 @c = 3endobj.instance_eval do puts "@a == #{@a}" puts "@b == #{@b}" puts "@c == #{@c}" puts "sum == #{@a + @b + @c}"end# ---- 輸出結(jié)果 ----@a == 1@b == 2@c == 3sum == 6解釋:讓我們創(chuàng)建一個(gè)Object的實(shí)例作為潔凈室,使用instance_eval在潔凈室第一個(gè)塊中里面定義三個(gè)變量,在第二個(gè)塊中定義4個(gè)方法。因?yàn)樗麄兊淖饔糜蚴沁@個(gè)潔凈室的實(shí)例,所以會(huì)得到最后的輸出結(jié)果。2.3.2 用潔凈室來(lái)處理上述問(wèn)題讓我們使用潔凈室處理剛剛頂級(jí)作用域的問(wèn)題。先修改一下event.rb。define do @limit = 150 endlisten "用戶成功創(chuàng)建訂單數(shù):" do @num = 1 puts "@num1 == #{@num}" order_count = 300 order_count > @limit ? order_count: nil endlisten "用戶成功付款訂單數(shù):" do @num = @num.to_i + 1 puts "@num2 == #{@num}" order_count = 150 order_count > @limit ? order_count: nil endlisten "商家及時(shí)放貨的訂單數(shù):" do @num = @num.to_i + 1 puts "@num3 == #{@num}" order_count = 130 order_count > @limit ? order_count: nil end重新運(yùn)行一下腳本,得到結(jié)果:@num1 == 1用戶成功創(chuàng)建訂單數(shù):300@num2 == 2@num3 == 3每一個(gè)事件之間應(yīng)該是獨(dú)立的,不應(yīng)該共享不必要的變量,為此,我們使用潔凈室修改一下實(shí)現(xiàn)代碼。實(shí)例:@defines = []@listens = []def define &block @defines << blockenddef listen description, &block @listens << {description: description, condition: block}endload 'event.rb'@listens.each do |listen| env = Object.new @defines.each do |define| env.instance_eval &define end condition = env.instance_eval &listen[:condition] puts "#{listen[:description]}#{condition}" if conditionend# ---- 輸出結(jié)果 ----@num1 == 1用戶成功創(chuàng)建訂單數(shù):300@num2 == 1@num3 == 1解釋:我們?cè)谥暗幕A(chǔ)上,每一次定義事件的時(shí)候創(chuàng)建了一個(gè)潔凈室,這樣實(shí)例變量的作用范圍就從頂級(jí)作用域變?yōu)榱藵崈羰覍?duì)象之中,事件之間就不會(huì)存在共享變量的情況了。
多重分支是組成分支結(jié)構(gòu)的重要語(yǔ)句,甚至比單獨(dú)的 if 語(yǔ)句用的更廣泛一些。
很多時(shí)候 if 語(yǔ)句可以很好的滿足我們對(duì)于分支控制的需求,但是當(dāng)你要對(duì)于一系列有著相同表達(dá)式不同內(nèi)容的東西分類的時(shí)應(yīng)該怎么辦?這正式今天要介紹的內(nèi)容。
這一層包含兩大塊:系統(tǒng)庫(kù)及 Android 運(yùn)行時(shí)。系統(tǒng)庫(kù)這一部分其實(shí)就是 C/C++ 庫(kù),這些庫(kù)在 Android 系統(tǒng)中通常以 so 的形式供不同的組件使用,開發(fā)者可以通過(guò)自己的應(yīng)用程序使用這些庫(kù)提供的服務(wù)。Android 運(yùn)行時(shí)Android 采用 Java 作為開發(fā)語(yǔ)言,在其運(yùn)行時(shí)中包含了 Java 核心庫(kù)的大多數(shù)功能,并使每一個(gè) Android 應(yīng)用程序都在它自己的進(jìn)程中運(yùn)行,都擁有一個(gè)獨(dú)立的 Dalvik 虛擬機(jī)實(shí)例。Dalvik 可以保證一個(gè)設(shè)備可以同時(shí)高效地運(yùn)行多個(gè)虛擬系統(tǒng)。
Go 語(yǔ)言為什么能在現(xiàn)有的成熟語(yǔ)言中脫穎而出呢?這要?dú)w功于它比 Java 還簡(jiǎn)潔的語(yǔ)法,接近 C 語(yǔ)言的編譯執(zhí)行速度,甚至還有不亞于腳本語(yǔ)言的開發(fā)速度。在目前最要求效率的當(dāng)下,它無(wú)疑會(huì)是一匹黑馬。但是和其它語(yǔ)言比起來(lái)劣勢(shì)也很明顯,因?yàn)樗霈F(xiàn)的時(shí)間短,學(xué)習(xí)資料少,第三方支持庫(kù)雖然多,但是比起 Java 以及 C 語(yǔ)言還是遠(yuǎn)遠(yuǎn)不夠。Go 語(yǔ)言不支持泛型,對(duì)于學(xué)習(xí) Java 的開發(fā)人員來(lái)說(shuō)一開始會(huì)很不適應(yīng)。
現(xiàn)在,如果我們希望把 HelloWorld.java 文件復(fù)制到 samples1 中,那么我們可以通過(guò)鼠標(biāo)右鍵點(diǎn)擊想要復(fù)制的文件,在彈出來(lái)的上下文菜單中選擇 Copy 選項(xiàng),如下圖所示:選擇 Copy 后,我們鼠標(biāo)右鍵點(diǎn)擊想要復(fù)制到的包名,在彈出來(lái)的上下文菜單中,選擇 Paste,如下圖所示:此時(shí),我們的 HelloWorld.java 文件就被復(fù)制到 samples1 中了,而且文件中的包名也自動(dòng)就行了修改,如下圖所示:我們可以看到這個(gè)操作的快捷鍵就是我們熟悉的復(fù)制粘貼快捷鍵組合 Cmd + C 和 Cmd + V(如果是 Windows 系統(tǒng)則是 Ctrl + C 和 Ctrl + V)
升級(jí) Gradle Wrapper 有 2 種方式:一種是我們前面演示的,直接修改distributionUrl字段,然后執(zhí)行Gradle 命令或是點(diǎn)擊同步按鈕同步。還有一種就是執(zhí)行 gradlew 命令gradlew wrapper –-gradle-version [version]這里我們將 5.0 升級(jí)為最新版 6.0.1.C:\Users\LeiQi PC\Documents\MyApplication>gradlew wrapper --gradle-version 6.0.1Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.Use '--warning-mode all' to show the individual deprecation warnings.See https://docs.gradle.org/6.0.1/userguide/command_line_interface.html#sec:command_line_warningsBUILD SUCCESSFUL in 1s1 actionable task: 1 up-to-date然后我們使用gradlew -v查看當(dāng)前的 Gradle 版本號(hào):C:\Users\LeiQi PC\Documents\MyApplication>gradlew -v------------------------------------------------------------Gradle 6.0.1------------------------------------------------------------Build time: 2019-11-18 20:25:01 UTCRevision: fad121066a68c4701acd362daf4287a7c309a0f5Kotlin: 1.3.50Groovy: 2.5.8Ant: Apache Ant(TM) version 1.10.7 compiled on September 1 2019JVM: 1.8.0_221 (Oracle Corporation 25.221-b11)OS: Windows 10 10.0 amd64我們看到此時(shí)版本號(hào)已經(jīng)升級(jí)為 6.0.1了。
繼承是面向?qū)ο筌浖夹g(shù)當(dāng)中的一個(gè)概念。如果一個(gè)類別 B “繼承自” 另一個(gè)類別 A,就把這個(gè) B 稱為 “A 的子類”,而把 A 稱為 “B 的父類別” 也可以稱 “A 是 B 的超類”。繼承可以使得子類具有父類別的各種屬性和方法,而不需要再次編寫相同的代碼。Java 語(yǔ)言提供了類的繼承機(jī)制。利用繼承,新建的類可以在原有類的基礎(chǔ)上,使用或者重寫原有類的成員方法,訪問(wèn)原有類的成員變量。新建的類成為子類,而原有類為新建類的父類,如果 A 是 B 的父類,B 是 C 的父類,那么 C 也是 A 的子類。
序號(hào)函數(shù)說(shuō)明 1str.len() 計(jì)算字符串的長(zhǎng)度 2str.contains() 查詢字符串是否包含某個(gè)字符或子字符串 3str.find() 查詢?cè)氐谝淮卧谧址谐霈F(xiàn)的位置 4str.count() 查詢某個(gè)元素出現(xiàn)的次數(shù) 5str.startswith() 查詢字符串是否以某個(gè)元素開頭 6str.endswith() 查詢字符串是否以某個(gè)元素結(jié)尾 7str.istitle() 查詢字符串是否首字母大寫其他都是小寫下面我們將通過(guò)代碼操作詳細(xì)介紹這幾個(gè)函數(shù)的使用方法:1. len() 函數(shù)該函數(shù)用于返回字符串的的長(zhǎng)度,包括空格和回車符。# 導(dǎo)入pandas包import pandas as pddata_path="C:/Users/13965/Documents/myFuture/IMOOC/pandasCourse-progress/data_source/第16小節(jié)/execl數(shù)據(jù)demo.xlsx"# 解析數(shù)據(jù)data = pd.read_excel(data_path)print(data)# --- 輸出結(jié)果 --- 編程語(yǔ)言 推出時(shí)間 價(jià)格 主要?jiǎng)?chuàng)始人0 java 1995年 45.6 James Gosling1 python@163.com 1991年 67.0 Guido van Rossum\n2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js@qq.com 1995年 59.5 Brendan Eich4 php 2012年\n 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustrup# data 解析出來(lái)的數(shù)據(jù)# len() 函數(shù)new_series=data["主要?jiǎng)?chuàng)始人"]slice_res= new_series.str.len() print(slice_res)# --- 輸出結(jié)果 ---0 131 172 263 124 145 17Name: 主要?jiǎng)?chuàng)始人, dtype: int64結(jié)果解析:通過(guò)該函數(shù)可以輸出字符串的長(zhǎng)度,“主要?jiǎng)?chuàng)始人” 列的第二個(gè)字符加上空格和回車符工 17 個(gè)字符,如果字符前后存在空格,也是加入計(jì)算的。2. contains() 函數(shù)該函數(shù)用于檢測(cè)字符串是否包含某個(gè)字符或者是子串,返回值為布爾型。# --- 解析 data 數(shù)據(jù)結(jié)果 --- 編程語(yǔ)言 推出時(shí)間 價(jià)格 主要?jiǎng)?chuàng)始人0 java 1995年 45.6 James Gosling1 python@163.com 1991年 67.0 Guido van Rossum\n2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js@qq.com 1995年 59.5 Brendan Eich4 php 2012年\n 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustrup# data 解析出來(lái)的數(shù)據(jù)# contains() 函數(shù)new_series=data["編程語(yǔ)言"]slice_res= new_series.str.contains("com") print(slice_res)# --- 輸出結(jié)果 ---0 False1 True2 False3 True4 False5 FalseName: 編程語(yǔ)言, dtype: bool結(jié)果解析:通過(guò)該函數(shù)檢測(cè) “編程語(yǔ)言” 列,字符串是否含有子串 com ,該列只有第 2 行和第 4 行含有 com 子串,所以這兩行的檢測(cè)結(jié)果為 True,其他行為 False。3. find() 函數(shù)該函數(shù)用于檢測(cè)字符串中第一次出現(xiàn)某個(gè)子串或者字符的下標(biāo)位置,如果不存在則返回為 -1。# --- 解析 data 數(shù)據(jù)結(jié)果 --- 編程語(yǔ)言 推出時(shí)間 價(jià)格 主要?jiǎng)?chuàng)始人0 java 1995年 45.6 James Gosling1 python@163.com 1991年 67.0 Guido van Rossum\n2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js@qq.com 1995年 59.5 Brendan Eich4 php 2012年\n 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustrup# data 解析出來(lái)的數(shù)據(jù)# find() 函數(shù)new_series=data["編程語(yǔ)言"]slice_res= new_series.str.find("com") print(slice_res)# --- 輸出結(jié)果 ---0 -11 112 -13 64 -15 -1Name: 編程語(yǔ)言, dtype: int64 結(jié)果解析:通過(guò)該函數(shù)進(jìn)行檢測(cè),可以看到 “編程語(yǔ)言” 列中字符串出現(xiàn) com 子串的位置下標(biāo),第 2 行為 11,第 4 行為 6,其他行因?yàn)椴淮嬖谠撟哟?,所以返?- 1。4. count() 函數(shù)該函數(shù)用于統(tǒng)計(jì)字符串中出現(xiàn)某個(gè)子串或者字符的次數(shù)。# --- 解析 data 數(shù)據(jù)結(jié)果 --- 編程語(yǔ)言 推出時(shí)間 價(jià)格 主要?jiǎng)?chuàng)始人0 java 1995年 45.6 James Gosling1 python@163.com 1991年 67.0 Guido van Rossum\n2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js@qq.com 1995年 59.5 Brendan Eich4 php 2012年\n 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustrup# data 解析出來(lái)的數(shù)據(jù)# count() 函數(shù)new_series=data["編程語(yǔ)言"]slice_res= new_series.str.count("o") print(slice_res)# --- 輸出結(jié)果 ---0 01 22 03 14 05 0Name: 編程語(yǔ)言, dtype: int64 結(jié)果解析:通過(guò)該函數(shù)檢測(cè) “編程語(yǔ)言” 列,各個(gè)字符串中出現(xiàn)字符 ‘o’ 的次數(shù),通過(guò)輸出結(jié)果可以看到每一個(gè)子串中該字符出現(xiàn)的次數(shù)。5. startswith() 函數(shù)該函數(shù)用于檢測(cè)字符串是否以某個(gè)字符或者子串開始,返回結(jié)果為布爾型。# --- 解析 data 數(shù)據(jù)結(jié)果 --- 編程語(yǔ)言 推出時(shí)間 價(jià)格 主要?jiǎng)?chuàng)始人0 java 1995年 45.6 James Gosling1 python@163.com 1991年 67.0 Guido van Rossum\n2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js@qq.com 1995年 59.5 Brendan Eich4 php 2012年\n 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustrup# data 解析出來(lái)的數(shù)據(jù)# startswith() 函數(shù)new_series=data["編程語(yǔ)言"]slice_res= new_series.str.startswith("j") print(slice_res)# --- 輸出結(jié)果 ---0 True1 False2 False3 True4 False5 FalseName: 編程語(yǔ)言, dtype: bool結(jié)果解析:通過(guò)該函數(shù),檢測(cè) “編程語(yǔ)言” 列各個(gè)字符串是否以字符 ‘j’ 開始,可以看到輸出結(jié)果只有第 1 行和第 4 行是的。6. endswith() 函數(shù)該函數(shù)用于檢測(cè)字符串是否以某個(gè)字符或者子串結(jié)尾,返回結(jié)果為布爾型。# --- 解析 data 數(shù)據(jù)結(jié)果 --- 編程語(yǔ)言 推出時(shí)間 價(jià)格 主要?jiǎng)?chuàng)始人0 java 1995年 45.6 James Gosling1 python@163.com 1991年 67.0 Guido van Rossum\n2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js@qq.com 1995年 59.5 Brendan Eich4 php 2012年\n 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustrup# data 解析出來(lái)的數(shù)據(jù)# endswith() 函數(shù)new_series=data["編程語(yǔ)言"]slice_res= new_series.str.endswith("p") print(slice_res)# --- 輸出結(jié)果 ---0 False1 False2 False3 False4 True5 FalseName: 編程語(yǔ)言, dtype: bool# 結(jié)果解析:通過(guò)該函數(shù)對(duì)“編程語(yǔ)言”列的字符串進(jìn)行檢測(cè),是否以字符 'p' 結(jié)尾,通過(guò)輸出結(jié)果可以看到只有第5行的 "php" 是以該字符為結(jié)尾的,檢測(cè)結(jié)果為 True 。 7. istitle() 函數(shù)該函數(shù)用于檢測(cè)字符串中每個(gè)單詞是否以大寫字符開頭,并且其他的字符均為小寫的內(nèi)容,這里要注意,檢測(cè)的單位是字符串中的每個(gè)單詞。# --- 解析 data 數(shù)據(jù)結(jié)果 --- 編程語(yǔ)言 推出時(shí)間 價(jià)格 主要?jiǎng)?chuàng)始人0 java 1995年 45.6 James Gosling1 python@163.com 1991年 67.0 Guido van Rossum\n2 C 1972年 33.9 Dennis MacAlistair Ritchie3 js@qq.com 1995年 59.5 Brendan Eich4 php 2012年\n 69.9 Rasmus Lerdorf5 C++ 1983年 75.0 Bjarne Stroustrup# data 解析出來(lái)的數(shù)據(jù)# istitle() 函數(shù)new_series=data["主要?jiǎng)?chuàng)始人"]slice_res= new_series.str.istitle() print(slice_res)# --- 輸出結(jié)果 ---0 True1 False2 False3 True4 True5 TrueName: 主要?jiǎng)?chuàng)始人, dtype: bool結(jié)果解析:通過(guò)該函數(shù)檢測(cè) “主要?jiǎng)?chuàng)始人” 列中各個(gè)字符串的每個(gè)單詞是否以大寫字母開頭,該單詞的其他字符為小寫,因?yàn)榈?2 行字符串的 “van” 單詞不是以大寫字母開頭,所有為 False,第 3 行字符串的 “MacAlistair” 雖然是以大寫字符開頭,但是該單詞的其他字符不全是小寫,因此也是返回 False 。
MongoDB 是一個(gè)文檔型數(shù)據(jù)庫(kù),由 C++ 編寫,功能豐富,支持復(fù)雜的數(shù)據(jù)類型,支持?jǐn)?shù)據(jù)建立索引,性能高,容易使用,方便部署。主要特點(diǎn)如下:面向集合存儲(chǔ),方便存儲(chǔ)對(duì)象類型的數(shù)據(jù);支持語(yǔ)言豐富,Python,Java,C++ 等語(yǔ)言;支持完全索引;文件存儲(chǔ)等格式為 JSON。傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù)以 MySQL 為例,一般是由數(shù)據(jù)庫(kù),表,記錄三個(gè)層次組成,MongoDB 是由數(shù)據(jù)庫(kù),集合,文檔對(duì)象組成。下表列出了 MongoDB 與 MySQL 的對(duì)比:MySQLMongoDB 描述 databasedatabase 數(shù)據(jù)庫(kù) tablecollection 數(shù)據(jù)庫(kù)表 / 集合 rowdocument 數(shù)據(jù)庫(kù)行 / 文檔 columnfield 數(shù)據(jù)字段列 / 域 indexindex 索引 indexindex 索引
命令選項(xiàng)說(shuō)明create avd -n name -k “sdk_id” [-c] [-f] [-p]創(chuàng)建一個(gè)新的 AVD。必須為該 AVD 提供一個(gè)名稱,并使用加引號(hào)的 sdk_id 指定要用于該 AVD 的 SDK 軟件包的 ID。-c:此 AVD 的 SD 卡映像的路徑,或要為此 AVD 創(chuàng)建的新 SD 卡映像的大小。-f:強(qiáng)制創(chuàng)建 AVD。-p:將從中創(chuàng)建此 AVD 的文件的目錄所在位置的路徑。delete avd -n刪除一個(gè) AVD。必須使用 name 指定該 AVD。move avd -n name [-p] [-r]移動(dòng)和/或重命名一個(gè) AVD。必須使用 name 指定該 AVD。-p:用于接收此 AVD 的文件的目錄所在位置的絕對(duì)路徑。-r:AVD 的新名稱。list列出所有可用的目標(biāo)、設(shè)備定義或 AVD。
列表是一個(gè)有序的序列,列表中所有的元素放在 [] 中間,并用逗號(hào)分開,例如:[1, 2, 3],一個(gè)包含 3 個(gè)整數(shù)的列表[‘a(chǎn)’, ‘b’, ‘c’],一個(gè)包含 3 個(gè)字符串的列表
要想實(shí)現(xiàn)一些復(fù)雜的功能,依靠簡(jiǎn)單的分支結(jié)構(gòu)和多重分支結(jié)構(gòu)等等是遠(yuǎn)遠(yuǎn)不夠的。所以我們還需要分支嵌套結(jié)構(gòu)。
在 IOS 同事幫助下,進(jìn)一步了解 IOS APP 啟動(dòng)基本知識(shí),這將有助于我們接下來(lái)改造我們項(xiàng)目結(jié)構(gòu),使得它更加簡(jiǎn)單,完全可以刪除額外的 Swift 代碼,包括 APP 啟動(dòng)代理那塊都交由 Kotlin 來(lái)完成。- 先創(chuàng)建一個(gè) Kotlin/Native + OC 的項(xiàng)目,這里就不重復(fù)創(chuàng)建過(guò)程,直接把 OC 目錄結(jié)構(gòu)給出:可以看到 OC 與 Swift 項(xiàng)目結(jié)構(gòu)差不多哈,可以看到其中有幾個(gè)重要的文件,main.m、AppDelegate.m、ViewController.mmain.m APP 啟動(dòng)入口,相當(dāng)于 main 函數(shù),先從 main 函數(shù)入手,然后一步步弄清整個(gè)啟動(dòng)流程。#import <UIKit/UIKit.h>#import "AppDelegate.h"int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));//這里也調(diào)用了AppDelegate類 }}然后轉(zhuǎn)到 AppDelegate.m, 可以看到在 didFinishLaunchingWithOptions 函數(shù)中調(diào)用了 KNFKotlinNativeFramework 中的 helloFromKotlin 函數(shù)。- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // KNFKotlinNativeFramework class is located in the framework that is generated during build. // If it is not resolved, try building for the device (not simulator) and reopening the project NSLog(@"%@", [[[KNFKotlinNativeFramework alloc] init] helloFromKotlin]);//注意這里調(diào)用helloFromKotlin,并輸出日志 return YES;}
和 Set 數(shù)據(jù)結(jié)構(gòu)一樣,Map 也提供了三個(gè)獲取 Map 對(duì)象的鍵值以及鍵值對(duì)組合的方法:方法名描述values返回 Map 實(shí)例中的值作為一個(gè)可以遍歷的對(duì)象keys返回 Map 實(shí)例中的鍵作為一個(gè)可以遍歷的對(duì)象entries返回 Map 實(shí)例中的鍵值對(duì)作為一個(gè)可以遍歷的對(duì)象keys() 方法是獲取 Map 實(shí)例上的鍵,并返回一個(gè)可迭代(Iterator)的對(duì)象。myMap.keys();var map = new Map();map.set('a', 1);map.set('b', 2);map.set('c', 3);var keys = map.keys()console.log(keys.next().value); // "a"console.log(keys.next().value); // "b"console.log(keys.next().value); // "c"獲取后的 keys 結(jié)構(gòu)可以被迭代器上的 next 函數(shù)獲取到對(duì)應(yīng)值。values() 方法是獲取 Map 實(shí)例上元素的值,并返回一個(gè)可迭代(Iterator)的對(duì)象。myMap.values();實(shí)例:var map = new Map();map.set('a', 1);map.set('b', 2);map.set('c', 3);var values = map.values()console.log(values.next().value); // 1console.log(values.next().value); // 2console.log(values.next().value); // 3獲取后的 values 結(jié)構(gòu)可以被迭代器上的 next 函數(shù)獲取到對(duì)應(yīng)值。entries() 方法返回一個(gè)包含 [key, value] 的可迭代(Iterator)的對(duì)象,返回的迭代器的迭代順序與 Map 實(shí)例的插入順序相同。myMap.entries()實(shí)例:var map = new Map();map.set('a', 1);map.set('b', 2);map.set('c', 3);var values = map.values()console.log(values.next().value); // 1console.log(values.next().value); // 2console.log(values.next().value); // 3keys()、values()、entries() 都可以被 for...of 循環(huán)。var map = new Map([["x", 1], ["y", 2], ["z", 3]]);for (let value of map.values()) { console.log(value);}// 1// 2// 3for (let [key, value] of map.entries()) { console.log(key + " = " + value);}// x = 1// y = 2// z = 3注意在循環(huán) entries() 結(jié)果的時(shí)候,因?yàn)槊恳豁?xiàng)是包含鍵值的數(shù)組,可以通過(guò) [key, value] 這種數(shù)組結(jié)構(gòu)的方式把鍵值結(jié)構(gòu)出來(lái)直接使用。
我們都知道 Object 對(duì)象的鍵只能是基本類型,大部分情況都是字符串,并且 Object 存儲(chǔ)的數(shù)據(jù)是無(wú)序的,不能記住插入的先后順序。ES6 為了彌補(bǔ) Object 的缺陷,新增了 Map 數(shù)據(jù)結(jié)構(gòu)用于存儲(chǔ)復(fù)雜的數(shù)據(jù)類型。Map 保存的是鍵值對(duì),并且能夠記住鍵的插入順序,而且任何值都可以作為 Map 的鍵來(lái)使用,包括引用類型。和 Set 一樣,Map 也是一個(gè)構(gòu)造函數(shù),需要通過(guò) new 的方式來(lái)創(chuàng)建一個(gè) Map 實(shí)例。var map = Map([iterable]);在創(chuàng)建 Map 實(shí)例時(shí)可以接收一個(gè)特定的二維數(shù)組或是一個(gè)可遍歷的對(duì)象作為參數(shù),這個(gè)參數(shù)內(nèi)的每一項(xiàng)是以鍵和值的方式來(lái)組合的,如: [key, value] 形式,第一個(gè)元素鍵,第二個(gè)元素是值。// 創(chuàng)建一個(gè)空的 Map 對(duì)象var map1 = new Map()map1.set('a', 1);map1.set('b', 2);map1.set('c', 3);console.log(map1) // Map(3) {"a" => 1, "b" => 2, "c" => 3}// map也可以進(jìn)行鏈?zhǔn)秸{(diào)用var map2 = new Map()map2.set('a', 1).set('b', 2).set('c', 3)console.log(map2) // Map(3) {"a" => 1, "b" => 2, "c" => 3}// 接收一個(gè)二維數(shù)組,二維數(shù)組中包含兩個(gè)值,key和valuevar map3 = new Map([["x", 10], ["y", 20], ["z", 30]]);console.log(map3) // Map(3) {"x" => 10, "y" => 20, "z" => 30}console.log(map1.get('a')) // 1console.log(map3.get('z')) // 30上面的代碼展示了 Map 數(shù)據(jù)結(jié)構(gòu)添加和獲取操作,和 Set 一樣,Map 操作數(shù)據(jù)也是通過(guò)函數(shù)的方式來(lái)實(shí)現(xiàn)的。后面的章節(jié)我們會(huì)對(duì) Map 做詳細(xì)的學(xué)習(xí)
開啟 Zookeeper 服務(wù)端,然后啟動(dòng)主類 ZookeeperConfigApplication 的 main 方法,查看控制臺(tái)輸出:>>> CuratorCacheListener 初始化這行輸出說(shuō)明監(jiān)聽已經(jīng)開啟了,現(xiàn)在就可以訪問(wèn) http://localhost:8888/imooc/getAll 來(lái)查詢數(shù)據(jù)庫(kù)的數(shù)據(jù)了:[{"id":1,"username":"Java","password":"123","phone":"123","address":"北京"},{"id":2,"username":"Go","password":"321","phone":"321","address":"上海"},{"id":3,"username":"Python","password":"456","phone":"654","address":"深圳"}]訪問(wèn)成功,接下來(lái)我們使用 Zookeeper 命令行客戶端連接 Zookeeper 服務(wù)端查詢節(jié)點(diǎn)數(shù)據(jù):# 查詢節(jié)點(diǎn)數(shù)據(jù)get /imooc/datasource# 打印數(shù)據(jù){"Username":"root","DriverClassName":"com.mysql.cj.jdbc.Driver","Url":"jdbc:mysql://localhost:3306/imooc?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai","Password":"021998"}我們可以看見 /imooc/datasource 節(jié)點(diǎn)已經(jīng)保存的數(shù)據(jù)源信息了。在修改數(shù)據(jù)源信息之前,我們需要在 MySQL新建另一個(gè)數(shù)據(jù) wiki,然后在 wiki 數(shù)據(jù)庫(kù)下新建 imooc 數(shù)據(jù)表:/* Navicat Premium Data Transfer Source Server : localhost Source Server Type : MySQL Source Server Version : 80019 Source Host : localhost:3306 Source Schema : wiki Target Server Type : MySQL Target Server Version : 80019 File Encoding : 65001 Date: 25/09/2020 00:55:14*/SET NAMES utf8mb4;SET FOREIGN_KEY_CHECKS = 0;-- ------------------------------ Table structure for imooc-- ----------------------------DROP TABLE IF EXISTS `imooc`;CREATE TABLE `imooc` ( `id` int(0) NOT NULL AUTO_INCREMENT, `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `phone` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `address` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ------------------------------ Records of imooc-- ----------------------------INSERT INTO `imooc` VALUES (1, 'C', '789', '987', '北京');INSERT INTO `imooc` VALUES (2, 'C#', '567', '765', '上海');INSERT INTO `imooc` VALUES (3, 'C++', '654', '456', '深圳');SET FOREIGN_KEY_CHECKS = 1;完成上面的操作后,我們就可以修改數(shù)據(jù)源信息了,使用 set 命令修改 data :# 修改 imooc 數(shù)據(jù)庫(kù)為 wiki 數(shù)據(jù)庫(kù)set /imooc/datasource {"Username":"root","DriverClassName":"com.mysql.cj.jdbc.Driver","Url":"jdbc:mysql://localhost:3306/wiki?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai","Password":"021998"}執(zhí)行修改命令后,我我們查看控制臺(tái)輸出:{dataSource-0} restart{dataSource-0} closing ...{dataSource-0} closed{dataSource-1} inited>>> 從配置中心更新數(shù)據(jù)源: {"Username":"root","DriverClassName":"com.mysql.cj.jdbc.Driver","Url":"jdbc:mysql://localhost:3306/wiki?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai","Password":"021998"}我們發(fā)現(xiàn),dataSource 重新啟動(dòng)并初始化了。接下來(lái)我們?cè)僭L問(wèn) http://localhost:8888/imooc/getAll 來(lái)查詢數(shù)據(jù)庫(kù)的數(shù)據(jù):[{"id":1,"username":"C","password":"789","phone":"987","address":"北京"},{"id":2,"username":"C#","password":"567","phone":"765","address":"上海"},{"id":3,"username":"C++","password":"654","phone":"456","address":"深圳"}]我們發(fā)現(xiàn)數(shù)據(jù)變成了 wiki 數(shù)據(jù)庫(kù)的信息,說(shuō)明我們的動(dòng)態(tài)數(shù)據(jù)源配置成功。
中綴調(diào)用實(shí)際上就是把原來(lái)只有一個(gè)參數(shù)的函數(shù)調(diào)用簡(jiǎn)化成兩個(gè)操作直接使用類似中綴運(yùn)算符調(diào)用,省略了類名或者 對(duì)象名+"."+函數(shù)名 調(diào)用方式:例子1 初始化 map:package com.imooc.kotlin.infix//普通利用Pair()初始化一個(gè)mapfun main(args: Array<String>) { val map = mapOf(Pair(1, "A"), Pair(2, "B"), Pair(3, "C")) map.forEach { key, value -> println("key: $key value:$value") }}//利用to函數(shù)初始化一個(gè)mapfun main(args: Array<String>) { val map = mapOf(1.to("A"), 2.to("B"), 3.to("C")) map.forEach { key, value -> println("key: $key value:$value") }}//利用to函數(shù)中綴調(diào)用初始化一個(gè)mapfun main(args: Array<String>) { val map = mapOf(1 to "A", 2 to "B", 3 to "C")//to實(shí)際上一個(gè)返回Pair對(duì)象的函數(shù),不是屬于map結(jié)構(gòu)內(nèi)部的運(yùn)算符,但是to在語(yǔ)法層面使用很像中綴運(yùn)算符調(diào)用 map.forEach { key, value -> println("key: $key value:$value") }}例子2 字符串比較://普通使用字符串對(duì)比調(diào)用StringUtils.equals(strA, strB)fun main(args: Array<String>) { val strA = "A" val strB = "B" if (StringUtils.equals(strA, strB)) {//這里對(duì)比字符串是了apache中的StringUtils println("str is the same") } else { println("str is the different") }}//利用中綴調(diào)用sameAs對(duì)比兩個(gè)字符串fun main(args: Array<String>) { val strA = "A" val strB = "B" if (strA sameAs strB) {//中綴調(diào)用 sameAs println("str is the same") } else { println("str is the different") }}
找到系統(tǒng)變量的新建按鈕,點(diǎn)擊添加一個(gè)新的環(huán)境變量。為其變量名設(shè)置為 JAVA_HOME,變量值設(shè)置為我們剛剛的Java安裝目錄:C:\Program Files\Java\jdk-15.0.1,點(diǎn)擊確定保存環(huán)境變量。
解壓文件,一般解壓到/usr/local。解壓后得到/usr/local/go文件夾,這一步可能需要 root 權(quán)限,如果你是 root 賬號(hào),則可以不加 sudo 。sudo tar -C /usr/local -zxvf go1.13.5.linux-amd64.tar.gz解壓 Go 語(yǔ)言的安裝包
Top Down 標(biāo)簽顯示一個(gè)調(diào)用列表,在該列表中展開方法或函數(shù)節(jié)點(diǎn)會(huì)顯示它的被調(diào)用方。如下圖所示,在 Top Down 標(biāo)簽頁(yè)中展開方法 A 的節(jié)點(diǎn)會(huì)顯示它的被調(diào)用方,即方法 B 和 D。在此之后,展開方法 D 的節(jié)點(diǎn)會(huì)顯示它的被調(diào)用方,即方法 B 和 C,依此類推。與 Flame chart 標(biāo)簽頁(yè)類似, Top Down 樹也匯總了具有相同調(diào)用堆棧的完全相同的方法的跟蹤信息。也就是說(shuō),F(xiàn)lame chart 標(biāo)簽頁(yè)提供了 Top down 標(biāo)簽頁(yè)的圖形表示方式。Top Down 標(biāo)簽提供以下信息來(lái)幫助說(shuō)明在每個(gè)調(diào)用上所花的 CPU 時(shí)間(時(shí)間也可表示為在選定范圍內(nèi)占線程總時(shí)間的百分比):Self:方法或函數(shù)調(diào)用在執(zhí)行自己的代碼(而非被調(diào)用方的代碼)上所花的時(shí)間;Children:方法或函數(shù)調(diào)用在執(zhí)行它的被調(diào)用方(而非自己的代碼)上所花的時(shí)間;Total:方法的 Self 時(shí)間和 Children 時(shí)間的總和。這表示應(yīng)用在執(zhí)行調(diào)用時(shí)所用的總時(shí)間。Bottom Up 標(biāo)簽頁(yè)顯示一個(gè)調(diào)用列表,在該列表中展開函數(shù)或方法的節(jié)點(diǎn)會(huì)顯示它的調(diào)用方。如下圖,提供了方法 C 的 Bottom Up 樹。在該 Bottom Up 樹中打開方法 C 的節(jié)點(diǎn)會(huì)顯示它獨(dú)有的各個(gè)調(diào)用方,即方法 B 和 D。請(qǐng)注意,盡管 B 調(diào)用 C 兩次,但在“Bottom Up”樹中展開方法 C 的節(jié)點(diǎn)時(shí),B 僅顯示一次。在此之后,展開 B 的節(jié)點(diǎn)會(huì)顯示它的調(diào)用方,即方法 A 和 D。Bottom Up 標(biāo)簽頁(yè)用于按照占用的 CPU 時(shí)間由多到少(或由少到多)的順序?qū)Ψ椒ɑ蚝瘮?shù)排序。我們可以檢查每個(gè)節(jié)點(diǎn)以確定哪些調(diào)用方在調(diào)用這些方法或函數(shù)上所花的 CPU 時(shí)間最多。 與 Top Down 樹相比, Bottom Up 樹中每個(gè)方法或函數(shù)的時(shí)間信息參照的是每個(gè)樹頂部的方法(頂部節(jié)點(diǎn))。 CPU 時(shí)間也可表示為在該記錄期間占線程總時(shí)間的百分比。
對(duì)于 C 語(yǔ)言來(lái)說(shuō),由于考慮到效率的問(wèn)題的。數(shù)組的傳遞一般都是不復(fù)制的。因此函數(shù)中如果傳入的是數(shù)組,那么在被調(diào)用的函數(shù)中其實(shí)就是傳入了原始函數(shù)中的數(shù)組,而不是一個(gè)副本。