2017.11.13 Dictionary、正則表達(dá)式、 容器介紹、 Python、 Flex布局

1. Dictionary

和java中的Map類似,可以用來(lái)存放鍵值對(duì)。

說(shuō)明

必須包含名空間System.Collection.Generic
Dictionary里面的每一個(gè)元素都是一個(gè)鍵值對(duì)(由二個(gè)元素組成:鍵和值)
鍵必須是唯一的,而值不需要唯一的
鍵和值都可以是任何類型(比如:string, int, 自定義類型,等等)
通過(guò)一個(gè)鍵讀取一個(gè)值的時(shí)間是接近O(1)
鍵值對(duì)之間的偏序可以不定義

  • 創(chuàng)建及初始化
 Dictionary<int,string>myDictionary=newDictionary<int,string>();
  • 添加元素
myDictionary.Add(1,"C#");
myDictionary.Add(2,"C++");
myDictionary.Add(3,"ASP.NET"); 
myDictionary.Add(4,"MVC");
  • 通過(guò)Key查找元素
if(myDictionary.ContainsKey(1))
{
Console.WriteLine("Key:{0},Value:{1}","1", myDictionary[1]);
 }
  • 通過(guò)KeyValuePair遍歷元素
foreach(KeyValuePair<int,string>kvp in myDictionary)
...{
Console.WriteLine("Key = {0}, Value = {1}",kvp.Key, kvp.Value);
}
  • 僅遍歷鍵 Keys 屬性
Dictionary<int,string>.KeyCollection keyCol=myDictionary.Keys;
foreach(intkeyinkeyCol)
...{
Console.WriteLine("Key = {0}", key);
}
  • 僅遍歷值 Valus屬性
Dictionary<int,string>.ValueCollection valueCol=myDictionary.Values;
foreach(stringvalueinvalueCol)
...{
Console.WriteLine("Value = {0}", value);
}
  • 通過(guò)Remove方法移除指定的鍵值
myDictionary.Remove(1);
if(myDictionary.ContainsKey(1))
...{
  Console.WriteLine("Key:{0},Value:{1}","1", myDictionary[1]);
}
else
{
Console.WriteLine("不存在 Key : 1"); 
 }

下面是我自己的例子:


image.png
image.png
image.png

2. 正則表達(dá)式/HTML圖片顯示/Select下拉框

2.1 正則表達(dá)式

正則表達(dá)式,又稱規(guī)則表達(dá)式,英文名為Regular Expression,在代碼中常簡(jiǎn)寫(xiě)為regex、regexp或RE,是計(jì)算機(jī)科學(xué)的一個(gè)概念。正則表通常被用來(lái)檢索、替換那些符合某個(gè)模式(規(guī)則)的文本。

正則表達(dá)式是對(duì)字符串(包括普通字符(例如,a 到 z 之間的字母)和特殊字符(稱為“元字符”))操作的一種邏輯公式,就是用事先定義好的一些特定字符、及這些特定字符的組合,組成一個(gè)“規(guī)則字符串”,這個(gè)“規(guī)則字符串”用來(lái)表達(dá)對(duì)字符串的一種過(guò)濾邏輯。正則表達(dá)式是一種文本模式,模式描述在搜索文本時(shí)要匹配的一個(gè)或多個(gè)字符串。


image.png

上圖為控制輸入框的內(nèi)容不能為漢字的正則表達(dá)式。每個(gè)符號(hào)所代表的意思如下:


image.png
2.2 HTML圖片顯示

在使用<img>標(biāo)簽顯示圖片時(shí),如果圖片太大顯示會(huì)超出div的大小。這回導(dǎo)致頁(yè)面可以橫向滑動(dòng),但是沒(méi)有圖片的地方div大小正常,被圖片撐大的部分顯示的就是上一個(gè)頁(yè)面的內(nèi)容。

