浙江跟進 年底起限用一次性消費用品

摘錄自2019年11月6日聯合報報導

繼上海、北京後,浙江也要跟進取消酒店提供一次性洗漱用品與外賣商家配送的一次性筷子和塑膠湯匙。

浙江省政府部門近日發布「關於限制一次性消費用品的通知」,根據新規定,自2019年12月31日起,在浙江省四星級及以上賓館(酒店)推廣不主動提供一次性消費用品,並逐步延伸至其他賓館(酒店)以及民宿、農家樂等提供住宿服務的場所。

新華社報導,新規定特別強調了政府機關的帶頭示範作用,規定在全省黨政機關和國有企事業單位食堂推廣不主動提供一次性筷子、調羹等餐具;黨政機關和國有企事業單位不得使用一次性杯具,單位內部辦公場所、會議室接待統一使用瓷杯或玻璃杯,倡導幹部職工辦公或開會自帶水杯,限制一次性消費用品工作將納入各部門年度考核內容。

目前,中國東部地區已有上海、蘇州、合肥等多個城市明確限制一次性消費用品的使用。

本站聲明:網站內容來源於https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

AVX代理商NICHICON代理商授權有哪幾家?

※怎麼檢測NBR手套規格是否有符合國家認証規定?

大樓隔熱紙施工分享說明,教你如何善用空間裝潢、設計 !

※買不起高檔茶葉,精緻包裝茶葉罐,也能撐場面!

塑膠射出模具射出成型過程大公開 !

※廢氣洗滌塔設計及注意事項 ?

中國北方省市為減輕冬季空汙,強推煤改氣、煤改電汰換工程

中國北方省市為減輕冬季空汙,強推煤改氣、煤改電汰換工程,但是部分地區未能供應充足的天然氣,導致一些民眾在嚴冬中因家中沒有暖氣而受凍。最近,中國廣大地區開始邁入冬季之際,供暖問題又開始浮現,面對激烈的漲價潮,農村一般百姓叫苦連天。

中國業內人士分析,最近氣價急漲包括多個原因,一是每年10月便進入天然氣季節性消費旺季;二是氣源上漲直接帶動了生產成本的增加;三是液化天然氣公司相繼從源頭減少了液化天然氣的供應。

本站聲明:網站內容來源於https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※找工作! 想知道堆高機駕駛日薪是多少嗎? 哪裡有職缺?幫你快速媒合

※隨時健康喝好水,高品質飲水機推薦,優質安全有把關

防爆隔熱紙規格資訊說明

※好的茗茶,更需要密封性高的茶葉罐,才能留住香氣!

※【找人才】台北塑膠射出廠徵選技師,薪資優,福利佳

峨眉山熱門景點增建玻璃牆、水泥護欄 稱防遊客輕生

摘錄自2019年11月6日世界日報北京報導

四川峨眉山為旅遊勝地,每年吸引眾多遊客前往。據媒體報導,攝身崖的金剛嘴景點上,日前竟出現一道道玻璃圍牆,突兀景象,遊客全傻眼。景區負責人表示,此舉主要是在不影響景觀的前提下,盡可能減少輕生事件。

據華西都市報報導,近些年來,峨眉山金頂攝身崖處不時發生遊客輕生事件,不少人建議景區加強應對。近日記者走訪峨眉山金頂片區攝身崖的金剛嘴景點,發現一道道厚厚的玻璃牆將此地圍成一圈,不少遊客表示「不和諧」、「彆扭」、「不自然」。

除了金剛嘴處修了玻璃牆,在往複式索道站旁也新修建了百餘米長的水泥護欄,而此處以前僅有低矮的鐵絲網防護。

金頂工作人員張先生表示,金剛嘴玻璃牆於今年十一假期前修建完畢,上下兩段總長約20餘公尺,高約1.8公尺,主要目的就是為了保障遊客的安全。

本站聲明:網站內容來源於https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※有廠商專門客製化橡膠製品嗎?

噴霧洗滌塔實際應用案例分享

※票選推薦煮婦最愛手壓封口機,省荷包不犧牲品質

※選購空壓機需注意八大事項 !

※DIY自行施工建築隔熱紙,簡易教學大公開 !

※選擇好的茶葉罐,有效地保持茶葉的鮮度與風味!

中國海南海關破獲瀕危加利福尼亞灣石首魚魚鰾走私案

摘錄自2019年11月6日中時電子報報導

中國海南海口海關今(6)日表示,破獲一起走私瀕危加利福尼亞灣石首魚魚鰾案件,涉案的565片魚鰾價值達5300多萬元(人民幣)(約合新台幣23,335元)。

今年5月,海口海關緝私部門在三亞鳳凰機場抓獲由香港乘機入境的犯罪嫌疑人胡某某和梁某,現場查獲藏匿於行李箱中的魚鰾440片。辦案民警此後又在海南、廣東等地相繼抓獲該涉案團夥成員6人,並繳獲魚鰾125片。一個組織嚴密、分工明確的跨國走私犯罪團夥逐漸浮出水面。

加利福尼亞灣石首魚是僅分佈於墨西哥加利福尼亞灣的特有瀕危物種,因受非法捕撈、走私販運及棲息地退化等威脅,加利福尼亞灣石首魚的種群數量持續減少,面臨滅絕風險。1996年,世界自然保護聯盟紅色名錄將其認定爲極度瀕危。

本站聲明:網站內容來源於https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

示波器鮮為人知的使用技巧?

※各大百貨每波促銷贈品活動,限量知名LOGOL型資料夾,獨家販售中!!

飲水機皆有含淨水功能嗎?

※選購空壓機需注意八大事項 !