水平方向撐開(kāi)的解決方法就是添加style=”display:block;width:100%。其中,display:block;此元素將顯示為塊級(jí)元素,此元素前后會(huì)帶有換行符。width:100%,將寬度設(shè)為100%,這個(gè)塊級(jí)元素寬度就被固定了。該元素不會(huì)被撐開(kāi),而是按比例縮小顯示。

如果加入圖片較小能在一個(gè)頁(yè)面顯示可以按照水平方向的解決方法加上height:100%解決,但是如果圖片較大,需要下拉??梢栽陧?yè)面加一個(gè)滾動(dòng)條style="overflow-y: scroll;"原本未加滾動(dòng)條時(shí),因?yàn)閳D片大將<img>元素?fù)未?,不在所框住的div內(nèi),也能下拉,但是能看到上一頁(yè)面的未覆蓋的內(nèi)容。加了y方向的滾動(dòng)條后就能解決這一問(wèn)題。

2.3 Select下拉框

在 HTML 表單中,<select> 標(biāo)簽每出現(xiàn)一次,一個(gè) Select 對(duì)象就會(huì)被創(chuàng)建。在使用選擇框時(shí),如需要默認(rèn)初始值,添加selected = 'selected'; 屬性,該選項(xiàng)即為默認(rèn)選項(xiàng)。


image.png

在制作下拉框時(shí),需要將默認(rèn)顯示為“請(qǐng)選擇”,但是選項(xiàng)沒(méi)有“請(qǐng)選擇”項(xiàng)時(shí),可以使用
image.png

將初始val賦為空,這樣“請(qǐng)選擇”項(xiàng)的val即為空,世紀(jì)選項(xiàng)就沒(méi)有“請(qǐng)選擇”項(xiàng)了。

源碼:

<input type="text" class="uc-a1" style="border: none;font-size: 
0.8125em;"id="RelaCredNo"onkeyup="value=value.replace(/[^\w\.\/]/ig,'')">
<div class="bc-bg" tabindex="0" data-control="PAGE" id="Page" style="overflow-y: scroll">
$("#show_img").append('<img src="'+relaImage+'" style="display:block;width:100%">');
  var result = JSON.parse(appcan.locStorage.getVal("selectRelaType"));
        var str = "";
        str += "<option value=''  selected = 'selected'>請(qǐng)選擇</option>";
        if (result.indexOf("本人|") < 0) {
            str += "<option value='1'>本人</option>";
        }
        if (result.indexOf("父親|") < 0) {
            str += "<option value='2'>父親</option>";
        }
        if (result.indexOf("母親|") < 0) {
            str += "<option value='3'>母親</option>";
        }
        if (result.indexOf("配偶父|") < 0) {
            str += "<option value='4'>配偶父</option>";
        }
        if (result.indexOf("配偶母|") < 0) {
            str += "<option value='5'>配偶母</option>";
        }
        if (result.indexOf("配偶|") < 0) {
            str += "<option value='6'>配偶</option>";
        }
        str += "<option value='7'>子女</option>";
        $("#RelaType").append(str);
        $('#RelaType').val("");
        $("#RelaCredType").append("<option value=''  selected = 'selected'>請(qǐng)選擇</option>
<option value='1'>身份證</option><option value='2'>護(hù)照</option>");
        $('#RelaCredType').val("");

3. 容器介紹

3.1 Array/ArrayList/List/LinkedList
  • Array

數(shù)組在C#中最早出現(xiàn)的。在內(nèi)存中是連續(xù)存儲(chǔ)的,所以它的索引速度非???,而且賦值與修改元素也很簡(jiǎn)單。

1.  string[] s=new string[2];   
2.    
3.  //賦值   
4.  s[0]="a";   
5.  s[1]="b";   
6.  //修改   
7.  s[1]="a1";   

但是數(shù)組存在一些不足的地方。在數(shù)組的兩個(gè)數(shù)據(jù)間插入數(shù)據(jù)是很麻煩的,而且在聲明數(shù)組的時(shí)候必須指定數(shù)組的長(zhǎng)度,數(shù)組的長(zhǎng)度過(guò)長(zhǎng),會(huì)造成內(nèi)存浪費(fèi),過(guò)短會(huì)造成數(shù)據(jù)溢出的錯(cuò)誤。如果在聲明數(shù)組時(shí)我們不清楚數(shù)組的長(zhǎng)度,就會(huì)變得很麻煩。

針對(duì)數(shù)組的這些缺點(diǎn),C#中最先提供了ArrayList對(duì)象來(lái)克服這些缺點(diǎn)。

底層數(shù)據(jù)結(jié)構(gòu)就是數(shù)組。

  • ArrayList

    ArrayList是命名空間System.Collections下的一部分,在使用該類時(shí)必須進(jìn)行引用,同時(shí)繼承了IList接口,提供了數(shù)據(jù)存儲(chǔ)和檢索。ArrayList對(duì)象的大小是按照其中存儲(chǔ)的數(shù)據(jù)來(lái)動(dòng)態(tài)擴(kuò)充與收縮的。所以,在聲明ArrayList對(duì)象時(shí)并不需要指定它的長(zhǎng)度。

1.  ArrayList list1 = new ArrayList();   
2.    
3.  //新增數(shù)據(jù)   
4.  list1.Add("cde");   
5.  list1.Add(5678);   
6.    
7.  //修改數(shù)據(jù)   
8.  list[2] = 34;   
9.    
10. //移除數(shù)據(jù)   
11. list.RemoveAt(0);   
12.   
13. //插入數(shù)據(jù)   
14. list.Insert(0, "qwe");   

從上面例子看,ArrayList好像是解決了數(shù)組中所有的缺點(diǎn),為什么又會(huì)有List?

我們從上面的例子看,在List中,我們不僅插入了字符串cde,而且插入了數(shù)字5678。這樣在ArrayList中插入不同類型的數(shù)據(jù)是允許的。因?yàn)锳rrayList會(huì)把所有插入其中的數(shù)據(jù)當(dāng)作為object類型來(lái)處理,在我們使用ArrayList處理數(shù)據(jù)時(shí),很可能會(huì)報(bào)類型不匹配的錯(cuò)誤,也就是ArrayList不是類型安全的。在存儲(chǔ)或檢索值類型時(shí)通常發(fā)生裝箱和取消裝箱操作,帶來(lái)很大的性能耗損。

裝箱與拆箱的概念:
裝箱:就是將值類型的數(shù)據(jù)打包到引用類型的實(shí)例中比如將string類型的值abc賦給object對(duì)象obj

1.  String i=”abc”;   
2.  object obj=(object)i; 

拆箱:就是從引用數(shù)據(jù)中提取值類型

比如將object對(duì)象obj的值賦給string類型的變量i。

1.  object obj=”abc”;   
2.  string i=(string)obj;   

裝箱與拆箱的過(guò)程是很損耗性能的。

底層數(shù)據(jù)結(jié)構(gòu)就是數(shù)組。類似于C++里面沒(méi)有泛型的Vector。

  • 泛型List

因?yàn)锳rrayList存在不安全類型與裝箱拆箱的缺點(diǎn),所以出現(xiàn)了泛型的概念。List類是ArrayList類的泛型等效類,它的大部分用法都與ArrayList相似,因?yàn)長(zhǎng)ist類也繼承了IList接口。最關(guān)鍵的區(qū)別在于,在聲明List集合時(shí),我們同時(shí)需要為其聲明List集合內(nèi)數(shù)據(jù)的對(duì)象類型。

比如:

1.  List<string> list = new List<string>();   
2.  //新增數(shù)據(jù)   
3.  list.Add(“abc”);   
4.  //修改數(shù)據(jù)   
5.  list[0] = “def”;   
6.  //移除數(shù)據(jù)   
7.  list.RemoveAt(0);   

上例中,如果我們往List集合中插入int數(shù)組123,IDE就會(huì)報(bào)錯(cuò),且不能通過(guò)編譯。這樣就避免了前面講的類型安全問(wèn)題與裝箱拆箱的性能問(wèn)題了。