真空封口機該不該買?使用心得分享

大樓隔熱紙施工分享說明,教你如何善用空間裝潢、設計 !

福建持續高溫乾旱 森林火災風險增高

摘錄自2019年11月6日中新網福州報導

今(2019)年8月以來,福建全省氣溫偏高,降雨較常年同期偏少,部分地區出現氣象乾旱。位於福建北部的南平市降水偏少,已導致水稻、蔬菜、茶葉、柑橘、甘薯、薏米等農作物遭受旱災。

據中國官方資料,截至目前,南平市浦城、順昌、建甌等7個縣(市)12.5萬人受災;農作物受災面積16.1千公頃,其中絕收900餘公頃;直接經濟損失9,200餘萬元人民幣。

廈門市島內達到了氣象重旱的標準,島外為重旱。截至昨(5)日,廈門已經連續61天沒有有效降雨了,這是1956年以來歷史同期首次出現這樣嚴重的氣象旱情。

氣象乾旱持續影響,導致福建多地森林火險氣象等級持續較高。福建省氣象局提醒稱,當天,福建全省大部分縣市森林火險氣象等級為較高危險(三級),龍岩、漳州、泉州、莆田、福州、寧德的部分縣市森林火險氣象等級為高度危險(四級),尤其是莆田荔城區森林火險氣象等級為極度危險(五級)。

本站聲明:網站內容來源於https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※專業客製化禮物、贈品設計,辦公用品常見【L夾】搖身一變大受好評!!

示波器探測執行效能最佳化的8大秘訣

※選用哪種桶裝水,外宿露營超方便?

※(全省)堆高機租賃保養一覽表

※DIY自行施工建築隔熱紙,簡易教學大公開 !

※票選推薦煮婦最愛手壓封口機,省荷包不犧牲品質

江蘇南通在外籍船截獲100隻棕色寡婦蛛及新鮮卵囊

摘錄自2019年11月6日新華社南京報導

據報,南通海關今(6)日通報,該關近日在一艘外籍船舶上,截獲100多頭棕色寡婦蛛及大量新鮮卵囊。目前,海關已對涉事船舶實施除害處理。

10月31日,南通海關在一艘來自大洋洲的巴拿馬籍國際航行船舶上,截獲100多頭棕色寡婦蛛及大量新鮮卵囊。工作人員查閱船舶航海日誌發現,該輪曾於8月6日至9月3日在南太平洋熱帶地區裝載原木,且船長表示裝載時,經常有蜘蛛隨風飄到船上。

「棕色寡婦蛛」是著名的黑寡婦蛛近緣種,分佈於熱帶地區。這種蜘蛛通常對人體局部產生危害,對兒童及體弱者可能致命。有證據表明,其攻擊性和侵略性比黑寡婦蛛強,一旦傳入並定殖,可能威脅民眾生命安全,破壞生態環境。

 

本站聲明:網站內容來源於https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※影響示波器測試準確度的五大因素

※無毒橡膠墊片哪裡買的到?

※飲用桶裝水到底安不安全? 破解錯誤迷思!

※十大封口機人氣排行榜-烘焙必備幫手!

連續封口機購物網-不怕你比價,就怕你買貴!

※買不起高檔茶葉,精緻包裝茶葉罐,也能撐場面!

java基礎階段幾個必會面試題

1.說出你對面向對象的理解

       在我理解,面向對象是向現實世界模型的自然延伸,這是一種“萬物皆對象”的編程思想。在現實生活中的任何物體都可以歸為一類事物,而每一個個體都是一類事物的實例。面向對象的編程是以對象為中心,以消息為驅動,所以程序=對象+消息。
       面向對象有三大特性,封裝、繼承和多態。
       封裝就是將一類事物的屬性和行為抽象成一個類,使其屬性私有化,行為公開化,提高了數據的隱秘性的同時,使代碼模塊化。這樣做使得代碼的復用性更高。
       繼承則是進一步將一類事物共有的屬性和行為抽象成一個父類,而每一個子類是一個特殊的父類–有父類的行為和屬性,也有自己特有的行為和屬性。這樣做擴展了已存在的代碼塊,進一步提高了代碼的復用性。
       如果說封裝和繼承是為了使代碼重用,那麼多態則是為了實現接口重用。多態的一大作用就是為了解耦–為了解除父子類繼承的耦合度。如果說繼承中父子類的關係式IS-A的關係,那麼接口和實現類之之間的關係式HAS-A。簡單來說,多態就是允許父類引用(或接口)指向子類(或實現類)對象。很多的設計模式都是基於面向對象的多態性設計的。

2.JVM的內存區及其GC算法

參考:

元空間:jdk1.8取消了持久代新增了元空間,並將方法區放在元空間中

3.集合框架下的各種接口和實現類有哪些,分別有啥特點

參考:

4.string類有啥特點,有哪些常用的API

1.String類對象的相等判斷使用equals()方法完成,“==”實現的是地址數值的比較
2.字符串內容一旦聲明則不可改變,String類對象內容的改變是依靠引用關係的變更實現的。
3.String類有兩種實例化方式,使用直接賦值可以不產生垃圾空間,並且可以自動入池,不要使用構造方法賦值。

一些常見API:

 indexOf():檢索字符串中某個字符或某段字符的下標。

lastIndexOf():和indexOf類似,不過是查找最後一個出現的位置。

str.lastIndexOf(str,index):從下標index往前查找最後一個出現的位置

substring():返回一個字符串的子字符串

charAt(index):返回下標對應的字符

trim():去掉字符串前後的空格

startsWith()/endsWith():檢測字符串是否已制定字符串開頭或結尾,返回值是boolean