底層數(shù)據(jù)結(jié)構(gòu)就是數(shù)組。類似于C++里面的Vector。

  • LinkedList

用雙鏈表實(shí)現(xiàn)的List,特點(diǎn)是插入刪除快,查找慢

LinkedList<T> 提供 LinkedListNode<T> 類型的單獨(dú)節(jié)點(diǎn),因此插入和移除的運(yùn)算復(fù)雜度為 O(1)。

可以移除節(jié)點(diǎn),然后在同一列表或其他列表中重新插入它們,這樣在堆中便不會(huì)分配額外的對(duì)象。由于該列表還維護(hù)內(nèi)部計(jì)數(shù),因此獲取 Count 屬性的運(yùn)算復(fù)雜度為 O(1)。

LinkedList<T> 對(duì)象中的每個(gè)節(jié)點(diǎn)都屬于 LinkedListNode<T> 類型。由于 LinkedList<T> 是雙向鏈表,因此每個(gè)節(jié)點(diǎn)向前指向 Next 節(jié)點(diǎn),向后指向 Previous 節(jié)點(diǎn)。

1.  LinkedList<string> list = new LinkedList<string>();  
2.  list.AddFirst("Data Value 1");  
3.  list.AddLast("Data Value 6");  

關(guān)于List和LonkedList的一個(gè)性能比較

  • 增加 刪除

在List<T>中增加、刪除節(jié)點(diǎn)的速度,大體上快于使用LinkedList<T>時(shí)的相同操作。將 List<T>.Add方法和LinkedList<T>的Add*方法相比較,真正的性能差別不在于Add操作,而在LinkedList<T>在給GC(垃圾回收機(jī)制)的壓力上。一個(gè)List<T>本質(zhì)上是將其數(shù)據(jù)保存在一個(gè)堆棧的數(shù)組上,而LinkedList<T>是將其所有節(jié)點(diǎn)保存在堆棧上(人家是一個(gè),我是一系列)。這就使得GC需要更多地管理堆棧上LinkedList<T>的節(jié)點(diǎn)對(duì)象。注意,List<T>.Insert方法比在LinkedList<T>中使用Add方法在任何地方添加一個(gè)節(jié)點(diǎn)可能要慢。然而,這個(gè)依賴于List<T>插入對(duì)象的位置。Insert方法必須使所有在插入點(diǎn)后面的元素往后移動(dòng)一位。如果新元素被插在List<T>最后或接近最后的位置,那么相對(duì)于GC維護(hù)LinkedList<T>節(jié)點(diǎn)的總的開(kāi)銷(xiāo)來(lái)說(shuō),其開(kāi)銷(xiāo)是可以被忽略的。

  • 索引

另一個(gè)List<T>性能優(yōu)于LinkedList<T>的地方是你在使用索引進(jìn)行訪問(wèn)的時(shí)候。在List<T>中,你可以使用索引值(indexer)直接定位到某個(gè)具體的元素位置。而在LinkedList<T>中,卻沒(méi)有這樣的奢侈品。在LinkedList<T>中,你必須通過(guò)Previous或Next屬性遍歷整個(gè)List,直到找到你想要的節(jié)點(diǎn)。

3.2 HashSet/HashTable/Dictionary

這三個(gè)容器的底層都是Hash表。

  • HashSet

MSDN很簡(jiǎn)單的解釋:表示值的集。

HashSet<T> 類提供了高性能的集運(yùn)算。一組是一個(gè)集合,不包含任何重復(fù)的元素,且的元素順序不分先后。

用了hash table來(lái)儲(chǔ)存數(shù)據(jù),是為了用O(n)的space來(lái)?yè)Q取O(n)的時(shí)間,也就是查找元素的時(shí)間是O(1)。

它包含一些集合的運(yùn)算

HashSet<T> 提供了許多數(shù)學(xué)設(shè)置操作例如,組添加 (聯(lián)合),并設(shè)置減法。下表列出了所提供 HashSet<T> 操作和及其數(shù)學(xué)等效項(xiàng)。

 UnionWith - Union 或?qū)⑵湓O(shè)置的添加