split()/根據括號內的字符串分離字符串,返回值是一個字符串數組

….

5.stringBuilder和stringBuffer的區別?

運行速度:StringBuilder >StringBuffer >String
線程安全:StringBuilder是線程不安全的,而StringBuffer是線程安全的
String:適用於少量的字符串操作的情況
StringBuilder:適用於單線程下在字符緩衝區進行大量操作的情況
StringBuffer:適用多線程下在字符緩衝區進行大量操作的情況

為什麼StringBuilder是不安全的?

下面是StringBuilder 的append方法源碼

char[] value;
int count;
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
count += len;
return this;
}

對於count + =len;不是一個原子操作 兩個線程同時執行假設都是 計數器為 10 執行完后 就會變成11 而不是12

什麼是原子操作:

 簡單的例子:
       轉賬,A轉給B100,因為停電,導致A轉出了100,B卻沒收到100,所以要把100回滾給A。
原子操作就是多線程下各線程同時執行失敗且同時成功,在兩個線程下,由於count繼承於父類AbstractStringBuilder,當
其中一個線程對coun執行+len后,另一線程取到的count值仍為原來的count值,故+len后和上一個線程得到的結果一樣,
故線程不安全
而stringBuffer中源碼:

@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}

當一個線程訪問append後會立即上鎖,從而另一個線程無法訪問append方法,故是線程安全的
在多線程下,stringBuffer下各線程需要頻繁的加鎖解鎖操作,從而需要運行更長的時間,雖然stringBuilder不需要加鎖解鎖,
但由於線程不安全性,更適用於單線程。

6.線程創建的3種方式,線程阻塞的API有哪些及其之間的區別?

Runnable,Thread,通過 Callable 和 Future 創建線程三種方式

1. 繼承Thread類來創建一個線程, 並實現run方法(線程需要完成的功能); 構建子類對象,start()啟動線程
2. 實現Runnable接口來創建一個線程, 實現Runnable,實現run()方法; 將Runnable接口類的對象作為參數傳遞給Thread類對象, 並調用start()方法;
3. 實現Callable接口來創建一個線程, 先定義一個Callable的實現類, 重寫call()方法, call()有返回值; 兩種執行方式:
1). 藉助FutureTask執行, 創建Callable實現類的對象, 並作為參數傳遞給FutureTask, FutureTask作為參數傳遞給Thread類的對象, 並執行start()方法;
2). 藉助線程池來執行, 先創建線程池, 然後調用線程池的submit方法, 並將Callable實現列作為參數傳入

方法二的好處:
1. 可以將一個Runnable實現類傳遞給多個線程對象, 適合用多個相同程序代碼的編程處理同一個資源
2. Thread類創建線程是採用繼承的方式, 而Java中只能單繼承, 如果某個子類的需要創建線程只能採用實現Runnable接口或者實現Callable接口的方式.

方法三的好處:
1. 有返回值
2. call()可以拋出異常
3. 運行Callable任務可以得到一個Future兌現,表示異步計算的結果. 它提供了檢測計算是否完成的方法(isDone())以等待計算的完成,並檢索計算的結果.

線程阻塞api:

sleep()方法;:該方法允許指定以ms為單位的一段時間作為參數, 它使得線程在指定的時間內進入阻塞狀態,不能得到CPU時間, 指定時間已過,線程重新進入可執行狀態.
suspend()和resume()方法:配套使用, suspend()使得線程進入阻塞狀態,且不會自動恢復, 必須將其對應的resume()調用, 才可以使線程進入可執行狀態.
yield();:使得線程放棄當前分得的CPU時間, 但是不使線程阻塞, 即線程仍然處於可執行狀態;
wait()和notify()方法:配套使用,若wait()有參數,相當於sleep(但可以通過notify強行喚醒), wait()沒有參數,相當於suspend(), 需要通過notify喚醒

sleep(0)和sleep(1)和不要sleep的區別

sleep(0),如果線程調度器的可運行隊列中有大於或等於當前線程優先級的就緒線程存在,操作系統會將當前線程從處理器上移除,調度其他優先級高的就緒線程運行;如果可運行隊列中的沒有就緒線程或所有就緒線程的優先級均低於當前線程優先級,那麼當前線程會繼續執行,就像沒有調用 Sleep(0)一樣。
Sleep(1),會引發線程上下文切換:調用線程會從線程調度器的可運行隊列中被移除一段時間,這個時間段約等於 timeout 所指定的時間長度。為什麼說約等於呢?是因為睡眠時間單位為毫秒,這與系統的時間精度有關。通常情況下,系統的時間精度為 10 ms,那麼指定任意少於 10 ms但大於 0 ms 的睡眠時間,均會向上求值為 10 ms。

7.抽象類和接口的區別?有了抽象類為啥還要接口?

1.一類可以實現多個接口但只能繼承自一個抽象類,從抽象類派生出的子類同樣可以實現接口,從而,我們能得出一個結論:接口是為Java實現多繼承而存在的
2.抽象類中可以存在非抽象的方法,可接口不能存在非抽象的方法,並且接口裡面的方法只是一個聲明,必須用 public abstract來修飾,沒有具體的實現
3.抽象方法中的成員變量可以被不同的修飾符修飾,而接口中的成員變量默認都是靜態常量
4.抽象類是對對象進行的抽象,而接口是一種行為規範,這一點是比較重要的.
(所以為什麼有了接口還要有抽象類)

8.冒泡排序,選擇排序,快速排序(了解)

冒泡排序:什麼是冒泡?比如說水底隨機產生一些氣泡,一起往上冒泡,越輕的氣泡往上冒的越快
具體:12 34 10 78 67
如果從小到大排序:先將67和78比較,67比78小,依次往前比較,小的放前面,打的放後面,以此為一輪排序,然後再將新的數組重複上述過程,共需要n輪排序(n為元素個數);