IntersectWith - 交集
ExceptWith - Set 減法
SymmetricExceptWith - 余集

列出的集操作中,除了 HashSet<T> 類還提供了方法來(lái)確定 set 是否相等、 重疊的集,以及一組是否為子集或另一個(gè)集的超集。

example

1.   HashSet<int> evenNumbers = new HashSet<int>();  
2.  HashSet<int> oddNumbers = new HashSet<int>();  
3.    
4.  for (int i = 0; i < 5; i++)  
5.  {  
6.       // Populate numbers with just even numbers.  
7.        evenNumbers.Add(i * 2);  
8.       // Populate oddNumbers with just odd numbers.  
9.       oddNumbers.Add((i * 2) + 1);  
10. }  
11.  // Create a new HashSet populated with even numbers.  
12. HashSet<int> numbers = new HashSet<int>(evenNumbers);  
13.  numbers.UnionWith(oddNumbers);  
  • HashTable

表示根據(jù)鍵的哈希代碼進(jìn)行組織的鍵/值對(duì)的集合。

Hashtable是System.Collections命名空間提供的一個(gè)容器,用于處理和表現(xiàn)類似key/value的鍵值對(duì),其中key通常可用來(lái)快速查找,同時(shí)key是區(qū)分大小寫(xiě);value用于存儲(chǔ)對(duì)應(yīng)于key的值。

Hashtable中key/value鍵值對(duì)均為object類型,所以Hashtable可以支持任何類型的key/value鍵值對(duì).

他內(nèi)部維護(hù)很多對(duì)Key-Value鍵值對(duì),其還有一個(gè)類似索引的值叫做散列值(HashCode),它是根據(jù)GetHashCode方法對(duì)Key通過(guò)一定算法獲取得到的,所有的查找操作定位操作都是基于散列值來(lái)實(shí)現(xiàn)找到對(duì)應(yīng)的Key和Value值的

當(dāng)前HashTable中的被占用空間達(dá)到一個(gè)百分比的時(shí)候就將該空間自動(dòng)擴(kuò)容,在.net中這個(gè)百分比是72%,也叫.net中HashTable的填充因子為0.72。例如有一個(gè)HashTable的空間大小是100,當(dāng)它需要添加第73個(gè)值的時(shí)候?qū)?huì)擴(kuò)容此HashTable.

這個(gè)自動(dòng)擴(kuò)容的大小是多少呢?答案是當(dāng)前空間大小的兩倍最接近的素?cái)?shù),例如當(dāng)前HashTable所占空間為素?cái)?shù)71,如果擴(kuò)容,則擴(kuò)容大小為素?cái)?shù)131.

1.   Hashtable openWith = new Hashtable();  
2.    
3.  // Add some elements to the hash table. There are no   
4.  // duplicate keys, but some of the values are duplicates.  
5.  openWith.Add("txt", "notepad.exe");  
6.  openWith.Add("bmp", "paint.exe");  
7.  openWith.Add("dib", "paint.exe");  
8.  openWith.Add("rtf", "wordpad.exe");  

HashTable也有Boxing和Unboxing的開(kāi)銷(xiāo)。

然后就有了

  • Dictionary

Dictionary也是鍵值容器,存入對(duì)象是需要與[key]值一一對(duì)應(yīng)的存入該泛型。相對(duì)于HashTable,類似于List和ArrayList的關(guān)系。它是類型安全的。

1.  Dictionary<string, string> myDic = new Dictionary<string, string>();  
2.  myDic.Add("aaa", "111");  
3.  myDic.Add("bbb", "222");  
4.  myDic.Add("ccc", "333");  
5.  myDic.Add("ddd", "444");  
  • 小結(jié)

數(shù)組的容量是固定的,您只能一次獲取或設(shè)置一個(gè)元素的值,而ArrayList或List<T>的容量可根據(jù)需要自動(dòng)擴(kuò)充、修改、刪除或插入數(shù)據(jù)。

數(shù)組可以具有多個(gè)維度,而 ArrayList或 List< T> 始終只具有一個(gè)維度。但是,您可以輕松創(chuàng)建數(shù)組列表或列表的列表。特定類型(Object 除外)的數(shù)組 的性能優(yōu)于 ArrayList的性能。 這是因?yàn)?ArrayList的元素屬于 Object 類型;所以在存儲(chǔ)或檢索值類型時(shí)通常發(fā)生裝箱和取消裝箱操作。不過(guò),在不需要重新分配時(shí)(即最初的容量十分接近列表的最大容量),List< T> 的性能與同類型的數(shù)組十分相近。

在決定使用 List<T> 還是使用ArrayList 類(兩者具有類似的功能)時(shí),記住List<T> 類在大多數(shù)情況下執(zhí)行得更好并且是類型安全的。如果對(duì)List< T> 類的類型T 使用引用類型,則兩個(gè)類的行為是完全相同的。但是,如果對(duì)類型T使用值類型,則需要考慮實(shí)現(xiàn)和裝箱問(wèn)題。
所以基本不怎么用ArrayList.

還要注意的一點(diǎn)

在單線程的時(shí)候使用Dictionary更好一些,多線程的時(shí)候使用HashTable更好。

因?yàn)镠ashTable可以通過(guò)Hashtable tab = Hashtable.Synchronized(new Hashtable());獲得線程安全的對(duì)象。


網(wǎng)上找的C#學(xué)習(xí)內(nèi)容:

HTML---css/div---- SQL----C#----面向?qū)ο?----設(shè)計(jì)模式----MVC----EntityFramework-----C#深入了解-----WebForm-----javascript----jquery----angularJS----.netCore------現(xiàn)在。。。。

往后我可能要繼續(xù)學(xué)習(xí)-----架構(gòu)----深入理解設(shè)計(jì)模式------.netCore-----NodeJs.------Git-----Docker
還有Unity3D------操作系統(tǒng)-----編譯原理-----數(shù)據(jù)結(jié)構(gòu)等。。。。。。。


4. Python多線程與多線程中join()的用法

Python多線程與多進(jìn)程中join()方法的效果是相同的。

下面僅以多線程為例:

首先需要明確幾個(gè)概念:

  • 知識(shí)點(diǎn)一:
    當(dāng)一個(gè)進(jìn)程啟動(dòng)之后,會(huì)默認(rèn)產(chǎn)生一個(gè)主線程,因?yàn)榫€程是程序執(zhí)行流的最小單元,當(dāng)設(shè)置多線程時(shí),主線程會(huì)創(chuàng)建多個(gè)子線程,在python中,默認(rèn)情況下(其實(shí)就是setDaemon(False)),主線程執(zhí)行完自己的任務(wù)以后,就退出了,此時(shí)子線程會(huì)繼續(xù)執(zhí)行自己的任務(wù),直到自己的任務(wù)結(jié)束,例子見(jiàn)下面一。

  • 知識(shí)點(diǎn)二:
    當(dāng)我們使用setDaemon(True)方法,設(shè)置子線程為守護(hù)線程時(shí),主線程一旦執(zhí)行結(jié)束,則全部線程全部被終止執(zhí)行,可能出現(xiàn)的情況就是,子線程的任務(wù)還沒(méi)有完全執(zhí)行結(jié)束,就被迫停止,例子見(jiàn)下面二。

  • 知識(shí)點(diǎn)三:
    此時(shí)join的作用就凸顯出來(lái)了,join所完成的工作就是線程同步,即主線程任務(wù)結(jié)束之后,進(jìn)入阻塞狀態(tài),一直等待其他的子線程執(zhí)行結(jié)束之后,主線程在終止,例子見(jiàn)下面三。

  • 知識(shí)點(diǎn)四:
    join有一個(gè)timeout參數(shù):

  1. 當(dāng)設(shè)置守護(hù)線程時(shí),含義是主線程對(duì)于子線程等待timeout的時(shí)間將會(huì)殺死該子線程,最后退出程序。所以說(shuō),如果有10個(gè)子線程,全部的等待時(shí)間就是每個(gè)timeout的累加和。簡(jiǎn)單的來(lái)說(shuō),就是給每個(gè)子線程一個(gè)timeout的時(shí)間,讓他去執(zhí)行,時(shí)間一到,不管任務(wù)有沒(méi)有完成,直接殺死。
  2. 沒(méi)有設(shè)置守護(hù)線程時(shí),主線程將會(huì)等待timeout的累加和這樣的一段時(shí)間,時(shí)間一到,主線程結(jié)束,但是并沒(méi)有殺死子線程,子線程依然可以繼續(xù)執(zhí)行,直到子線程全部結(jié)束,程序退出。