選擇排序:從一個數組裡選出最小的元素放在數組第一位並交換位置,然後再將去掉第一位的數組找出最小元素並放在這個新數組第一位,
重複此操作。
12 34 10 78 67
第一輪:10| 34 12 78 67
第二輪:10 12| 34 78 67
第三輪:10 12 34| 78 67
第四輪:10 12 34 67| 78
排序結束

快速排序:基於基數排序。先取任意一基數,一般為數組第一個元素(由於當第一個元素為最小值(最大值)時會使排序出現錯誤,故有時候也取中間的元素),然後將比基數小的數作為一個數組,比基數大的數作為一個數組,再將新的兩個數組分別遞歸排序。
通過基數分成兩個數組的過程:12 34 10 78 67 8 假設數組為arr
取一基數temp=12 取low=0(數組第一位),high=5(數組最後一位)
第一輪:第一步:先從后往前比較:arr[high]=8<12=temp,結束這一步操作,high與low不變。如果這裏arr[high]>12,則令high-1得到新的high將arr[high]與temp比較,依此下去直到arr[high]<temp,這種情況high發生改變,low不變。
第二步:再從前往後將arr[low]與temp比較,原理與第一步相同,因為arr[1]>temp,此時low=1,結束這一步操作。
第三步:交換arr[low]與arr[high]的值
第一輪結果:12 8 10 78 67 34(low=1,high=5)
第二輪:與第一輪一樣,第一步,從arr[high]往前,直到arr[2]=10<12,此時high=2,結束這一步
第二步,從arr[low]往後,12,8,10都不大於12,到這裏的時候,因為low=2=high,故比較,得到索引index=low=high=2
第二輪結果:12 8 10 78 67 34
因為index得到了值3,將arr[index]作為分界點將最後一輪結果數組[12 8 10 78 67 34]分為兩個數組[12 8 10]和[78 67 34]
將新的到的兩個數組重複進行上述操作
[12 8 10]->因為12為最大值,故取中間值8->[8]和[10 12]->[8]、[10]、[12]
[78 67 34]->取67,->[34]、[67 78]->[34]、[67]、[78]->[8]、[10]、[12]、[34]、[67]、[78]
(拓展:希爾排序、插入排序)

9.什麼是死鎖?如何避免死鎖

死鎖的定義:所謂死鎖是指多個線程因競爭資源而造成的一種僵局(互相等待),若無外力作用,這些進程都將無法向前推進。

產生原因:
1) 系統資源的競爭
通常系統中擁有的不可剝奪資源,其數量不足以滿足多個進程運行的需要,使得進程在 運行過程中,會因爭奪資源而陷入僵局,如磁帶機、打印機等。只有對不可剝奪資源的競爭 才可能產生死鎖,對可剝奪資源的競爭是不會引起死鎖的。
2) 進程推進順序非法
進程在運行過程中,請求和釋放資源的順序不當,也同樣會導致死鎖。例如,併發進程 P1、P2分別保持了資源R1、R2,而進程P1申請資源R2,進程P2申請資源R1時,兩者都 會因為所需資源被佔用而阻塞。

四個產生死鎖的條件:
互斥條件:進程要求對所分配的資源(如打印機)進行排他性控制,即在一段時間內某 資源僅為一個進程所佔有。此時若有其他進程請求該資源,則請求進程只能等待。
不剝奪條件:進程所獲得的資源在未使用完畢之前,不能被其他進程強行奪走,即只能 由獲得該資源的進程自己來釋放(只能是主動釋放)。
請求和保持條件:進程已經保持了至少一個資源,但又提出了新的資源請求,而該資源 已被其他進程佔有,此時請求進程被阻塞,但對自己已獲得的資源保持不放。
循環等待條件:存在一種進程資源的循環等待鏈,鏈中每一個進程已獲得的資源同時被 鏈中下一個進程所請求。即存在一個處於等待狀態的進程集合{Pl, P2, …, pn},其中Pi等 待的資源被P(i+1)佔有(i=0, 1, …, n-1),Pn等待的資源被P0佔有。

避免死鎖:
1.加鎖順序(線程按照一定的順序加鎖)
2.加鎖時限(線程嘗試獲取鎖的時候加上一定的時限,超過時限則放棄對該鎖的請求,並釋放自己佔有的鎖)
3.死鎖檢測
參考:

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

什麼是回調,回調在編程中的含義

回調函數的最初需求背景

回調函數我能想到的最古老的場景就是系統編程會用到。

編程分為兩類:

  • 系統編程(system programming)
  • 應用編程(application programming)

什麼是系統編程:
  所謂系統編程,簡單來說,就是編寫各種各樣的功能庫。比如Windows裏面的win32、gdi32庫,win32就能調用主機硬件和系統層的功能,gdi32能用來繪製圖形相關。這些庫就等着那些做應用的人來調用就行。

什麼是應用編程:
  而應用編程就是利用已經寫好的各種系統功能庫、語言功能庫來編寫具某種業務功能用的程序,就是應用。比如一個基礎的爬蟲程序,可以利用python語言和requests庫來完成,一個基礎的Web站點可以利用Java語言和Java Servlet庫來完成。

系統編程和回調的關係

  系統程序員會給自己寫的庫留下一些接口,即API,以供應用程序員使用。所以在抽象層的圖示里,庫位於應用的底下。當程序跑起來時,一般情況下,應用程序會時常通過API調用庫里所預先備好的函數。但是有些庫函數卻要求應用先傳給它一個函數,好在合適的時候調用,以完成目標任務。這個被傳入的、后又被調用的函數就稱為回調函數。

如果你看文字看得比較懵,那麼你看我畫的圖(下面是圖1):

(圖1)

理解回調前,先理解同步調用

同步調用是以一種阻塞式調用,簡單來說就是從上往下,按照順序去執行。 而回調就是一種非同步調用式順序。

  同步式調用的具體案例,可以聯想到古代的烽火台。古代長城的烽火傳遞的機制就和同步調用差不多,現在我們假設每個烽火只能看到相鄰的烽火狀態,每個烽火的狀態只有亮(點火狀態)和暗(不點火狀態)。

  現在有A、B、C、D四個烽火台,A首先點亮,B看到A的烽火亮了,立馬去點火,花了2秒點亮。但是這時候負責C烽火的人在睡覺,可是這時候所有人都在等待C點亮,終於C睡了2個小時候看到了B點亮,然後去點亮。D由於長期沒有點亮,導致烽火出現問題,因此整個過程都在等待D的完成。(由此也引發一些思考,同步調用有時也容易掉鏈子,如果上一步掉鏈子了,下一步之後的操作都完蛋了。)

同步調用的案例代碼:

print("start.")
print(123)
print(456)

a = 7
if a > 6:
    print(789)

print(91011)
print("end.")

回調需要解決的問題

  常見的系統都會開發出很多庫,庫裏面有很多函數。而有些函數,需要調用者根據自己的需求來寫入要調用的函數。因為這個在編寫庫的時候沒法預測,只能由調用者輸入,所以就需要回調機制。

  回調機制是用來完善同步調用機制的一種方式,用來完善同步調用機制的還有異步調用機制。(後面會寫文章介紹這種更重要的異步)

回調函數怎麼解決實際問題的案例

回調就是通過如下方式來解決上面說的問題。

  • 函數能變成參數
  • 靈活、自定義的方式調用

函數變參數案例

def doubel(x):
    return 2*x

def quadruple(x):
    return 4*x

# mind function
def getAddNumber(k, getEventNumber):
    return 1 + getEventNumber(k)

def main():
    k=1
    i=getAddNumber(k,double)
    print(i)
    i=getAddNumber(k,quadruple)
    print(i)

# call main
main()

輸出結果:

3
5

靈活、自定義的方式調用(酒店叫醒旅客)案例

這個案例真是回調的靈魂所在了,假設你是酒店的前台小姐姐,你不可能知道今晚入住的旅客需不需要明天要不要叫醒服務、需要什麼樣的叫醒服務。

def call_you_phone(times):
    """
    叫醒方式: 給你打電話
    :param times: 打幾次電話
    :return: None
    """
    print('已經給旅客撥打了電話的次數:', str(times))

def knock_you_door(times):
    """
    叫醒方式: 去敲你房間門
    :param times: 敲幾次門
    :return: None
    """
    print('已經給旅客敲門的次數:', str(times))

def no_service(times):
    """
    叫醒方式: 無叫醒服務. (默認旅客是選無叫醒服務)
    :param times: 敲幾次門
    :return: None
    """
    print('顧客選擇無服務.不要打擾他的好夢。')

def front_desk(times, function_name=no_service()):
    """
    這個相當於酒店的前台,你去酒店之後,你要啥叫醒方式都得在前台說
    這裡是實現回調函數的核心,相當於一个中轉中心。
    :param times:次數
    :param function_name:回調函數名
    :return:調用的函數結果
    """
    return function_name(times)

if __name__ == '__main__':
    front_desk(100, call_you_phone)  # 意味着給你打100次電話,把你叫醒

輸出:

已經給旅客撥打了電話的次數:100

實際應用(Python的requests庫自帶的事件鈎子)

這個案例就很好解決原本程序是同步機制執行的,但是通過鈎子事件,就可以優先去執行一些先行步驟。而這個鈎子事件的原理就是函數回調。

import requests

def env_hooks(response, *args, **kwargs):
    print(response.headers['Content-Type'])

def main():
    result = requests.get("https://api.github.com", hooks=dict(response=env_hooks))
    print(result.text)

if __name__ == '__main__':
    main()

輸出:

application/json; charset=utf-8
{"current_user_url":"https://api.github.com/user","current_user_authorizations_html_url":"...省略"}

課後思考題

看完了上面的案例,請你回答如下幾個問題

1.回調在那些場景下使用?
2.回調必須以函數為參數嗎?
3.回調和異步的差異在哪裡?

把你的思考評論在評論區裏面,我會抽空給你回復的。

參考文獻

參考:
參考:

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

.NET Core 對龍芯的支持情況和對 .NET Core 開發嵌入式的思考

目錄

.NET Core 對龍芯的支持情況和對 .NET Core 開發嵌入式的思考

一,遺憾的嘗試

前些天看到了張隊公眾推送的《》,聯想到上一周與朋友在龍芯搗鼓 .NET Core,就想寫一下關於 .NET Core 在龍芯下的資料。

Jexus Web Server 能夠在龍芯服務器上跑,但是 ASP.NET 呢?.NET Core 呢?安裝什麼版本的 Mono ?Jexus 作者的文章表達有點模糊呀~

上一周與朋友在龍芯上面為了部署 .NET 項目,頗費心機。朋友公司中標政府項目,開發好 .NET Core 做的項目后,才發現要部署的服務器是龍芯的,.NET Core 無法在上面運行。

服務器有什麼有 Mono 4.x,可以創建簡單的 Proparm.cs ,編譯出程序,使用 mono xx.exe 運行,可是把項目放進去編譯不出來~想編譯安裝 Mono 6.x 也不行,中間有些過程報錯。