4.1 Python多線程的默認(rèn)情況
import threading
import time

def run():
    time.sleep(2)
    print('當(dāng)前線程的名字是: ', threading.current_thread().name)
    time.sleep(2)


if __name__ == '__main__':

    start_time = time.time()

    print('這是主線程:', threading.current_thread().name)
    thread_list = []
    for i in range(5):
        t = threading.Thread(target=run)
        thread_list.append(t)

    for t in thread_list:
        t.start()

    print('主線程結(jié)束!' , threading.current_thread().name)
    print('一共用時(shí):', time.time()-start_time)

其執(zhí)行結(jié)果如下

C:\Users\yuanyizhang\AppData\Local\Programs\Python\Python36-32\python.exe 
C:/Users/yuanyizhang/PycharmProjects/untitled/test.py

這是主線程: MainThread
主線程結(jié)束! MainThread
一共用時(shí): 0.0020051002502441406
當(dāng)前線程的名字是:  Thread-1
當(dāng)前線程的名字是:  Thread-5
當(dāng)前線程的名字是:  Thread-4
當(dāng)前線程的名字是:  Thread-3
當(dāng)前線程的名字是:  Thread-2

Process finished with exit code 0
關(guān)鍵點(diǎn):
  1. 我們的計(jì)時(shí)是對(duì)主線程計(jì)時(shí),主線程結(jié)束,計(jì)時(shí)隨之結(jié)束,打印出主線程的用時(shí)。
  2. 主線程的任務(wù)完成之后,主線程隨之結(jié)束,子線程繼續(xù)執(zhí)行自己的任務(wù),直到全部的子線程的任務(wù)全部結(jié)束,程序結(jié)束。
4.2 設(shè)置守護(hù)線程
import threading
import time

def run():

    time.sleep(2)
    print('當(dāng)前線程的名字是: ', threading.current_thread().name)
    time.sleep(2)


if __name__ == '__main__':

    start_time = time.time()

    print('這是主線程:', threading.current_thread().name)
    thread_list = []
    for i in range(5):
        t = threading.Thread(target=run)
        thread_list.append(t)

    for t in thread_list:
        t.setDaemon(True)
        t.start()

    print('主線程結(jié)束了!' , threading.current_thread().name)
    print('一共用時(shí):', time.time()-start_time)

其執(zhí)行結(jié)果如下,注意請(qǐng)確保setDaemon()在start()之前。

C:\Users\yuanyizhang\AppData\Local\Programs\Python\Python36-32\python.exe 
C:/Users/yuanyizhang/PycharmProjects/untitled/test.py

這是主線程: MainThread
主線程結(jié)束了! MainThread
一共用時(shí): 0.0010030269622802734

Process finished with exit code 0

關(guān)鍵點(diǎn):
  1. 非常明顯的看到,主線程結(jié)束以后,子線程還沒(méi)有來(lái)得及執(zhí)行,整個(gè)程序就退出了。

4.3 join的作用

import threading
import time

def run():

    time.sleep(2)
    print('當(dāng)前線程的名字是: ', threading.current_thread().name)
    time.sleep(2)