.NET Core 自然不用想了,完全無法編譯,通過 Google 查詢資料,要重寫 C++ 部分(移植),才能在 龍芯 下編譯出 CoreCLR。

官方 CoreCLR 源碼庫,可以看到一些腳本和編譯工具鏈。

RISV-C 是精簡指令集,MIPS 是指 基於 RISC-V 的 CPU 架構,龍芯服務器使用 MIPS 架構。

最終,無法部署 .NET 軟件,朋友公司改用 Java 開發。。。

之前筆者為了在 Armel 的 CPU 下運行 .NET Core ,花了很多時間手動編譯 .NET Core,最終還是失敗。我將編譯過程詳細寫了一篇文章,地址《》。

二,.NET Core在嵌入式下的幾點不足

18年7月張隊來我校組織了大灣區 .NET 交流會,從那時起開始學習 .NET ,19 年三月月份進入敢為實習轉正至此。

使用 .NET Core 開發半年的時間里,在嵌入式開發中,我個人總結當前 .NET Core 在嵌入式領域有幾個問題/建議。

1,不支持前幾年的CPU

.NET Core 無法在樹莓派 Zero上運行(Arm v6);

無法在華為海思A9芯片上運行(Armel Armv7);

這兩種芯片雖說是幾年前出的芯片,但是 .NET Core 大張旗鼓的說要搞 IoT,卻不兼容舊一些的 CPU,目前很多舊式設備依然會在未來一段時間內是主流的存在 。

微軟官方也說了:

Note: .NET Core 2.1 is supported on Raspberry Pi 2+. It isn’t supported on the Pi Zero or other devices that use an ARMv6 chip. .NET Core requires ARMv7 or ARMv8 chips, like the ARM Cortex-A53.

Arm 方面的支持還是不夠廣。

2,測試的硬件設備較少

官方對嵌入式設備的測試,主要在 樹莓派 2 / 3,還有很多開發板沒有測試~

3,支持兼容的系統版本較少

.NET Core 支持很多 Linux 系統,但是對應這些系統的支持,都是以最新版本的系統為主,例如 .NET Core 3.0 在Ubuntu 上是支持 16.x、18.x,14.x 和 17.x 被無情的拋棄了。

.NET Core 3.0 支持的系統如下:

4,體積依然太大

對於嵌入式開發來說, .NET Core 的體積依然太大,.NET Core 3.0 也拯救不了。。。哪怕只有一行 Hello World,也要 70MB+ 以上。

5,依賴庫比較傷腦筋

經常會出現 ICU、libssl、gcc 等依賴庫版本不一致或沒有安裝這些庫時的報錯信息,石頭哥曾經被這些問題搞得掉頭髮。

三,.NET Core 龍芯移植的進展和資料

根據大佬們的移植,在 11 月 9 號時,已經實現了 在龍芯上面運行 .NET Core 的 Hello World 實例,

The code base was upgraded to 3.0. Hello World and serveral tests in coreclr can run on MIPS64 now. 

這是對於 CoreCLR 的移植,還有很多問題等待大神解決。

對於 .NET Core 在 MIPS 上的移植討論,可以到 Issue 查看

不過,微軟官方目前沒有移植計劃,只能靠社區去完成了。

Microsoft currently has no plans or work in progress to support MIPS. Of course, we would be willing to accept external contributions towards that goal as appropriate. Note that it is, certainly, a significant amount of work to port .NET Core to a new platform.

還有另一個大神的作品

This project will focus on translating .NET IL for non-supported .NET targets. Portibility is a huge focus.

  • .NET Standard compatibility
  • Native C performance
  • C89: modern, legacy and embedded platforms (x86, MIPS, SPARK, RISC-V, PPC, AVR, etc)
  • CC65: 6502 platforms (Atari, C64, NES, Apple II, etc) [CS2X may be better suited]]
  • SDCC: Many targets (ColecoVision, etc) [CS2X may be better suited]
  • Assembly: CP1610 (Intellivision) [CS2X may be better suited]]
  • Retarget: Custom assembly targets via plugin system (FPGA CPU, 16bit bytes, etc)
  • Custom Standard lib(s) for various targets.
  • Documentation

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

※評比南投搬家公司費用收費行情懶人包大公開

007.Kubernetes二進制部署Flannel

一 部署flannel

1.1 安裝flannel


kubernetes 要求集群內各節點(包括 master 節點)能通過 Pod 網段互聯互通。flannel 使用 vxlan 技術為各節點創建一個可以互通的 Pod 網絡,使用的端口為 UDP 8472。




flanneld 第一次啟動時,從 etcd 獲取配置的 Pod 網段信息,為本節點分配一個未使用的地址段,然後創建 flannedl.1 網絡接口(也可能是其它名稱,如 flannel1 等)。




flannel 將分配給自己的 Pod 網段信息寫入 /run/flannel/docker 文件,docker 後續使用這個文件中的環境變量設置 docker0 網橋,從而從這個地址段為本節點的所有 Pod 容器分配 IP。

更多flannel參考:《008.Docker Flannel+Etcd分佈式網絡部署》。

  1 [root@k8smaster01 ~]# cd /opt/k8s/work/
  2 [root@k8smaster01 work]# mkdir flannel
  3 [root@k8smaster01 work]# wget https://github.com/coreos/flannel/releases/download/v0.11.0/flannel-v0.11.0-linux-amd64.tar.gz
  4 [root@k8smaster01 work]# tar -xzvf flannel-v0.11.0-linux-amd64.tar.gz -C flannel