if __name__ == '__main__':

    start_time = time.time()

    print('這是主線程:', threading.current_thread().name)
    thread_list = []
    for i in range(5):
        t = threading.Thread(target=run)
        thread_list.append(t)

    for t in thread_list:
        t.setDaemon(True)
        t.start()

    for t in thread_list:
        t.join()

    print('主線程結(jié)束了!' , threading.current_thread().name)
    print('一共用時(shí):', time.time()-start_time)

其執(zhí)行結(jié)果如下:

這是主線程: MainThread
當(dāng)前線程的名字是:  Thread-1
當(dāng)前線程的名字是:  Thread-2
當(dāng)前線程的名字是:  Thread-4
當(dāng)前線程的名字是:  Thread-5
當(dāng)前線程的名字是:  Thread-3
主線程結(jié)束了! MainThread
一共用時(shí): 4.004054546356201
關(guān)鍵點(diǎn):
  1. 可以看到,主線程一直等待全部的子線程結(jié)束之后,主線程自身才結(jié)束,程序退出。
  2. 可以通過(guò)join(time)設(shè)置時(shí)間 控制主線程是否等待子線程結(jié)束再結(jié)束,設(shè)置時(shí)間較小時(shí),等待時(shí)間不足,主線程會(huì)先結(jié)束(本例可設(shè)置join(0.3)),時(shí)間足夠長(zhǎng)時(shí),主線程等待足夠時(shí)間,子線程可以全部結(jié)束(本例設(shè)置join(1))

5. Flex布局

flex 做布局太容易了,尤其是在垂直居中這方面

布局的傳統(tǒng)解決方案,基于盒狀模型,依賴 display 屬性 + position屬性 + float屬性。它對(duì)于那些特殊布局非常不方便,比如,垂直居中就不容易實(shí)現(xiàn)。

Flex 是 Flexible Box 的縮寫(xiě),意為"彈性布局",用來(lái)為盒狀模型提供最大的靈活性。

任何一個(gè)容器都可以指定為 Flex 布局。

.box{
  display: flex;
}

行內(nèi)元素也可以使用 Flex 布局。

.box{
  display: inline-flex;
}

Webkit 內(nèi)核的瀏覽器,必須加上-webkit前綴。

注意,設(shè)為 Flex 布局以后,子元素的float、clear和vertical-align屬性將失效。


image.png

容器默認(rèn)存在兩根軸:水平的主軸(main axis)和垂直的交叉軸(cross axis)。主軸的開(kāi)始位置(與邊框的交叉點(diǎn))叫做main start,結(jié)束位置叫做main end;交叉軸的開(kāi)始位置叫做cross start,結(jié)束位置叫做cross end。

項(xiàng)目默認(rèn)沿主軸排列。單個(gè)項(xiàng)目占據(jù)的主軸空間叫做main size,占據(jù)的交叉軸空間叫做cross size。

容器的屬性

以下6個(gè)屬性設(shè)置在容器上。

flex-direction
flex-wrap
flex-flow
justify-content
align-items

具體各個(gè)屬性值與作用參考
http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 34,741評(píng)論 18 399
  • java筆記第一天 == 和 equals ==比較的比較的是兩個(gè)變量的值是否相等,對(duì)于引用型變量表示的是兩個(gè)變量...
    jmychou閱讀 1,656評(píng)論 0 3
  • (一)Java部分 1、列舉出JAVA中6個(gè)比較常用的包【天威誠(chéng)信面試題】 【參考答案】 java.lang;ja...
    獨(dú)云閱讀 7,265評(píng)論 0 62
  • 很累、很糗 一縷浮光 風(fēng)景還在 很美
    阿拉斯加的霾閱讀 178評(píng)論 0 0
  • 作者:健美頌 §1 驅(qū)車(chē)風(fēng)動(dòng)石的路上,美景如畫(huà),讓突然掠過(guò)眼前的“寡婦村”三個(gè)字顯得格格不入。 “老而無(wú)夫謂之寡”...
    健美頌閱讀 316評(píng)論 0 0

友情鏈接更多精彩內(nèi)容