1.2 分發flannel

  1 [root@k8smaster01 ~]# cd /opt/k8s/work
  2 [root@k8smaster01 work]# source /opt/k8s/bin/environment.sh
  3 [root@k8smaster01 work]# for master_ip in ${MASTER_IPS[@]}
  4   do
  5     echo ">>> ${master_ip}"
  6     scp flannel/{flanneld,mk-docker-opts.sh} root@${master_ip}:/opt/k8s/bin/
  7     ssh root@${master_ip} "chmod +x /opt/k8s/bin/*"
  8   done


1.3 創建flannel證書和密鑰

  1 [root@k8smaster01 ~]# cd /opt/k8s/work
  2 [root@k8smaster01 work]# cat > flanneld-csr.json <<EOF
  3 {
  4     "CN": "flanneld",
  5     "hosts": [],
  6     "key": {
  7         "algo": "rsa",
  8         "size": 2048
  9     },
 10     "names": [
 11         {
 12             "C": "CN",
 13             "ST": "Shanghai",
 14             "L": "Shanghai",
 15             "O": "k8s",
 16             "OU": "System"
 17         }
 18     ]
 19 }
 20 EOF
 21 #創建flanneld的CA證書請求文件



解釋:

該證書只會被 kubectl 當做 client 證書使用,所以 hosts 字段為空。

  1 [root@k8smaster01 ~]# cd /opt/k8s/work
  2 [root@k8smaster01 work]# cfssl gencert -ca=/opt/k8s/work/ca.pem \
  3 -ca-key=/opt/k8s/work/ca-key.pem -config=/opt/k8s/work/ca-config.json \
  4 -profile=kubernetes flanneld-csr.json | cfssljson -bare flanneld	#生成CA密鑰(ca-key.pem)和證書(ca.pem)


1.4 分發證書和私鑰

  1 [root@k8smaster01 ~]# cd /opt/k8s/work
  2 [root@k8smaster01 work]# source /opt/k8s/bin/environment.sh
  3 [root@k8smaster01 work]# for master_ip in ${MASTER_IPS[@]}
  4   do
  5     echo ">>> ${master_ip}"
  6     ssh root@${master_ip} "mkdir -p /etc/flanneld/cert"
  7     scp flanneld*.pem root@${master_ip}:/etc/flanneld/cert
  8   done


1.5 寫入集群 Pod 網段信息

  1 [root@k8smaster01 ~]# cd /opt/k8s/work
  2 [root@k8smaster01 work]# source /opt/k8s/bin/environment.sh
  3 [root@k8smaster01 work]# etcdctl \
  4   --endpoints=${ETCD_ENDPOINTS} \
  5   --ca-file=/opt/k8s/work/ca.pem \
  6   --cert-file=/opt/k8s/work/flanneld.pem \
  7   --key-file=/opt/k8s/work/flanneld-key.pem \
  8   mk ${FLANNEL_ETCD_PREFIX}/config '{"Network":"'${CLUSTER_CIDR}'", "SubnetLen": 21, "Backend": {"Type": "vxlan"}}'



注意:注意:本步驟只需執行一次。

提示:flanneld 當前版本 (v0.11.0) 不支持 etcd v3,故使用 etcd v2 API 寫入配置 key 和網段數據;

寫入的 Pod 網段 ${CLUSTER_CIDR} 地址段(如 /16)必須小於 SubnetLen,必須與 kube-controller-manager 的 –cluster-cidr 參數值一致。

1.6 創建flanneld的systemd

  1 [root@k8smaster01 ~]# cd /opt/k8s/work
  2 [root@k8smaster01 work]# source /opt/k8s/bin/environment.sh
  3 [root@k8smaster01 work]# cat > flanneld.service << EOF
  4 [Unit]
  5 Description=Flanneld overlay address etcd agent
  6 After=network.target
  7 After=network-online.target
  8 Wants=network-online.target
  9 After=etcd.service
 10 Before=docker.service
 11 
 12 [Service]
 13 Type=notify
 14 ExecStart=/opt/k8s/bin/flanneld \\
 15   -etcd-cafile=/etc/kubernetes/cert/ca.pem \\
 16   -etcd-certfile=/etc/flanneld/cert/flanneld.pem \\
 17   -etcd-keyfile=/etc/flanneld/cert/flanneld-key.pem \\
 18   -etcd-endpoints=${ETCD_ENDPOINTS} \\
 19   -etcd-prefix=${FLANNEL_ETCD_PREFIX} \\
 20   -iface=${IFACE} \\
 21   -ip-masq
 22 ExecStartPost=/opt/k8s/bin/mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/docker
 23 Restart=always
 24 RestartSec=5
 25 StartLimitInterval=0
 26 
 27 [Install]
 28 WantedBy=multi-user.target
 29 RequiredBy=docker.service
 30 EOF



解釋:

mk-docker-opts.sh:該腳本將分配給 flanneld 的 Pod 子網段信息寫入 /run/flannel/docker 文件,後續 docker 啟動時使用這個文件中的環境變量配置 docker0 網橋;

flanneld:使用系統缺省路由所在的接口與其它節點通信,對於有多個網絡接口(如內網和公網)的節點,可以用 -iface 參數指定通信接口;

flanneld:運行時需要 root 權限;

-ip-masq: flanneld 為訪問 Pod 網絡外的流量設置 SNAT 規則,同時將傳遞給 Docker 的變量 –ip-masq(/run/flannel/docker 文件中)設置為 false,這樣 Docker 將不再創建 SNAT 規則; Docker 的 –ip-masq 為 true 時,創建的 SNAT 規則比較“暴力”:將所有本節點 Pod 發起的、訪問非 docker0 接口的請求做 SNAT,這樣訪問其他節點 Pod 的請求來源 IP 會被設置為 flannel.1 接口的 IP,導致目的 Pod 看不到真實的來源 Pod IP。 flanneld 創建的 SNAT 規則比較溫和,只對訪問非 Pod 網段的請求做 SNAT。

1.7 分發flannel systemd

  1 [root@k8smaster01 ~]# cd /opt/k8s/work
  2 [root@k8smaster01 work]# source /opt/k8s/bin/environment.sh
  3 [root@k8smaster01 work]# for master_ip in ${MASTER_IPS[@]}
  4   do
  5     echo ">>> ${master_ip}"
  6     scp flanneld.service root@${master_ip}:/etc/systemd/system/
  7   done


二 啟動並驗證

2.1 啟動flannel

  1 [root@k8smaster01 ~]# source /opt/k8s/bin/environment.sh
  2 [root@k8smaster01 ~]# for master_ip in ${MASTER_IPS[@]}
  3   do
  4     echo ">>> ${master_ip}"
  5     ssh root@${master_ip} "systemctl daemon-reload && systemctl enable flanneld && systemctl restart flanneld"
  6   done


2.2 檢查flannel啟動

  1 [root@k8smaster01 ~]# source /opt/k8s/bin/environment.sh
  2 [root@k8smaster01 ~]# for master_ip in ${MASTER_IPS[@]}
  3   do
  4     echo ">>> ${master_ip}"
  5     ssh root@${master_ip} "systemctl status flanneld|grep Active"
  6   done



2.3 檢查pod網段信息

  1 [root@k8smaster01 ~]# source /opt/k8s/bin/environment.sh
  2 [root@k8smaster01 ~]# etcdctl \
  3   --endpoints=${ETCD_ENDPOINTS} \
  4   --ca-file=/etc/kubernetes/cert/ca.pem \
  5   --cert-file=/etc/flanneld/cert/flanneld.pem \
  6   --key-file=/etc/flanneld/cert/flanneld-key.pem \
  7   get ${FLANNEL_ETCD_PREFIX}/config			#查看集群 Pod 網段(/16)



  1 [root@k8smaster01 ~]# source /opt/k8s/bin/environment.sh
  2 [root@k8smaster01 ~]# etcdctl \
  3   --endpoints=${ETCD_ENDPOINTS} \
  4   --ca-file=/etc/kubernetes/cert/ca.pem \
  5   --cert-file=/etc/flanneld/cert/flanneld.pem \
  6   --key-file=/etc/flanneld/cert/flanneld-key.pem \
  7   ls ${FLANNEL_ETCD_PREFIX}/subnets			#查看已分配的 Pod 子網段列表(/24)
  8 [root@k8smaster01 ~]# source /opt/k8s/bin/environment.sh
  9 [root@k8smaster01 ~]# etcdctl \
 10   --endpoints=${ETCD_ENDPOINTS} \
 11   --ca-file=/etc/kubernetes/cert/ca.pem \
 12   --cert-file=/etc/flanneld/cert/flanneld.pem \
 13   --key-file=/etc/flanneld/cert/flanneld-key.pem \
 14   get ${FLANNEL_ETCD_PREFIX}/subnets/172.30.32.0-21	#查看某一 Pod 網段對應的節點 IP 和 flannel 接口地址




解釋:

172.30.32.0/21 被分配給節點 k8smaster01 (172.24.8.71);

VtepMAC 為 k8smaster01 節點的 flannel.1 網卡 MAC 地址。

2.4 檢查flannel網絡信息

  1 [root@k8smaster01 ~]# ip addr show



解釋:flannel.1 網卡的地址為分配的 Pod 子網段的第一個 IP(.0),且是 /32 的地址。

  1 [root@k8smaster01 ~]# ip route show |grep flannel.1
  2 172.30.128.0/21 via 172.30.128.0 dev flannel.1 onlink
  3 172.30.208.0/21 via 172.30.208.0 dev flannel.1 onlink



解釋:

到其它節點 Pod 網段請求都被轉發到 flannel.1 網卡;

flanneld 根據 etcd 中子網段的信息,如 ${FLANNEL_ETCD_PREFIX}/subnets/172.30.32.0-21 ,來決定進請求發送給哪個節點的互聯 IP。

2.5 驗證各節點flannel


在各節點上部署 flannel 后,檢查是否創建了 flannel 接口(名稱可能為 flannel0、flannel.0、flannel.1 等):

  1 [root@k8smaster01 ~]# source /opt/k8s/bin/environment.sh
  2 [root@k8smaster01 ~]# for master_ip in ${MASTER_IPS[@]}
  3   do
  4     echo ">>> ${master_ip}"
  5     ssh ${master_ip} "/usr/sbin/ip addr show flannel.1|grep -w inet"
  6   done



輸出:

  1 >>> 172.24.8.71
  2     inet 172.30.32.0/32 scope global flannel.1
  3 >>> 172.24.8.72
  4     inet 172.30.128.0/32 scope global flannel.1
  5 >>> 172.24.8.73
  6     inet 172.30.208.0/32 scope global flannel.1



在各節點上 ping 所有 flannel 接口 IP,確保能通:

  1 [root@k8smaster01 ~]# source /opt/k8s/bin/environment.sh
  2 [root@k8smaster01 ~]# for master_ip in ${MASTER_IPS[@]}
  3   do
  4     echo ">>> ${master_ip}"
  5     ssh ${master_ip} "ping -c 1 172.30.32.0"
  6     ssh ${master_ip} "ping -c 1 172.30.128.0"
  7     ssh ${master_ip} "ping -c 1 172.30.208.0"
  8   done


本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包"嚨底家"

網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家費用,距離,噸數怎麼算?達人教你簡易估價知識!