同一款2.0T發動機,價格卻差了10來20萬!買了就坑?

其實大家也可以反過來想一下,如果光是靠發動機可以來衡量一款車是不是好車的話,那麼那麼吉利博越一直都被各路大神吐槽油耗高、小問題多,但依然不愁賣,這又該如何解釋。如今在網上還有一種說法:豪華車型不弄7、8、9個擋,都是為了省成本,不夠高大上,多擋位變速箱理應是豪華車型的標配。

在你心目中,最坑爹的車型是哪一款?



套娃的?

加價提車的?

買發動機送車的?

可是最近在網上竟然看到有人說最坑爹的竟然是一些豪車,說它們的發動機、變速箱都是通過購買而來的,可以說是“高級拼裝車”。其中像路虎極光、捷豹XFL、林肯MKZ等好幾款車型紛紛躺槍,究竟是怎麼回事?

被說“坑爹”的原因很簡單,因為這些車型都搭載了福特全新蒙迪歐的2.0T發動機,同時售價也要比福特全新蒙迪歐更高,因此成了“史上最坑爹的汽車”。

按照這樣的說法,如今在汽車市場上“坑爹”的車型可多了。像寶馬在2006年之前,他們就一直為路虎攬勝和發現3車型提供V8發動機,難不成用了寶馬發動機的路虎就不是路虎?會影響車型檔次?

但如果你想說“他們都是豪華品牌,不至於掉檔次”的話,那現款奧迪Q5又跟大眾途觀L相同的EA888 2.0T發動機,但奧迪Q5的價格要比大眾途觀L高出許多,你又怎麼看呢?

先不說品牌檔次,光是在一些調校、用料等一些內在品質方面,奧迪Q5的表現就比大眾途觀L更為出色,開起來的質感也會更舒適,而且它的安全性能也是得到了市場的檢驗,這就是它的價值所在!

其實大家也可以反過來想一下,如果光是靠發動機可以來衡量一款車是不是好車的話,那麼那麼吉利博越一直都被各路大神吐槽油耗高、小問題多,但依然不愁賣,這又該如何解釋?

如今在網上還有一種說法:豪華車型不弄7、8、9個擋,都是為了省成本,不夠高大上,多擋位變速箱理應是豪華車型的標配?

擋位多與少這個問題,已經不是第一次跟大家科普了,在這裏先不說多擋位的變速箱省不省油,但是拿變速箱擋位來衡量一款車是否上檔次,這完全是一種“病態”。

先來說說路虎極光,不少網友都知道它搭載了9AT變速箱,擋位數夠多吧?可是之前就被曝光過它的變速箱在D擋位存在故障問題,這是一個軟件調校的問題。

同樣,Jeep自由光也搭載了9AT變速箱,可不少車主紛紛表示“沒看見過它的第9擋”,即使把時速跑到120km/h也仍然在第8擋以下,第9擋如同雞肋。很顯然,這同樣是一個匹配、調校的問題。

通過這兩個例子,想說:如果高擋位成為雞肋或者換擋不平順,擋位數量再多都是沒意義的。現款的寶馬X1同為豪華車型,而且現在只搭載了6AT變速箱,加上它空間大、操控好、上檔次,而且口碑還不錯,你還在意它的擋位數量嗎?

再說了,如今像眾泰T700、陸風X7、傳祺GS4等車型,它們雖然並不是什麼高檔車型但都搭載了多擋位變速箱,這很顯然並不是高擋車型的“專屬”,一味的追求是毫無意義的。

此外,有些消費者還會關注到平台的問題,認為一款豪車跟普通車型採用相同的平台打造會顯得“廉價、有失身份”,其實這也是一個誤區!

就拿本田飛度跟謳歌CDX作例子,雖然兩款車都是基於同一個平台打造,但謳歌CDX在用料、舒適性等方面的表現會更加出色,而且它擁有跟飛度一樣的大空間和良好的操控。

但是相反過來,本田飛度能有謳歌CDX那樣舒適的乘坐和駕駛質感嗎?因此,“同平台”的意義並不單純只是降低研發成本,也能對提升車型品質起到一定的作用。

還有奧迪Q7跟大眾途昂,儘管它們都採用了大眾MQB平台進行打造,但是論豪華感、行駛質感等方面,兩款車依然有較大的差距。也就是說“同平台”並不代表工藝、用料、調校都是一樣的,只是共用了部分技術罷了。

如今在汽車市場上,共用發動機、變速箱,甚至採用同一個研發平台的車型還有很多,雖然最大的意義還是在於降低研發成本,但最核心的部分還是在匹配調校、用料方面。

SO~這並不能成為“坑爹、廉價、不上檔次”的代名詞,真正的一款車“好不好”、“值不值”並不能由誰說了算,只有自己親身體驗過,感受過覺得OK,而且價格也能接受,那才是最好、最適合的。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

※推薦評價好的iphone維修中心

8款老闆愛的車最低只要4萬

還有就是形象與同級比起來要更顯莊重,即使去談大買賣,也不至於讓人瞧不起。其實不僅是別克GL8,還有許多定位為商務MpV的車型同樣也充滿了濃郁的商務氣息,而這次推薦GL8主要原因還是因為它空間及乘坐舒適性達到同級一流水平,應有的电子設備都有,相對而言,GL8是現在市面上主流MpV中比較卓越的一款車型。

關於#老闆開什麼車#這樣的話題

相信不少人都有關注過吧

雖然老闆的座駕並沒有什麼標準

可是總有幾款讓人印象深刻

為什麼老闆們都這麼喜歡這些車?

老闆們喜歡的這些車是否適合你?

開上這些車后你是否就能當老闆?

看完這8款老闆車你就會有答案了

首先要排除一個誤區,誰說老闆就一定要開個大奔馳或大賓利的?開五菱宏光的小賣鋪老闆不也是老闆嗎?什麼空間大、油耗低、動力足、操控好、保養便宜、可靠性高等等優點就不多說了,反正銷量說明一切嘛。不過買最便宜的車裝最多的貨,這些簡單的商業意識還是要具備的。

其實能“裝”的確是五菱宏光的核心價值吧,裝人:最多可放置8個座椅,什麼7座SUV都是辣雞;裝貨:只要裝得下,世界就是你的;裝X:方式太多,請自行上論壇選,總有一款適合你。

可能這隻是我的個人印象吧,從小到大,身邊總有一些開着捷達,成天到處跑業務的創業老闆,他們總是會稱讚自己的捷達很省心,很省油,又好開,說這樣的一台車可以完全滿足他們的代步需求,而且外觀低調,卻很有商務范。

其實說到捷達的外觀,雖然現款的捷達也很低調,也很有商務范,同樣也是個“老實”形象,還是以前方頭方腦的造型給我的印象更深刻,可是那個造型放在今天馬路上,也許展現出更多的是“經典”或“復古”吧。

為什麼說開帕薩特的老闆最神秘?首先,一般人根本分不清帕薩特和輝騰,還有就是的確有許多隱形富豪為了低調會選擇帕薩特這款車,首先大眾標就夠低調了,再來就是外觀造型,家族式設計遍布全車身,讓人怎麼看都覺得是一輛不超過20萬的車。

可是20萬要買低調的車選擇很多,為什麼這些隱形富豪要選帕薩特?其實還是圍繞着舒適性吧,德系紮實底盤質感,大空間;還有就是形象與同級比起來要更顯莊重,即使去談大買賣,也不至於讓人瞧不起。

其實不僅是別克GL8,還有許多定位為商務MpV的車型同樣也充滿了濃郁的商務氣息,而這次推薦GL8主要原因還是因為它空間及乘坐舒適性達到同級一流水平,應有的电子設備都有,相對而言,GL8是現在市面上主流MpV中比較卓越的一款車型。

當然,這樣的MpV一般都是公務用車,老闆一般只坐在第二排,坐在舒適的座椅上,有公事要聊的時候,跟助理溝通起來十分方便;沒事聊的時候,放下靠背,也可以睡得很舒服。

作為豐田越野神車蘭德酷路澤的分支車型,普拉多其實已經更傾向於都市SUV,可是在造型方面還是很有越野的味道,這也是許多老闆們喜歡它原因之一,不過實際普拉多還是延續了較好的越野性能。

很多人都說什麼樣的人就會開什麼樣的車,我通過普拉多的車主們就能明顯體現出這點,說不上個個都高大威猛,可是至少也是條硬漢。

雖然說“虎頭奔之後再也沒有S級”,有情懷的車迷都喜歡那個年代的S級,可是現在的S級無疑是更好的S級,動力更好,配置更高,價格更低。雖然造型方面的確是向現在的消費市場妥協了,可是現在的S級仍然是D級車裡最有老闆范的。

但是實際上並不是所有買S級的老闆都會請司機,或者說不是所有買了S級的老闆自己都不開,即使自己開S級的時候的確有點像司機,可是他們還是很願意去駕駛這輛高級車。

與其說開霸道(普拉多)的老闆真霸氣,還不如說開攬勝的人才是真正的“霸道總裁”,說到高大上,縱觀市面上所有高端中大型SUV,好像真沒幾款能媲美路虎攬勝的了。也有人說路虎攬勝根本沒有直接的競爭對手,因為在公路和越野的性能都如此卓越,內飾如此豪華,外觀如此霸氣的SUV屈指可數。

雖然說攬勝也有極高的越野性能,可是車主們更願意把它看作是豪華都市SUV,而且攬勝的形象也似乎更合適出現在都市中。

看到勞斯萊斯,貌似我們的話題就要結束了,我也都相信大家和我一樣,勞斯萊斯才是代表最“尊貴”的老闆車,雖然到了這個等級,選擇還有賓利和邁巴赫,可是這些品牌都不如勞斯萊斯尊貴。

其實到了這個級別的車,更講究的應該就奢華、藝術、品味,多的不說了。

不知道大家看了這麼多老闆車之後,有沒有你心儀的那輛呢?或者在你的印象里,什麼車才算老闆車呢?歡迎把你的所有見解評論到下方留意區哦。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

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

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

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

※教你寫出一流的銷售文案?

※超省錢租車方案

大廠面試過程復盤(微信/阿里/頭條均拿offer,附答案篇)

背景

本人前端,3年經驗,由於個人的原因,決定跳槽,於是大概3月開始找工作,總歷時大概2個月,面試了微信/阿里/頭條,三家都拿到了offer,來分享一下面經。

問題比較多,而且很多面試題都是跟個人項目相關的,項目相關的問題借鑒意義不大,所以這裏總結一些與項目無絕對關係的問題,歡迎圍觀~

本文答案均以鏈接的形式給出,因為我本人的一個特點就是回答題目一定要夠詳細,而且大部分的題目我都寫過文章或者公眾號轉發過文章了,感興趣可以直接關注公眾號前端Q,希望對你有幫助~

整體流程

這裏,我梳理了一些自己的心得,方便自己後面做直播,這裏就當預告一下,先放個思維導圖。

PS: 圖片有點大,如果打不開,直接訪問我的博客

微信

筆試

  1. 數組交集,編寫一個函數,輸入兩個數組,輸出它們的交集。輸出數組中不含重複的元素,元素排列順序可隨意。

原題地址:https://leetcode-cn.com/problems/intersection-of-two-arrays-ii/

  1. 二叉樹的搜索,輸入一個普通二叉樹的根節點,實現一個調度器,調用調度器的next()方法,將返回二叉樹中下一個最小的數;調用迭代器的hasNext()方法,將返回是否存在下一個數。二叉樹節點是整數,無序。

原題地址:https://leetcode-cn.com/problems/binary-search-tree-iterator/

  1. 三角形個數,輸入一個非負整數的數組,如果將數組元素選作三角形的邊長,編寫一個函數,輸出這個數組可構成的三角形數量。

原題地址:https://leetcode-cn.com/problems/valid-triangle-number/

  1. 數組切分問題,輸入一個正序排列的整型數組,如果它可以被切分為1個或多個子序列,輸出True,反之False。子序列需為連續的整型數組,並且長度至少為3。
例1:
輸入: [1,2,3,3,4,5]
輸出: True
解釋:可以切分為2個各自連續的子序列:
1, 2, 3
3, 4, 5
例2:
輸入: [1,2,3,3,4,4,5,5]
輸出: True
解釋:可以切分為2個各自連續的子序列:
1, 2, 3, 4, 5
3, 4, 5
例3:
輸入: [1,2,3,4,4,5]
輸出: False
解釋:無法切分出長度至少為3的子序列。

原題地址:https://leetcode-cn.com/problems/split-array-into-consecutive-subsequences/

  1. 一隻青蛙一次可以跳上1級台階,也可以跳上2級。求該青蛙跳上一個n級的台階總共有多少種跳法.
  2. 求下面代碼的輸出
function test(a,b) {
  console.log(b)
  return {
    test:function(c){
      return test(c,a);
    }
  };
}

var retA = test(0);  
retA.test(2);  
retA.test(4);  
retA.test(8);
var retB = test(0).test(2).test(4).test(8);
var retC = test('good').test('bad');  
retC.test('good');  
retC.test('bad');
  1. top k

原題地址:https://leetcode-cn.com/problems/kth-largest-element-in-an-array/

  1. 閉包問題及優化
for (var i = 0; i < 4; i++) {
  setTimeout(function() {
    console.log(i);
  }, 300);
}

PS:一面筆試要求是30分鐘,前4道算法題,二面筆試題是15分鐘

與項目關係不大的問答題

  1. 節流防抖(實現/場景/源碼,如lodash實現原理)(https://www.cnblogs.com/LuckyWinty/p/5949970.html#4564734)
  2. 事件循環(瀏覽器/node/版本差異)(https://mp.weixin.qq.com/s/QgfE5Km1xiEkQqADMLmj-Q)
  3. setTimeout 實現原理(https://mp.weixin.qq.com/s/7qTRSMqaqG8XZ9rpEBhYNQ)
  4. react 和 vue 的區別
  5. Promise 原理(https://juejin.im/post/5d6f7c83e51d4561c541a712)
  6. 前端錯誤監控及容災(https://mp.weixin.qq.com/s/prf-mXexBh1Ie-ctq9FnzA)
  7. 性能優化(https://mp.weixin.qq.com/s/qXFd3f7CkEzz4u_1zl-TSw、https://mp.weixin.qq.com/s/dy1u2g9TeCoq2WOdPLqAXw、https://mp.weixin.qq.com/s/DJ8Fdq1_cIoW0_NYekZwFw、https://mp.weixin.qq.com/s/azeUIx0EA86EFQrtIRUKwQ、https://mp.weixin.qq.com/s/wDKKj5R8SYm-_75Zn1y30A、https://mp.weixin.qq.com/s/BOdnCYbMQfmCpUC3w3KZqw、https://mp.weixin.qq.com/s/FdG7uVIDXltNyskL3qh8Cw、太多了,貼不過來了,自己再總結吧)
  8. 談談 node 的內存泄漏(我的總結暫時沒時間寫,可以看看這篇,https://zhuanlan.zhihu.com/p/25736931)
  9. 開發過程中遇到的最大挑戰是什麼(梳理項目,得出難點)
  10. 學習的動力怎麼來的,如何維持(有興趣可以留意一下我的直播)
  11. 瀏覽器的渲染機制是怎樣的(https://mp.weixin.qq.com/s/wcw30EUb2ds3AoW176WGeg)
  12. SSR 作用及優缺點(seo/首屏快/開發成本高等,我項目用的是vue ssr,沒專門總結,可以先看這個,https://zhuanlan.zhihu.com/p/35871344)
  13. 如何進行狀態管理(vuex/redux)
  14. webpack 及瀏覽器的技術分享目的是什麼,分享了什麼,怎麼做的分享(https://mp.weixin.qq.com/s/1FySzmVrNjS6wjgqALC96g、https://mp.weixin.qq.com/s/wcw30EUb2ds3AoW176WGeg)
  15. 如何進行項目重構(知乎很多討論,直接去參考就可以了,或者看看這個https://www.itzhai.com/refactoring/refactoring-principle.html)
  16. 進程與線程的區別(https://www.zhihu.com/question/25532384)
  17. 說說知道的設計模式(參考掘金小冊子就可以了)
  18. CI/CD(https://mp.weixin.qq.com/s/MbeW8UNZ1fPekWcaNqmsCQ)

PS:由於面試全過程歷時比較長,一些題目已經忘記了。大概記得這麼點,然後很看項目,每一輪都詳細問了項目~

可能感興趣的問答

  1. 面試一共幾輪

我本人一共 4 輪技術面 + 1 輪HR面。目前微信職級為9級以下的技術崗不用經過面委,9級以下的一般4輪技術面,內部轉崗可3輪技術面,9級及以上的需要走面委面試,大概形式是做份ppt去講自己的項目經歷及其他技術項。9級及以上的就5-10輪技術面不等。

  1. 歷時多長

我本人總歷時一個多月(相對來說算很快了),所以如果你要面騰訊,千萬不要裸辭,不對,面什麼都不要裸辭,這年頭不好混,慫一點。

  1. 整體面試流程是怎樣的

內推->一面->二面->三面->四面->HR面->口頭offer->正式offer->背調->入職

每個階段耗時一到兩周的時間

  1. 微信工作地點

目前微信總部在廣州,大部分的組都在廣州,其中微信支付在深圳。

  1. 微信考算法多嗎

多,基本上就是算法+項目

阿里

筆試

  1. n階樓梯問題(尾遞歸的優化[函數最後調用自身可以減少中間變量|化遞歸為循環去優化]/備忘錄優化)
  2. 節流防抖的實現(分析筆試答案時問到,總結差別,說出應用場景)(https://www.cnblogs.com/LuckyWinty/p/5949970.html#4564734)
  3. 深拷貝(類型考慮/Symbol/Date等的構造/循環優化/共用引用優化等),這裏貼2篇文章給大家參考,https://juejin.im/post/5d6aa4f96fb9a06b112ad5b1,https://mp.weixin.qq.com/s/M7KBX3w2KqlWhZFHJSYP6Q)
  4. 封裝一個只能輸入数字的React組件

問答題

  1. 輸入URL后發生了什麼(https://mp.weixin.qq.com/s/DLq_GIkdnuOayThfi3jI0A)
  2. 事件循環說一下(https://mp.weixin.qq.com/s/QgfE5Km1xiEkQqADMLmj-Q)
  3. JS有幾種基本類型,分別是什麼,與對象的區別(不貼鏈接了,我認為是前端的都應該知道)
  4. JS 執行過程中是如何保存上下文的(堆和棧,可以看極客時間的《瀏覽器工作原理》,或者參考我這裏,https://mp.weixin.qq.com/s/klZ6j3Gj9cwHGQFys6Hdjg、https://mp.weixin.qq.com/s/HqADCzMGlIFDNnMRLsPTAA)
  5. 你認為什麼是前端
  6. 為什麼想來阿里
  7. 最近在看什麼書
  8. 微前端了解嗎(https://mp.weixin.qq.com/s/awBqvJmqWc7JGxwgB0QQZA、https://mp.weixin.qq.com/s/80S-RFmoZoq8KfCH6YZ_Tg、https://mp.weixin.qq.com/s/HVwcY8JGyrK8VcN1Ic9sWQ)
  9. 你想成為什麼樣的人(個人成長規劃)
  10. 項目中遇到的最大挑戰是什麼,如何解決的
  11. node 大量日誌怎麼處理的(緩衝隊列)
  12. http2 的特點(https://mp.weixin.qq.com/s/OitrWEosrpuXh19o_TDasg)
  13. node 與其他語言有什麼區別,其優劣勢是什麼
  14. csrf 的核心原理(https://juejin.im/post/5bc009996fb9a05d0a055192)
  15. node 事件循環(https://mp.weixin.qq.com/s/QgfE5Km1xiEkQqADMLmj-Q)
  16. FCP/FMP/FP 分別是怎樣定義,如何統計(https://mp.weixin.qq.com/s/wDKKj5R8SYm-_75Zn1y30A)
  17. MySQL 題目,id 唯一,name 可以重複,求 name 有重複的所有數據
  18. 有沒有推動過什麼東西
  19. 未來的一個發展是否是全棧,如何規劃(可以留意我的直播)
  20. 鏈路錄屏的原理(可以分析rrweb即可,參考例子,https://mp.weixin.qq.com/s/PxEzBrr3YF1jD84c_p1uAA)
  21. 鏈路錄屏法務問題如何解決(屏蔽關鍵信息/用戶授權等)
  22. FMP 定義及統計,w3c的草案你知道嗎(自行谷歌查找)
  23. react 項目的可持續維護性如何體現(自行谷歌查找)
  24. react hooks用過嗎,為什麼要用(沒有專門總結,自行谷歌查找)
  25. h5 和小程序有什麼區別(自行谷歌查找)
  26. https加密原理,中間人攻擊知道嗎(https://mp.weixin.qq.com/s/aMYp6Y5n26r9vdQIom4g0w、https://mp.weixin.qq.com/s/sHtZhRTNOihmxap5sDD6xQ)
  27. ng 負載均衡的方式有哪些(https://mp.weixin.qq.com/s/u-XbBwGxHrhJGiMiiqz26w、https://mp.weixin.qq.com/s/o2Us4Zj6DO2NHGQVaHIa1A)
  28. CDN 有什麼作用(https://github.com/LuckyWinty/fe-weekly-questions/issues/24)
  29. 不可變數據裏面,immutable,刪除數組裡面的列表(https://juejin.im/post/5b9b30a35188255c6418e67c,
    https://juejin.im/post/5e6a14b1f265da572978a1d3)
  30. 垃圾回收中,內部函數返給上層的對象是如何管理的
  31. es 靜態分析原理(https://zhuanlan.zhihu.com/p/33843378)
  32. 有一個很大很大的文件,如何統計文件裏面重複最多的行是哪行(參考git的記錄存儲)

頭條

筆試題

一面:

  1. 執行代碼求輸出,並說明為什麼,嚴格模式下輸出有變化嗎,為什麼
var a = function () {this.b = 3;}
var c = new a();
a.prototype.b = 9;
var b = 7;
a();

console.log(b);
console.log(c.b);
  1. 給定一個升序整型數組[0,1,2,4,5,7,13,15,16],找出其中連續出現的数字區間,輸出為[“0->2″,”4->5″,”7″,”13″,”15->16”]
function summaryRanges(arr){
    //TODO
}
  1. 請實現以下的函數,可以批量請求數據,所有的URL地址在urls參數中,同時可以通過 max 參數控制請求的併發度,當所有請求結束之後,需要執行 callback 回調函數。發請求的函數可以直接使用 fetch 即可
function sendRequest(urls: sring[],max:number,callback:()=>void){
    //TODO
}

二面:

  1. 實現一個字符串反轉:
    輸入:www.toutiao.com.cn
    輸出:cn.com.toutiao.www

要求:
1.不使用字符串處理函數
2.空間複雜度盡可能小

  1. 不藉助變量,交換兩個數。
function swap(a, b) {
    //TODO
}
  1. 觀察者模式與發布訂閱者區別,並寫出其模型

與項目無絕對相關的問答題

  1. vue 事件機制是如何實現的 (https://juejin.im/post/59ca5e975188257a8908959b)
  2. vue 的組件通信方式有哪些
  3. react fiber 的實現原理 (https://juejin.im/post/5dadc6045188255a270a0f85#comment)
  4. vue 響應式數據原理(vue2/vue3/依賴收集/發布訂閱/watcher消息隊列控制/Vue.set實現)(https://mp.weixin.qq.com/s/zDv_IQ36o_rRD25xN9uyuw、https://mp.weixin.qq.com/s/hTygoAan4yH3V4XV9iE1Pw)
  5. vue 轉小程序怎麼實現(ast/生命周期對齊/跨平台模塊兼容/兼容細節點實現過程)
  6. 性能指標,如何理解TTI,如何統計,與FID有什麼區別,如何實現統計,還聊了很多性能的東西(https://mp.weixin.qq.com/s/wDKKj5R8SYm-_75Zn1y30A)
  7. 說說你所了解的安全問題及防護方法(https://mp.weixin.qq.com/s/rU32rVM6Q-ele01ZB3RFzg)
  8. 說說你知道的設計模式,並舉個對應的模式例子(https://mp.weixin.qq.com/s/x3OCgS_knmM4D5zNSIVGRg)
  9. 未來規劃及學習方法
  10. 你覺得你是怎樣拿到京東校招的sp的
  11. 遇到的最大挑戰/過去的最大收穫分別是什麼

我本人的博客/公眾號,似乎面試官都看過,都知道我學過什麼,知道什麼,所以很多我博客上有的東西都沒問,甚至我引申到過去,都不讓說,有種沒機會表現的感覺,哈哈

感受&更多學習資料

其實單看問題,參考性還是比較小的,畢竟面試官主要會根據簡歷去發問。這裏的一個感受就是,項目中遇到的最大挑戰,這個問題真不好答,我當時答得也不夠好,後面又回去總結了一波項目,建議大家都好好總結一下自己平時遇到的問題,尋根究底。

這部分的題目,我會同步到我的每周N題上,歡迎大家來交流答案啊。想刷題的也可以來,地址如下:
https://github.com/LuckyWinty/fe-weekly-questions/issues

有很多知識點,雖然我沒被問到,但是我寫了不少文章,感興趣的話可以關注一下我的博客,地址如下:
https://github.com/LuckyWinty/blog

更多我覺得比較好的博客,地址如下:

  • https://juejin.im/user/5cf288385188254abb110e3b/posts
  • https://juejin.im/user/58d4e734570c350058cbb900/posts
  • http://blog.poetries.top/FE-Interview-Questions/
  • https://juejin.im/user/5bea27965188250edf4ad8b7/posts
  • https://juejin.im/user/5c45ddf06fb9a04a006f5491/posts

交流

  • 歡迎加我微信(winty230),拉你進技術群,長期交流學習…
  • 歡迎關注「前端Q」,認真學前端,做個專業的技術人…

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

【其他文章推薦】

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

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

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

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

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

※教你寫出一流的銷售文案?

面試:在面試中關於List(ArrayList、LinkedList)集合會怎麼問呢?你該如何回答呢?

前言

在一開始基礎面的時候,很多面試官可能會問List集合一些基礎知識,比如:

  • ArrayList默認大小是多少,是如何擴容的?

  • ArrayListLinkedList的底層數據結構是什麼?

  • ArrayListLinkedList的區別?分別用在什麼場景?

  • 為什麼說ArrayList查詢快而增刪慢?

  • Arrays.asList方法后的List可以擴容嗎?

  • modCount在非線程安全集合中的作用?

  • ArrayListLinkedList的區別、優缺點以及應用場景

 

ArrayList(1.8)

ArrayList是由動態再分配的Object[]數組作為底層結構,可設置null值,是非線程安全的。

ArrayList成員屬性

//默認的空的數組,在構造方法初始化一個空數組的時候使用
private static final Object[] EMPTY_ELEMENTDATA = {};
​
//使用默認size大小的空數組實例
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
​
//ArrayList底層存儲數據就是通過數組的形式,ArrayList長度就是數組的長度。
transient Object[] elementData; 
​
//arrayList的大小
private int size;

那麼ArrayList底層數據結構是什麼呢?

很明顯,使用動態再分配的Object[]數組作為ArrayList底層數據結構了,既然是使用數組實現的,那麼數組特點就能說明為什麼ArrayList查詢快而增刪慢?

因為數組是根據下標查詢不需要比較,查詢方式為:首地址+(元素長度*下標),基於這個位置讀取相應的字節數就可以了,所以非常快;但是增刪會帶來元素的移動,增加數據會向後移動,刪除數據會向前移動,導致其效率比較低。

 

ArrayList的構造方法

  • 帶有初始化容量的構造方法

  • 無參構造方法

  • 參數為Collection類型的構造器

//帶有初始化容量的構造方法
public ArrayList(int initialCapacity) {
    //參數大於0,elementData初始化為initialCapacity大小的數組
    if (initialCapacity > 0) {
        this.elementData = new Object[initialCapacity];
    //參數小於0,elementData初始化為空數組
    } else if (initialCapacity == 0) {
        this.elementData = EMPTY_ELEMENTDATA;
    //參數小於0,拋出異常
    } else {
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    }
}
​
//無參構造方法
public ArrayList() {
    //在1.7以後的版本,先構造方法中將elementData初始化為空數組DEFAULTCAPACITY_EMPTY_ELEMENTDATA
    //當調用add方法添加第一個元素的時候,會進行擴容,擴容至大小為DEFAULT_CAPACITY=10
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

那麼ArrayList默認大小是多少?

從無參構造方法中可以看出,一開始默認為一個空的實例elementData為上面的DEFAULTCAPACITY_EMPTY_ELEMENTDATA,當添加第一個元素的時候會進行擴容,擴容大小就是上面的默認容量DEFAULT_CAPACITY10

ArrayList的Add方法

  • boolean add(E):默認直接在末尾添加元素

  • void add(int,E):在特定位置添加元素,也就是插入元素

  • boolean addAll(Collection<? extends E> c):添加集合

  • boolean addAll(int index, Collection<? extends E> c):在指定位置后添加集合

boolean add(E)
public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}

通過ensureCapacityInternal方法為確定容量大小方法。在添加元素之前需要確定數組是否能容納下,size是數組中元素個數,添加一個元素size+1。然後再數組末尾添加元素。

其中,ensureCapacityInternal方法包含了ArrayList擴容機制grow方法,當前容量無法容納下數據時1.5倍擴容,進行:

private void ensureCapacityInternal(int minCapacity) {
    //判斷當前的數組是否為默認設置的空數據,是否取出最小容量
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    //包括擴容機制grow方法
    ensureExplicitCapacity(minCapacity);
}
​
private void ensureExplicitCapacity(int minCapacity) {
        //記錄著集合的修改次數,也就每次add或者remove它的值都會加1
        modCount++;
​
        //當前容量容納不下數據時(下標超過時),ArrayList擴容機制:擴容原來的1.5倍
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
​
private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        //ArrayList擴容機制:擴容原來的1.5倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

ArrayList是如何擴容的?

根據當前的容量容納不下新增數據時,ArrayList會調用grow進行擴容:

//相當於int newCapacity = oldCapacity + oldCapacity/2
int newCapacity = oldCapacity + (oldCapacity >> 1);

擴容原來的1.5倍。

void add(int,E)
public void add(int index, E element) {
    //檢查index也就是插入的位置是否合理,是否存在數組越界
    rangeCheckForAdd(index);
    //機制和boolean add(E)方法一樣
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    System.arraycopy(elementData, index, elementData, index + 1,
                     size - index);
    elementData[index] = element;
    size++;
}

ArrayList的刪除方法

  • remove(int):通過刪除指定位置上的元素,

  • remove(Object):根據元素進行刪除,

  • clear():elementData中每個元素都賦值為null,等待垃圾回收將這個給回收掉,

  • removeAll(collection c):批量刪除。

 

remove(int)
public E remove(int index) {
    //檢查下標是否超出數組長度,造成數組越界
    rangeCheck(index);
​
    modCount++;
    E oldValue = elementData(index);
    //算出數組需要移動的元素數量
    int numMoved = size - index - 1;
    if (numMoved > 0)
        //數組數據遷移,這樣會導致刪除數據時,效率會慢
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
    //將--size上的位置賦值為null,讓gc(垃圾回收機制)更快的回收它。
    elementData[--size] = null; // clear to let GC do its work
    //返回刪除的元素
    return oldValue;
}

為什麼說ArrayList刪除元素效率低?

因為刪除數據需要將數據後面的元素數據遷移到新增位置的後面,這樣導致性能下降很多,效率低。

remove(Object)
public boolean remove(Object o) {
    //如果需要刪除數據為null時,會讓數據重新排序,將null數據遷移到數組尾端
    if (o == null) {
        for (int index = 0; index < size; index++)
            if (elementData[index] == null) {
                //刪除數據,並遷移數據
                fastRemove(index);
                return true;
            }
    } else {
        //循環刪除數組中object對象的值,也需要數據遷移
        for (int index = 0; index < size; index++)
            if (o.equals(elementData[index])) {
                fastRemove(index);
                return true;
            }
    }
    return false;
}

可以看出,arrayList是可以存放null值。

 

LinkedList(1.8)

LinkedList是一個繼承於AbstractSequentialList的雙向鏈表。它也可以被當做堆棧、隊列或雙端隊列進行使用,而且LinkedList也為非線程安全, jdk1.6使用的是一個帶有 header節頭結點的雙向循環鏈表, 頭結點不存儲實際數據 ,在1.6之後,就變更使用兩個節點firstlast指向首尾節點。

LinkedList的主要屬性

//鏈表節點的個數 
transient int size = 0; 
//鏈表首節點
 transient Node<E> first; 
//鏈表尾節點
 transient Node<E> last; 
//Node節點內部類定義
private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;
​
        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }

一旦變量被transient修飾,變量將不再是對象持久化的一部分,該變量內容在序列化后無法獲得訪問

LinkedList構造方法

無參構造函數, 默認構造方法聲明也不做,firstlast節點會被默認初始化為null。

*
/** Constructs an empty list. \*/*public LinkedList() {}
​

LinkedList插入

由於LinkedList由雙向鏈表作為底層數據結構,因此其插入無非由三大種

  • 尾插: add(E e)addLast(E e)addAll(Collection<? extends E> c)

  • 頭插: addFirst(E e)

  • 中插: add(int index, E element)

可以從源碼看出,在鏈表首尾添加元素很高效,在中間添加元素比較低效,首先要找到插入位置的節點,在修改前後節點的指針。

 

 

尾插-add(E e)和addLast(E e)
//常用的添加元素方法
public boolean add(E e) {
    //使用尾插法
    linkLast(e);
    return true;
}
​
//在鏈表尾部添加元素
public void addLast(E e) {
        linkLast(e);
    }
​
//在鏈表尾端添加元素
void linkLast(E e) {
        //尾節點
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        //判斷是否是第一個添加的元素
        //如果是將新節點賦值給last
        //如果不是把原首節點的prev設置為新節點
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        //將集合修改次數加1
        modCount++;
    }
​
頭插-addFirst(E e)
public void addFirst(E e) {
    //在鏈表頭插入指定元素
    linkFirst(e);
}
​
private void linkFirst(E e) {
         //獲取頭部元素,首節點
        final Node<E> f = first;
        final Node<E> newNode = new Node<>(null, e, f);
        first = newNode;
        //鏈表頭部為空,(也就是鏈表為空)
        //插入元素為首節點元素
        // 否則就更新原來的頭元素的prev為新元素的地址引用
        if (f == null)
            last = newNode;
        else
            f.prev = newNode;
        //
        size++;
        modCount++;
    }
中插-add(int index, E element)

index不為首尾的的時候,實際就在鏈表中間插入元素。

 // 作用:在指定位置添加元素
    public void add(int index, E element) {
        // 檢查插入位置的索引的合理性
        checkPositionIndex(index);
​
        if (index == size)
            // 插入的情況是尾部插入的情況:調用linkLast()。
            linkLast(element);
        else
            // 插入的情況是非尾部插入的情況(中間插入):linkBefore
            linkBefore(element, node(index));
    }
​
    private void checkPositionIndex(int index) {
        if (!isPositionIndex(index))
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }
​
    private boolean isPositionIndex(int index) {
        return index >= 0 && index <= size;
    }
​
    void linkBefore(E e, Node<E> succ) {
        // assert succ != null;
        final Node<E> pred = succ.prev;  // 得到插入位置元素的前繼節點
        final Node<E> newNode = new Node<>(pred, e, succ);  // 創建新節點,其前繼節點是succ的前節點,後接點是succ節點
        succ.prev = newNode;  // 更新插入位置(succ)的前置節點為新節點
        if (pred == null)
            // 如果pred為null,說明該節點插入在頭節點之前,要重置first頭節點 
            first = newNode;
        else
            // 如果pred不為null,那麼直接將pred的後繼指針指向newNode即可
            pred.next = newNode;
        size++;
        modCount++;
    }

LinkedList 刪除

刪除和插入一樣,其實本質也是只有三大種方式,

  • 刪除首節點:removeFirst()

  • 刪除尾節點:removeLast()

  • 刪除中間節點 :remove(Object o)remove(int index)

在首尾節點刪除很高效,刪除中間元素比較低效要先找到節點位置,再修改前後指針指引。

 

 

刪除中間節點-remove(int index)和remove(Object o)
remove(int index)和remove(Object o)都是使用刪除指定節點的unlink刪除元素

 public boolean remove(Object o) {
     //因為LinkedList允許存在null,所以需要進行null判斷        
     if (o == null) {
         //從首節點開始遍歷
         for (Node<E> x = first; x != null; x = x.next) {
             if (x.item == null) {
                 //調用unlink方法刪除指定節點
                 unlink(x);
                 return true;
             }
         }
     } else {
         for (Node<E> x = first; x != null; x = x.next) {
             if (o.equals(x.item)) {
                 unlink(x);
                 return true;
             }
         }
     }
    return false;
 } 
​
//刪除指定位置的節點,其實和上面的方法差不多
    //通過node方法獲得指定位置的節點,再通過unlink方法刪除
    public E remove(int index) {
        checkElementIndex(index);
       
        return unlink(node(index));
    }
​
 //刪除指定節點
    E unlink(Node<E> x) {
        //獲取x節點的元素,以及它上一個節點,和下一個節點
        final E element = x.item;
        final Node<E> next = x.next;
        final Node<E> prev = x.prev;
        //如果x的上一個節點為null,說明是首節點,將x的下一個節點設置為新的首節點
        //否則將x的上一節點設置為next,將x的上一節點設為null
        if (prev == null) {
            first = next;
        } else {
            prev.next = next;
            x.prev = null;
        }
        //如果x的下一節點為null,說明是尾節點,將x的上一節點設置新的尾節點
        //否則將x的上一節點設置x的上一節點,將x的下一節點設為null
        if (next == null) {
            last = prev;
        } else {
            next.prev = prev;
            x.next = null;
        }
        //將x節點的元素值設為null,等待垃圾收集器收集
        x.item = null;
        //鏈表節點個數減1
        size--;
        //將集合修改次數加1
        modCount++;
        //返回刪除節點的元素值
        return element;
    }
刪除首節點-removeFirst()
//刪除首節點
public E remove() {
        return removeFirst();
    }
 //刪除首節點
 public E removeFirst() {
      final Node<E> f = first;
      //如果首節點為null,說明是空鏈表,拋出異常
      if (f == null)
          throw new NoSuchElementException();
      return unlinkFirst(f);
  }
  //刪除首節點
  private E unlinkFirst(Node<E> f) {
      //首節點的元素值
      final E element = f.item;
      //首節點的下一節點
      final Node<E> next = f.next;
      //將首節點的元素值和下一節點設為null,等待垃圾收集器收集
      f.item = null;
      f.next = null; // help GC
      //將next設置為新的首節點
      first = next;
      //如果next為null,說明說明鏈表中只有一個節點,把last也設為null
      //否則把next的上一節點設為null
      if (next == null)
          last = null;
      else
          next.prev = null;
      //鏈表節點個數減1
      size--;
      //將集合修改次數加1
      modCount++;
      //返回刪除節點的元素值
      return element;
 }
刪除尾節點-removeLast()
  
 //刪除尾節點
    public E removeLast() {
        final Node<E> l = last;
        //如果首節點為null,說明是空鏈表,拋出異常
        if (l == null)
            throw new NoSuchElementException();
        return unlinkLast(l);
    }
    private E unlinkLast(Node<E> l) {
        //尾節點的元素值
        final E element = l.item;
        //尾節點的上一節點
        final Node<E> prev = l.prev;
        //將尾節點的元素值和上一節點設為null,等待垃圾收集器收集
        l.item = null;
        l.prev = null; // help GC
        //將prev設置新的尾節點
        last = prev;
        //如果prev為null,說明說明鏈表中只有一個節點,把first也設為null
        //否則把prev的下一節點設為null
        if (prev == null)
            first = null;
        else
            prev.next = null;
        //鏈表節點個數減1
        size--;
        //將集合修改次數加1
        modCount++;
        //返回刪除節點的元素值
        return element;
    }

其他方法也是類似的,比如查詢方法 LinkedList提供了getgetFirstgetLast等方法獲取節點元素值。

modCount屬性的作用?

modCount屬性代表為結構性修改( 改變list的size大小、以其他方式改變他導致正在進行迭代時出現錯誤的結果)的次數,該屬性被Iterator以及ListIterator的實現類所使用,且很多非線程安全使用modCount屬性。

初始化迭代器時會給這個modCount賦值,如果在遍歷的過程中,一旦發現這個對象的modCount和迭代器存儲的modCount不一樣,Iterator或者ListIterator 將拋出ConcurrentModificationException異常,

這是jdk在面對迭代遍歷的時候為了避免不確定性而採取的 fail-fast(快速失敗)原則:

在線程不安全的集合中,如果使用迭代器的過程中,發現集合被修改,會拋出ConcurrentModificationExceptions錯誤,這就是fail-fast機制。對集合進行結構性修改時,modCount都會增加,在初始化迭代器時,modCount的值會賦給expectedModCount,在迭代的過程中,只要modCount改變了,int expectedModCount = modCount等式就不成立了,迭代器檢測到這一點,就會拋出錯誤:urrentModificationExceptions

 

總結

ArrayList和LinkedList的區別、優缺點以及應用場景

區別:

  • ArrayList是實現了基於動態數組的數據結構,LinkedList是基於鏈表結構。

  • 對於隨機訪問的getset方法查詢元素,ArrayList要優於LinkedList,因為LinkedList循環鏈表尋找元素。

  • 對於新增和刪除操作addremoveLinkedList比較高效,因為ArrayList要移動數據。

優缺點:

  • ArrayListLinkedList而言,在末尾增加一個元素所花的開銷都是固定的。對ArrayList而言,主要是在內部數組中增加一項,指向所添加的元素,偶爾可能會導致對數組重新進行分配;而對LinkedList而言,這個開銷是 統一的,分配一個內部Entry對象。

  • ArrayList集合中添加或者刪除一個元素時,當前的列表移動元素後面所有的元素都會被移動。而LinkedList集合中添加或者刪除一個元素的開銷是固定的。

  • LinkedList集合不支持 高效的隨機隨機訪問(RandomAccess),因為可能產生二次項的行為。

  • ArrayList的空間浪費主要體現在在list列表的結尾預留一定的容量空間,而LinkedList的空間花費則體現在它的每一個元素都需要消耗相當的空間

應用場景:

ArrayList使用在查詢比較多,但是插入和刪除比較少的情況,而LinkedList用在查詢比較少而插入刪除比較多的情況

各位看官還可以嗎?喜歡的話,動動手指點個,點個關注唄!!謝謝支持!

歡迎掃碼關注,原創技術文章第一時間推出

 

 

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

【其他文章推薦】

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

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

※推薦評價好的iphone維修中心

QNX Message Passing,一個讓人頭禿的 IPC BUG

問題描述

QNX系統中 Client 與 Server 通過 QNX Message Passing 進行進程間通信。正式開發前,寫過測試程序 (Client),和 Server 通信一切正常。但把同樣的代碼拷貝到正式的 Client 中,結果發現調用 MsgSend() 后無響應,pidin 显示 Client 處於 REPLY PENDING 的狀態。

幾番嘗試,發現一個讓人很難接受的事實:只能在 Client 的主線程中調用 MsgSend() 才能收到 Server 的回復,如果在 Client 的對等線程中調用MsgSend(),則會因為收不到 Server 的回復而 Pending。

問題分析

測試程序能正常工作,所以起初懷疑是 Client 的問題。面對龐大的 Client,始終沒想到突破口。甚至曾一度懷疑是否是 QNX 的系統限制,MsgSend() 只能在主線程中調用,官網文檔翻了一圈並沒有發現這樣的限制。自己寫了個 IPC Server 來測試,發現並沒有這個問題。

Client Server 結果
測試程序,主線程中調用 MsgSend() 正式 Server OK
正式 Client,對等線程中調用 MsgSend() 正式 Server REPLY PENDING
正式 Client,對等線程中調用 MsgSend() 簡化版測試 Server OK

最後不得不懷疑起 Server,莫非 Server 端有什麼機制能檢測到消息是發自主線程還是對等線程,然後只回復來自主線程的 IPC 請求?

一個典型的 IPC Server 示例代碼如下:

While(1) {
   int rcvid = MsgReceive(chid, &recvBuf, sizeof(recvBuf), NULL);
   /* … process the request based on recvBuf … */
   MsgReply(rcvid, EOK, &replyBuf, sizeof(replyBuf)); // reply to unblock the IPC client
}

如果是從 Client 的主線程發送來的消息,rcvid 是一個很小的数字,如 1, 3, 5… 如果是從Client 的對等線程發送來的消息,rcvid 是一個大於 65535 的数字,如 65538, 65540, 65542… 

讓人意外的是 Server 用了一個 int16_t 來保存 rcvid,直接導致後續的 MsgReply() 無法正確的將消息回給 Client,從而導致 Client 一直處於 REPLY PENDING 狀態。

Reference

  • http://www.qnx.com/developers/docs/7.0.0/#com.qnx.doc.neutrino.sys_arch/topic/ipc_Robust.html  

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

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

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

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

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

※教你寫出一流的銷售文案?

※超省錢租車方案

Docker_01

目錄

  • 1.1 Docker簡介
    • 1.1.1 為什麼會有Docker的出現?
    • 1.1.2 Docker理念
    • 1.1.3 Docker or 虛擬機?
  • 2.1 Docker安裝
  • 3.1 Docker基本使用
    • 3.1.1 什麼是鏡像?
    • 3.1.2 Docker鏡像加載原理
    • 3.1.3 常用命令
  • 4.1 重要知識點

1.1 Docker簡介

1.1.1 為什麼會有Docker的出現?

一款產品從開發到上線,從操作系統,到運行環境,再到應用配置。作為開發+運維之間的協作我們需要關心很多東西,這也是很多互聯網公司都不得不面對的問題,特別是各種版本的迭代之後,不同版本環境的兼容,對運維人員都是考驗
Docker之所以發展如此迅速,也是因為它對此給出了一個標準化的解決方案。
環境配置如此麻煩,換一台機器,就要重來一次,費力費時。很多人想到,能不能從根本上解決問題。軟件可以帶環境安裝?1. 也就是說,安裝的時候,把原始環境一模一樣地複製過來。開發人員利用 Docker 可以消除協作編碼時“在我的機器上可正常工作”的問題。

1.1.2 Docker理念

Docker是基於Go語言實現的雲開源項目。
Docker的主要目標是“Build,Ship and Run Any App,Anywhere”,也就是通過對應用組件的封裝、分發、部署、運行等生命周期的管理,使用戶的APP(可以是一個WEB應用或數據庫應用等等)及其運行環境能夠做到“一次封裝,到處運行”。
Linux 容器技術的出現就解決了這樣一個問題,而 Docker 就是在它的基礎上發展過來的。將應用運行在 Docker 容器上面,而 Docker 容器在任何操作系統上都是一致的,這就實現了跨平台、跨服務器。只需要一次配置好環境,換到別的機子上就可以一鍵部署好,大大簡化了操作。

總而言之:解決了運行環境和配置問題軟件容器,方便做持續集成並有助於整體發布的容器虛擬化技術。

1.1.3 Docker or 虛擬機?

虛擬機(virtual machine)就是帶環境安裝的一種解決方案。
它可以在一種操作系統裏面運行另一種操作系統,比如在Windows 系統裏面運行Linux 系統。應用程序對此毫無感知,因為虛擬機看上去跟真實系統一模一樣,而對於底層系統來說,虛擬機就是一個普通文件,不需要了就刪掉,對其他部分毫無影響。這類虛擬機完美的運行了另一套系統,能夠使應用程序,操作系統和硬件三者之間的邏輯不變。 
但是虛擬機有很多缺點:1.資源佔用多2.冗餘步驟多3.啟動慢

由於前面虛擬機存在這些缺點,Linux 發展出了另一種虛擬化技術:Linux 容器(Linux Containers,縮寫為 LXC)。
Linux 容器不是模擬一個完整的操作系統,而是對進程進行隔離。有了容器,就可以將軟件運行所需的所有資源打包到一個隔離的容器中。容器與虛擬機不同,不需要捆綁一整套操作系統,只需要軟件工作所需的庫資源和設置。系統因此而變得高效輕量並保證部署在任何環境中的軟件都能始終如一地運行。
 
比較了 Docker 和傳統虛擬化方式的不同之處:

  • 傳統虛擬機技術是虛擬出一套硬件后,在其上運行一個完整操作系統,在該系統上再運行所需應用進程;
  • 而容器內的應用進程直接運行於宿主的內核,容器內沒有自己的內核,而且也沒有進行硬件虛擬。因此容器要比傳統虛擬機更為輕便。
  • 每個容器之間互相隔離,每個容器有自己的文件系統 ,容器之間進程不會相互影響,能區分計算資源。

對於開發和運維來說Docker的特點:

  • 更快速的應用交付和部署:傳統的應用開發完成后,需要提供一堆安裝程序和配置說明文檔,安裝部署后需根據配置文檔進行繁雜的配置才能正常運行。Docker化之後只需要交付少量容器鏡像文件,在正式生產環境加載鏡像並運行即可,應用安裝配置在鏡像里已經內置好,大大節省部署配置和測試驗證時間。
  • 更便捷的升級和擴縮容:隨着微服務架構和Docker的發展,大量的應用會通過微服務方式架構,應用的開發構建將變成搭樂高積木一樣,每個Docker容器將變成一塊“積木”,應用的升級將變得非常容易。當現有的容器不足以支撐業務處理時,可通過鏡像運行新的容器進行快速擴容,使應用系統的擴容從原先的天級變成分鐘級甚至秒級。
  • 更簡單的系統運維:應用容器化運行后,生產環境運行的應用可與開發、測試環境的應用高度一致,容器會將應用程序相關的環境和狀態完全封裝起來,不會因為底層基礎架構和操作系統的不一致性給應用帶來影響,產生新的BUG。當出現程序異常時,也可以通過測試環境的相同容器進行快速定位和修復。
  • 更高效的計算資源利用: Docker是內核級虛擬化,其不像傳統的虛擬化技術一樣需要額外的Hypervisor支持,所以在一台物理機上可以運行很多個容器實例,可大大提升物理服務器的CPU和內存的利用率。

2.1 Docker安裝

安裝地址有兩個:

  • docker官網:(http://www.docker.com)
  • docker中文官網:(https://www.docker-cn.com/)
    跟github一樣docker也有自己的中心倉庫Docker Hub官網: https://hub.docker.com/
    Linux環境下安裝的話可能要注意套個CDN加速一般選擇阿里雲或者網易的鏡像庫。

安裝命令:

$ sudo yum install -y yum-utils

$ sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
These repositories are included in the docker.repo file above but are disabled by default. You can enable them alongside the stable repository. The following command enables the nightly repository.

$ sudo yum-config-manager --enable docker-ce-nightly
To enable the test channel, run the following command:

$ sudo yum-config-manager --enable docker-ce-test
You can disable the nightly or test repository by running the yum-config-manager command with the --disable flag. To re-enable it, use the --enable flag. The following command disables the nightly repository.

$ sudo yum-config-manager --disable docker-ce-nightly

具體方法參考官網:https://docs.docker.com/engine/install/centos/

3.1 Docker基本使用

3.1.1 什麼是鏡像?

鏡像是一種輕量級、可執行的獨立軟件包,用來打包軟件運行環境和基於運行環境開發的軟件,它包含運行某個軟件所需的所有內容,包括代碼、運行時、庫、環境變量和配置文件。
在Docker打包一個鏡像的時候會使用一個叫UnionFS(聯合文件系統)的文件系統:UnionFS(聯合文件系統):Union文件系統(UnionFS)是一種分層、輕量級並且高性能的文件系統,它支持對文件系統的修改作為一次提交來一層層的疊加,同時可以將不同目錄掛載到同一個虛擬文件系統下(unite several directories into a single virtual filesystem)。Union 文件系統是 Docker 鏡像的基礎。鏡像可以通過分層來進行繼承,基於基礎鏡像(沒有父鏡像),可以製作各種具體的應用鏡像。
特性:一次同時加載多個文件系統,但從外面看起來,只能看到一個文件系統,聯合加載會把各層文件系統疊加起來,這樣最終的文件系統會包含所有底層的文件和目錄。

3.1.2 Docker鏡像加載原理

Docker鏡像加載原理:
docker的鏡像實際上由一層一層的文件系統組成,這種層級的文件系統UnionFS。
bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引導加載kernel, Linux剛啟動時會加載bootfs文件系統,在Docker鏡像的最底層是bootfs。這一層與我們典型的Linux/Unix系統是一樣的,包含boot加載器和內核。當boot加載完成之後整個內核就都在內存中了,此時內存的使用權已由bootfs轉交給內核,此時系統也會卸載bootfs。

rootfs (root file system) ,在bootfs之上。包含的就是典型 Linux 系統中的 /dev, /proc, /bin, /etc 等標準目錄和文件。rootfs就是各種不同的操作系統發行版,比如Ubuntu,Centos等等。

平時我們安裝進虛擬機的CentOS都是好幾個G,為什麼docker這裏才200M??
對於一個精簡的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序庫就可以了,因為底層直接用Host的kernel,自己只需要提供 rootfs 就行了。由此可見對於不同的linux發行版, bootfs基本是一致的, rootfs會有差別, 因此不同的發行版可以公用bootfs。

分層的鏡像:以我們的pull為例,在下載的過程中我們可以看到docker的鏡像好像是在一層一層的在下載.

為什麼 Docker 鏡像要採用這種分層結構呢?
最大的一個好處就是 – 共享資源
 
比如:有多個鏡像都從相同的 base 鏡像構建而來,那麼宿主機只需在磁盤上保存一份base鏡像,
同時內存中也只需加載一份 base 鏡像,就可以為所有容器服務了。而且鏡像的每一層都可以被共享。

3.1.3 常用命令

1.幫助命令:

  • docker version
  • docker info
  • docker –help

2.鏡像命令:

  • docker images OPTIONS說明:-a :列出本地所有的鏡像(含中間映像層)-q :只显示鏡像ID –digests :显示鏡像的摘要信息 –no-trunc :显示完整的鏡像信息。

  • docker search 某個XXX鏡像名字 OPTIONS說明:–no-trunc : 显示完整的鏡像描述 -s : 列出收藏數不小於指定值的鏡像 –automated : 只列出 automated build類型的鏡像;

  • docker pull 某個XXX鏡像名字

  • docker rmi 某個XXX鏡像名字ID 刪除鏡像
    3.容器命令:

  • 新建並啟動容器:
    docker run [OPTIONS] IMAGE [COMMAND] [ARG…]
    OPTIONS說明(常用):有些是一個減號,有些是兩個減號
     
    –name=”容器新名字”: 為容器指定一個名稱;
    -d: 後台運行容器,並返回容器ID,也即啟動守護式容器;
    -i:以交互模式運行容器,通常與 -t 同時使用;
    -t:為容器重新分配一個偽輸入終端,通常與 -i 同時使用;
    -P: 隨機端口映射;
    -p: 指定端口映射,有以下四種格式
          ip:hostPort:containerPort
          ip::containerPort
          hostPort:containerPort
          containerPort

  • 列出當前所有正在運行的容器
    docker ps [OPTIONS]
    OPTIONS說明(常用):
     
    -a :列出當前所有正在運行的容器+歷史上運行過的
    -l :显示最近創建的容器。
    -n:显示最近n個創建的容器。
    -q :靜默模式,只显示容器編號。
    –no-trunc :不截斷輸出。

  • 退出容器
    exit:容器停止退出。 ctrl+P+Q:容器不停止退出

  • 啟動容器
    docker start 容器ID或者容器名

  • 重啟容器
    docker restart 容器ID或者容器名

  • 停止容器
    docker stop 容器ID或者容器名

  • 強制停止容器
    docker kill 容器ID或者容器名

  • 刪除已停止的容器
    docker rm 容器ID(一次性刪除多個容器:1.docker rm -f $(docker ps -a -q)2.docker ps -a -q | xargs docker rm)

4.1 重要知識點

1.關於docker ps -a命令它不會列出你後台啟動的進程也就是說你用守護進程方式啟動容器的話:docker run -d 容器名是不會被ps出來的。
這個是docker的機制問題,比如你的web容器,我們以nginx為例,正常情況下,我們配置啟動服務只需要啟動響應的service即可。例如service nginx start但是,這樣做,nginx為後台進程模式運行,就導致docker前台沒有運行的應用,這樣的容器後台啟動后,會立即自殺因為他覺得他沒事可做了.所以,最佳的解決方案是,將你要運行的程序以前台進程的形式運行。
2.如何重新進入已經啟動的容器
有兩個法子:

  • docker exec -it 容器ID bashShell
  • docker attach 容器ID

上述兩個區別:

  • attach 直接進入容器啟動命令的終端,不會啟動新的進程
  • exec 是在容器中打開新的終端,並且可以啟動新的進程
    3.從容器內拷貝文件到主機上
    docker cp 容器ID:容器內路徑 目的主機路徑。

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

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

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

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

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

※別再煩惱如何寫文案,掌握八大原則!

網頁設計最專業,超強功能平台可客製化

【原創】Linux中斷子系統(三)-softirq和tasklet

背景

  • Read the fucking source code! –By 魯迅
  • A picture is worth a thousand words. –By 高爾基

說明:

  1. Kernel版本:4.14
  2. ARM64處理器,Contex-A53,雙核
  3. 使用工具:Source Insight 3.5, Visio

1. 概述

中斷子系統中有一個重要的設計機制,那就是Top-half和Bottom-half,將緊急的工作放置在Top-half中來處理,而將耗時的工作放置在Bottom-half中來處理,這樣確保Top-half能儘快完成處理,那麼為什麼需要這麼設計呢?看一張圖就明白了:

  • ARM處理器在進行中斷處理時,處理器進行異常模式切換,此時會將中斷進行關閉,處理完成后再將中斷打開;
  • 如果中斷不分上下半部處理,那麼意味着只有等上一个中斷完成處理后才會打開中斷,下一个中斷才能得到響應。當某个中斷處理處理時間較長時,很有可能就會造成其他中斷丟失而無法響應,這個顯然是難以接受的,比如典型的時鐘中斷,作為系統的脈搏,它的響應就需要得到保障;
  • 中斷分成上下半部處理可以提高中斷的響應能力,在上半部處理完成后便將中斷打開(通常上半部處理越快越好),這樣就可以響應其他中斷了,等到中斷退出的時候再進行下半部的處理;
  • 中斷的Bottom-half機制,包括了softirqtaskletworkqueue、以及前文中提到過的中斷線程化處理等,其中tasklet又是基於softirq來實現的,這也是本文討論的主題;

在中斷處理過程中,離不開各種上下文的討論,了解不同上下文的區分有助於中斷處理的理解,所以,還是來一張老圖吧:

  • task_struct結構體中的thread_info.preempt_count用於記錄當前任務所處的context狀態;
  • PREEMPT_BITS:用於記錄禁止搶佔的次數,禁止搶佔一次該值就加1,使能搶佔該值就減1;
  • SOFTIRQ_BITS:用於同步處理,關掉下半部的時候加1,打開下半部的時候減1;
  • HARDIRQ_BITS:用於表示處於硬件中斷上下文中;

前戲結束了,直奔主題吧。

2. softirq

2.1 初始化

softirq不支持動態分配,Linux kernel提供了靜態分配,關鍵的結構體描述如下,可以類比硬件中斷來理解:

/* 支持的軟中斷類型,可以認為是軟中斷號, 其中從上到下優先級遞減 */
enum
{
	HI_SOFTIRQ=0,       /* 最高優先級軟中斷 */
	TIMER_SOFTIRQ,      /* Timer定時器軟中斷 */
	NET_TX_SOFTIRQ,     /* 發送網絡數據包軟中斷 */
	NET_RX_SOFTIRQ,     /* 接收網絡數據包軟中斷 */
	BLOCK_SOFTIRQ,      /* 塊設備軟中斷 */
	IRQ_POLL_SOFTIRQ,   /* 塊設備軟中斷 */
	TASKLET_SOFTIRQ,    /* tasklet軟中斷 */
	SCHED_SOFTIRQ,      /* 進程調度及負載均衡的軟中斷 */
	HRTIMER_SOFTIRQ, /* Unused, but kept as tools rely on thenumbering. Sigh! */
	RCU_SOFTIRQ,    /* Preferable RCU should always be the last softirq, RCU相關的軟中斷 */

	NR_SOFTIRQS
};

/* 軟件中斷描述符,只包含一個handler函數指針 */
struct softirq_action {
	void	(*action)(struct softirq_action *);
};
/* 軟中斷描述符表,實際上就是一個全局的數組 */
static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp;

/* CPU軟中斷狀態描述,當某個軟中斷觸發時,__softirq_pending會置位對應的bit */
typedef struct {
	unsigned int __softirq_pending;
	unsigned int ipi_irqs[NR_IPI];
} ____cacheline_aligned irq_cpustat_t;
/* 每個CPU都會維護一個狀態信息結構 */
irq_cpustat_t irq_stat[NR_CPUS] ____cacheline_aligned;

/* 內核為每個CPU都創建了一個軟中斷處理內核線程 */
DEFINE_PER_CPU(struct task_struct *, ksoftirqd);

來一張圖吧:

  • softirq_vec[]數組,類比硬件中斷描述符表irq_desc[],通過軟中斷號可以找到對應的handler進行處理,比如圖中的tasklet_action就是一個實際的handler函數;
  • 軟中斷可以在不同的CPU上并行運行,在同一個CPU上只能串行執行;
  • 每個CPU維護irq_cpustat_t狀態結構,當某個軟中斷需要進行處理時,會將該結構體中的__softirq_pending字段或上1UL << XXX_SOFTIRQ

2.2 流程分析

2.2.1 軟中斷註冊

中斷處理流程中設備驅動通過request_irq/request_threaded_irq接口來註冊中斷處理函數,而在軟中斷處理流程中,通過open_softirq接口來註冊,由於它實在是太簡單了,我忍不住想把代碼貼上來:

void open_softirq(int nr, void (*action)(struct softirq_action *))
{
	softirq_vec[nr].action = action;
}

也就是將軟中斷描述符表中對應描述符的handler函數指針指向對應的函數即可,以便軟中斷到來時進行回調。

那麼,問題來了,什麼時候進行軟中斷函數回調呢?

2.2.2 軟中斷執行之一:中斷處理后

先看第一種情況,用圖片來回答問題:

  • Linux中斷子系統(二)-通用框架處理文章中講述了整个中斷處理流程,在接收到中斷信號后,處理器進行異常模式切換,並跳轉到異常向量表處進行執行,關鍵的流程為:el0_irq->irq_handler->handle_arch_irq(gic->handle_irq)->handle_domain_irq->__handle_domain_irq
  • __handle_domain_irq函數中,irq_enterirq_exit分別用於來標識進入和離開硬件中斷上下文處理,這個從preempt_count_add/preempt_count_sub來操作HARDIRQ_OFFSET可以看出來,這也對應到了上文中的Context描述圖;
  • 在離開硬件中斷上下文後,如果!in_interrupt() && local_softirq_pending為真,則進行軟中斷處理。這個條件有兩個含義:1)!in_interrupt()表明不能處在中斷上下文中,這個範圍包括in_nmiin_irqin_softirq(Bottom-half disable)in_serving_softirq,凡是處於這幾種狀態下,軟中斷都不會被執行;2)local_softirq_pending不為0,表明有軟中斷處理請求;

軟中斷執行的入口就是invoke_softirq,繼續分析一波:

  • invoke_softirq函數中,根據中斷處理是否線程化進行分類處理,如果中斷已經進行了強制線程化處理(中斷強制線程化,需要在啟動的時候傳入參數threadirqs),那麼直接通過wakeup_softirqd喚醒內核線程來執行,否則的話則調用__do_softirq函數來處理;
  • Linux內核會為每個CPU都創建一個內核線程ksoftirqd,通過smpboot_register_percpu_thread函數來完成,其中當內核線程運行時,在滿足條件的情況下會執行run_ksoftirqd函數,如果此時有軟中斷處理請求,調用__do_softirq來進行處理;

上圖中的邏輯可以看出,最終的核心處理都放置在__do_softirq函數中完成:

  • local_softirq_pending函數用於讀取__softirq_pending字段,可以類比於設備驅動中的狀態寄存器,用於判斷是否有軟中斷處理請求;
  • 軟中斷處理時會關閉Bottom-half,處理完后再打開;
  • 軟中斷處理時,會打開本地中斷,處理完后關閉本地中斷,這個地方對應到上文中提到的Top-halfBottom-half機制,在Bottom-half處理的時候,是會將中斷打開的,因此也就能繼續響應其他中斷,這個也就意味着其他中斷也能來打斷當前的Bottom-half處理;
  • while(softirq_bit = ffs(pending)),循環讀取狀態位,直到處理完每一個軟中斷請求;
  • 跳出while循環之後,再一次判斷是否又有新的軟中斷請求到來(由於它可能被中斷打斷,也就意味着可能有新的請求到來),有新的請求到來,則有三個條件判斷,滿足的話跳轉到restart處執行,否則調用wakeup_sotfirqd來喚醒內核線程來處理:
    1. time_before(jiffies, MAX_SOFTIRQ_TIME),軟中斷處理時間小於兩毫秒;
    2. !need_resched,當前沒有進程調度的請求;
    3. max_restart = MAX_SOFTIRQ_RESTART,跳轉到restart循環的次數不大於10次;
      這三個條件的判斷,是基於延遲和公平的考慮,既要保證軟中斷儘快處理,又不能讓軟中斷處理一直佔據系統,正所謂trade-off的藝術;

__do_softirq既然可以在中斷處理過程中調用,也可以在ksoftirqd中調用,那麼softirq的執行可能有兩種context,插張圖吧:

讓我們來思考最後一個問題:硬件中斷觸發的時候是通過硬件設備的電信號,那麼軟中斷的觸發是通過什麼呢?答案是通過raise_softirq接口:

  • 可以在中斷處理過程中調用raise_softirq來進行軟中斷處理請求,處理的實際也就是上文中提到過的irq_exit退出硬件中斷上下文之後再處理;
  • raise_softirq_irqoff函數中,最終會調用到or_softirq_pending,該函數會去讀取本地CPU的irq_stat__softirq_pending字段,然後將對應的軟中斷號給置位,表明有該軟中斷的處理請求;
  • raise_softirq_irqoff函數中,會判斷當前的請求的上下文環境,如果不在中斷上下文中,就可以通過喚醒內核線程來處理,如果在中斷上下文中處理,那就不執行;
  • 多說一句,在軟中斷整個處理流程中,會經常看到in_interrupt()的條件判斷,這個可以確保軟中斷在CPU上的串行執行,避免嵌套;

2.2.3 軟中斷執行之二:Bottom-half Enable后

第二種軟中斷執行的時間點,在Bottom-half使能的時候,通常用於併發處理,進程空間上下文中進行調用:

  • 在討論併發專題的時候,我們談到過Bottom-half與進程之間能產生資源爭奪的情況,如果在軟中斷和進程之間有臨界資源(軟中斷上下文優先級高於進程上下文),那麼可以在進程上下文中調用local_bh_disable/local_bh_enable來對臨界資源保護;
  • 圖中左側的函數,都是用於打開Bottom-half的接口,可以看出是spin_lock_bh/read_lock_bh/write_lock_bh等併發處理接口的變種形式調用;
  • __local_bh_enable_ip函數中,首先判斷調用該本接口時中斷是否是關閉的,如果已經關閉了再操作BH接口就會告警;
  • preempt_count_sub需要與preempt_count_add配套使用,用於操作thread_info->preempt_count字段,加與減的值是一致的,而在__local_bh_enable_ip接口中,將cnt值的減操作分成了兩步:preempt_count_sub(cnt-1)preempt_count_dec,這麼做的原因是執行完preempt_count_sub(cnt-1)后,thread_info->preempt_count字段的值保留了1,把搶佔給關閉了,當do_softirq執行完畢后,再調用preempt_count_dec再減去剩下的1,進而打開搶佔;
  • 為什麼在使能Bottom-half時要進行軟中斷處理呢?在併發處理時,可能已經把Bottom-half進行關閉了,如果此時中斷來了后,軟中斷不會被處理,在進程上下文中打開Bottom-half時,這時候就會檢查是否有軟中斷處理請求了;

3. tasklet

從上文中分析可以看出,tasklet是軟中斷的一種類型,那麼兩者有啥區別呢?先說結論吧:

  • 軟中斷類型內核中都是靜態分配,不支持動態分配,而tasklet支持動態和靜態分配,也就是驅動程序中能比較方便的進行擴展;
  • 軟中斷可以在多個CPU上并行運行,因此需要考慮可重入問題,而tasklet會綁定在某個CPU上運行,運行完后再解綁,不要求重入問題,當然它的性能也就會下降一些;

3.1 數據結構

  • DEFINE_PER_CPU(struct tasklet_head, tasklet_vec)為每個CPU都分配了tasklet_head結構,該結構用來維護struct tasklet_struct鏈表,需要放到該CPU上運行的tasklet將會添加到該結構的鏈表中,內核中為每個CPU維護了兩個鏈表tasklet_vectasklet_vec_hi,對應兩個不同的優先級,本文以tasklet_vec為例;
  • struct tasklet_structtasklet的抽象,幾個關鍵字段如圖所示,通過next來鏈接成鏈表,通過state字段來標識不同的狀態以確保能在CPU上串行執行,func函數指針在調用task_init()接口時進行初始化,並在最終觸發軟中斷時執行;

3.2 流程分析

  • tasklet本質上是一種軟中斷,所以它的調用流程與上文中討論的軟中斷流程是一致的;
  • 調度tasklet運行的接口是tasklet_schedule,如果tasklet沒有被調度則進行調度處理,將該tasklet添加到CPU對應的鏈表中,然後調用raise_softirq_irqoff來觸發軟中斷執行;
  • 軟中斷執行的處理函數是tasklet_action,這個在softirq_init函數中通過open_softirq函數進行註冊的;
  • tasklet_action函數,首先將該CPU上tasklet_vec中的鏈表挪到臨時鏈表list中,然後再對這個list進行遍歷處理,如果滿足執行條件則調用t->func()執行,並continue跳轉遍歷下一個節點。如果不滿足執行條件,則繼續將該tasklet添加回原來的tasklet_vec中,並再次觸發軟中斷;

3.3 接口

簡單貼一下接口吧:

/* 靜態分配tasklet */
DECLARE_TASKLET(name, func, data)

/* 動態分配tasklet */
void tasklet_init(struct tasklet_struct *t, void (*func)(unsigned long), unsigned long data);

/* 禁止tasklet被執行,本質上是增加tasklet_struct->count值,以便在調度時不滿足執行條件 */
void tasklet_disable(struct tasklet_struct *t);

/* 使能tasklet,與tasklet_diable對應 */
void tasklet_enable(struct tasklet_struct *t);

/* 調度tasklet,通常在設備驅動的中斷函數里調用 */
void tasklet_schedule(struct tasklet_struct *t);

/* 殺死tasklet,確保不被調度和執行, 主要是設置state狀態位 */
void tasklet_kill(struct tasklet_struct *t);

收工!

歡迎關注個人公眾號,不定期分享Linux內核機制文章。

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

【其他文章推薦】

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

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

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

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

※教你寫出一流的銷售文案?

Java中容易遺漏的小知識點( 一 )(為了和小白一樣馬上要考試的兄弟準備的,希望小白和大家高過不掛)

筆者csdn博客同文地址:https://blog.csdn.net/weixin_45791445/article/details/106597515

我是小康小白,一個平平無奇的Java小白。熱愛有趣的文字,生活和遠方。
個人博客:https://blog.csdn.net/weixin_45791445

小白最近快考試了,複習的順便總結一下一些小白認為容易忘記的知識點,希望能幫助到大家。

小白的總結系列二,三已上線Java中容易遺漏的常用的知識點( 二 )(為了和小白一樣馬上要考試的兄弟準備的,希望小白和大家高過不掛)
Java中容易遺漏的常用的知識點( 三 )(為了和小白一樣馬上要考試的兄弟準備的,希望小白和大家高過不掛)
  1. Java代碼運行機制

     1. 編寫源代碼
     	得到的是以“.java”為擴展名的源文件,源文件名應與該文件中被修飾為public的類名相同。
     2. 編譯(使用cmd命令編譯時使用的命令是javac 文件名.java。使用的javac編輯器)
     	編譯后的文件叫做類文件。得到的是以“.class”為擴展名的字節碼文件。
     	這裏出現的錯誤叫編譯時錯誤。
     	
     然後使用java命令運行,命令格式為:java 項目名(注意這裏沒有後綴))	
     3.類裝載ClassLoader
     4.字節碼(byte-code)校驗
     5. 解釋
     6. 運行
     這裏出現的錯誤叫運行時錯誤。
    
  2. 在一個簡單的Java程序中有一個獲以上的類組合而成。其次在一個可以獨立運行的Java程序中有且只有一個main()方法,它是程序運行的開端。程序的主體被包含在類中,這個起始的地方被稱為main方法。main方法之前必須加上public,static,void。static表示

  3. switch中的控製表達式必須為char,int,short或byte類型的。case後面的常量表達式必須和控製表達式的類型相同。(書上)

書上這一節後面的習題中有個選項說支持long類型是錯誤的。

switch表達式後面的數據類型只能是byte,short,char,int四種整形類型,枚舉類型和java.lang.String類型(從java 7才允許),不能是boolean類型。至於四種基本類型的包裝類是由於有自動拆箱的操作所以支持(實際)

  1. instanceof是對象運算符,用來判定一個對象是否屬於莫個指定的類(或其子類)的實例。

  2. 邏輯運算符分為標準邏輯運算符(!& ^ |)和條件邏輯運算符(&& ||)

  3. byte:1字節,short:2字節,int:4字節,long:8字節,float:4字節,double:8字節,char:2字節,boolean:書上此處為空。

switch的格式

do-while的格式(最後要加一個”;”)

foreach

  1. 運算符優先級
  2. 在判斷語句中的i++和–j是一個完整的獨立語句,先進行自加或者自減后再進行比對。
    (下面是debug測試)
  3. outer標籤

outer標籤是什麼,上面的文章講的很詳細。
小白在這裏補充一下break outer;和continue outer;的區別

break outer;是直接完全的跳出到outer標籤標記的循環外面。
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20200608102636433.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTc5MTQ0NQ==,size_16,color_FFFFFF,t_70#pic_center =500×500)
continue outer;的作用並非完全跳出外層循環,而是跳出outer標籤標記循環的本次循環,直接進行此循環的下一次循環;

![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20200608102735262.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTc5MTQ0NQ==,size_16,color_FFFFFF,t_70#pic_center =500×500)
12. 構造方法

  1. 類是對象模板,只有實例化之後才可以使用。new運算符用於創建一個類的實例並返回對象的引用。
    默認構造方法對成員變量的初始化原則如下:
    對於整型成員變量,默認初值是0;對與浮點型,默認初值是0.0;對於boolean類型,默認初值是false;對於引用型,默認值是null。

  2. this關鍵字
    this可以出現在類的構造方法和非static修飾的成員方法(即實例方法)中,this代表實例對象自身,可以通過this來訪問實例對象的成員變量或調用成員方法。
    類方法中不可以使用this
    由於類方法可以通過類名字直接調用,這時可能還沒有任何對象產生,因此指代對象實例本身的this關鍵字不可以出現在類方法中。

  3. 	1)public訪問權限最具有開放性,可以用來修飾類、類與接口的成員(包括成員變量、成員方法)
    。由public類修飾的類或類成員可被任何類訪問。
    	2)protected可以用來修飾類的成員變量或方法。具有protected訪問特性的類成員可以被本類、
    本包中的其他類訪問,也可以被其他包中的子類繼承,它的可訪問性低於public,高於默認。
    	3)如果在定義類、接口、成員變量、成員方法時沒有指定訪問權限控制符,他們的權限就為默認權
    限。具有默認權限的類、接口、成員變量、成員方法,只能被本類和同一個包中的其他類、接口及成員方
    法引用,因此默認權限也被稱為包權限。
    	4)私有訪問控制符private用來聲明類的私有成員,它提供了最高的保護級別。用private修飾的
    成員變量或方法只能被該類自身所訪問和修改,而不能被任何其他類(包括該類的子類)來獲取和引用。
    

Java文件名應與修飾為public的類名相同。且Java文件中只能有一個public修飾的類

特殊情況:
只有被修飾為public訪問權限的成員變量和方法才可以被不同包的其他類使用,修飾為protected的成員變量和方法可以被不同包的子類繼承,訪問。不同包的其他類禁止訪問修飾為private和默認權限的成員變量和方法。

  1. super關鍵字
    子類在繼承父類時,可能會出現變量隱藏、方法覆蓋(overriding)等現象。變量隱藏指子類的成員變量與父類成員同名,此時,父類的成員變量被隱藏。方法覆蓋指子類的方法與父類的方法名相同,方法的返回值類型、入口參數的數目、類型、順序均相同,只是方法實現的功能不同,此時父類的方法被覆蓋。如果子類需要調用或訪問父類被隱藏的變量或被覆蓋的方法,可以使用super關鍵字實現。
    當用子類的構造方法創建一個子類對象時,子類的構造方法總會顯式或隱式地先調用父類的某個構造方法。如果子類的構造方法沒有明顯地指明調用父類的哪個構造方法,Java會默認調用父類的無參構造方法;子類也可以通過super關鍵字顯式調用父類指定的構造方法,具體調用哪個構造方法需要根據super()的參數類型決定。

  2. Java中的子類對象可以向上轉換為父類對象(也稱上轉型對象),允許將子類的實例賦值給父類的引用,也允許一個父類的引用指向子類對象。
    但是反過來,一個父類對象的類型未必可以向下轉換成子類對象,因為子類具有的信息,父類未必包含,這種轉換是不安全的。只有當父類引用實際上指向一個子類對象時,才可以進行這種轉換。

  3. 實例變量依附於對象,在使用new關鍵字創建對象時,Java運行系統為每個對象分配一個內存空間,不同的實例變量佔用不同的內存區域。類變量依附於類(而非對象),對於類變量來說,Java運行系統為類的類變量分配公共的存儲空間,該類的每個實例對象共享同一類變量的存儲空間。因此,每個對象對類變量的修改都會影響其他實例對象。
    (1)類變量可以通過類名直接訪問,而不需要創建對象。
    (2)任何一個對象對類變量的修改,都是在同一內存單元上完成的。因此,每個對象對類變量的修改都會影響其他實例對象。

    聲明為static的方法稱為類方法(或稱靜態方法),與此相對,沒有static修飾的成員方法則為實例方法。類方法的本質是該方法屬於整個類,而不是屬於某個實例,可以不創建實例,直接通過類名調用。 類方法的使用具有以下特點:
    (1)類方法可以通過類直接調用,而不需要創建實例對象。例如:Java Application的入口main()方法就被聲明為static類方法,可以不需要創建任何實例對象對調用。
    (2)類方法屬於整個類,被調用時可能還沒有創建任何對象實例,因此類方法內只可以訪問類變量,而不能直接訪問實例變量和實例方法。
    (3)類方法中不能使用this關鍵字,因為靜態方法不屬於任何一個實例。

  4. 抽象類和抽象方法(為什麼會有抽象類?)
    語法:

    abstract class <類名> [extends<父類>][implements<接口名>]{ <類主體> }
    

如果一個類A需要繼承抽象類,則該類必須實現抽象類中定義的所有抽象方法。否則,該類也必須修飾為抽象類。也就是說,抽象類的子類如果僅實現父類的部分抽象方法,子類也必須聲明為抽象類。

為什麼會有抽象類和抽象方法?
有時候,我們沒有足夠的信息去描述一個具體的對象,這樣就不能用正常的類來描述它,那麼這時候就需要抽象類了。抽象方法沒有方法體,為什麼呢?小白的理解是我們只知道這個對象有這樣的一種方法(或者理解為” 行為 “),但不知到它的這種方法能夠干什麼,就沒有寫具體的方法主體。因此,抽象類不能實例化(創建的人都不知道它具體是什麼,怎麼實例成一個具體的對象)
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20200607181353317.png#pic_center =240×240)

  1. 接口
    接口(interface)是Java所提供的另一種重要結構。接口是一種特殊的類,但接口與類存在着本質的區別。類有成員變量和成員方法,而接口卻只有常量和抽象方法,也就是說接口的成員變量必須初始化,同時接口中的所有方法必須聲明為abstract方法

語法:

[接口修飾符] interface〈接口名〉[extends〈父類接口列表〉] { 接口體 }

用implements子句表示類實現某個接口。一個類可以同時實現多個接口,接口之間用逗號“,”分隔。 在類體中可以使用接口中定義的常量,由於接口中的方法為抽象方法,所以必須在類體中加入要實現接口方法的代碼,如果一個接口是從別的一個或多個父接口中繼承而來,則在類體中必須加入實現該接口及其父接口中所有方法的代碼。 在實現一個接口時,類中對方法的定義要和接口中的相應方法的定義相匹配,其方法名、方法的返回值類型、方法的訪問權限和參數的數目與類型信息要一致

接口繼承中出現的方法重名和常量重名
(1)方法重名 如兩個方法完全一樣,只保留一個。 如果兩個方法有不同的參數(類型或個數),那麼子接口中包括兩個方法,方法被重載。 若兩個方法僅在返回值上不同,出現錯誤。
(2)常量重名 兩個重名常量全部保留,並使用原來的接口名作為前綴。

  1. 內部類:
    Java支持在一個類中聲明另一個類,這樣的類稱為內部類(InnerClass),而包含內部類的類稱為內部類的外部類(OuterClass)。內部類一般用來實現一些沒有通用意義的功能邏輯。

eaducoder裏面老用。小白表示心累ಥ_ಥಥ_ಥ。

一個類把內部類看成是自己的成員,外部類的成員變量在內部類中仍然有效,內部類可以直接使用外部類中的成員變量和方法,即使他們是private的,這也是內部類的一個好處。

  1. 匿名類(小白表示從未用過,但寫一下吧。萬一考呢。)
    使用類創建對象時,Java允許把類體與對象的創建組合在一起。也就是說,類創建對象時,除了構造方法還有類體,此類體被稱為匿名類。
    實戰:
一個匿名類:
Student3 liu = new Student3() { 
	void speak() { 
			System.out.println("這是匿名類中的方法"); 
		} 
};// 匿名類體結束

重點來了

  1. 泛型
    泛型的本質是參數化類型,也就是說所操作的數據類型被指定為一個參數。這種參數類型可以用在類、接口和方法的創建中,分別稱為泛型類、泛型接口、泛型方法。

1)泛型類聲明:
創建一個簡單的泛型是非常容易的。首先,在一對尖括號(< >)中聲明類型變量,以逗號間隔變量名列表。在類的實例變量和方法中,可以在任何類型的地方使用那些類型變量。
格式:

class 泛型類名<泛型列表>{ 
	類體 
}

泛型類聲明時並不指明泛型列表是什麼類型的數據,可以是任何對象或接口,但不能是基本類型數據。泛型列表處的泛型可以作為類的成員變量的類型、方法的類型以及局部變量的類型。

2)使用泛型類聲明對象:
使用泛型類聲明對象時,必須指定類中使用泛型的具體具體類名,如: Chorus<Student,Button> model model = new Chorus<Student,Button>();

3)泛型接口:
格式:

Interface 泛型接口名<泛型列表>{
	 接口體 
}

小白沒想到書上對於泛型講的這麼多。(唉,不禁為我的菜雞感覺億點悲傷。)

小白實戰中常用的是:
在創建arraylist或者list集合時加泛型

ArrayList<String> listTest = new ArrayList<String>();

這樣限定了創建集合的類型。對於此小白的理解時泛型是在創建list或者arrayList集合時指定集合中的元素是同一種類型。例如你在創建時指定了創建的list集合中只能有String類型的變量,那麼你向其中添加數據時,如果不是String類型的數據,程序在編譯時就會報錯。如果不是用泛型這種錯誤只有在程序運行時才會報錯。而且,泛型讓我們在get獲得集合中的數據時,無需因為類型不同需要強轉而煩惱。

當你向加了泛型的語句中加入不同數據類型的數據時是會報錯的。但如果不加,這種錯誤就只能在程序運行是才報錯。

這次先寫到這裏小白明天接着寫。

Java中容易遺漏的常用的知識點( 二 )(為了和小白一樣馬上要考試的兄弟準備的,希望小白和大家高過不掛)
Java中容易遺漏的常用的知識點( 三 )(為了和小白一樣馬上要考試的兄弟準備的,希望小白和大家高過不掛)

![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20200607181353317.png#pic_center =240×240)

小白的總結系列二已上線Java中容易遺漏的常用的知識點( 二 )(為了和小白一樣馬上要考試的兄弟準備的,希望小白和大家高過不掛)

兄弟們,小白編寫不易。希望各位兄弟們,點贊評論收藏加關注。小白在此謝謝各位老爺們,也祝福和我一樣面臨考試的兄弟們高分通過。

對於白嫖的兄弟們,

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

【其他文章推薦】

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

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※想知道最厲害的網頁設計公司"嚨底家"!

※別再煩惱如何寫文案,掌握八大原則!

※產品缺大量曝光嗎?你需要的是一流包裝設計!

全球暖化影響北極圈 海冰覆蓋值降至40年來次低

摘錄自2020年9月21日中央社報導

北極圈氣候暖化導致覆蓋北極海的冰層大幅縮小,科學家21日表示,今年覆蓋值來到40年來第2低,為氣候變遷迅速改變北極地帶的另一個跡象。

路透社報導,美國國家冰雪資料中心(National Snow and Ice Data Center)研究人員說,根據衛星紀錄,今年度海冰面積最小值落在9月15日,只有374萬平方公里,是40年前有紀錄以來,海冰面積第2次低於400萬平方公里。

北極圈海冰覆蓋值最低紀錄為341萬平方公里,是在2012年一場季末氣旋風暴導致剩下的海冰解體後發生。受到西伯利亞熱浪產生的熱空氣影響,今年海冰在8月31日到9月5日這6天期間縮減速度之快,超越有紀錄以來任何一年。

氣候變遷
國際新聞
北極
全球暖化
冰層消融
海冰

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

【其他文章推薦】

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

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

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

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

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

※教你寫出一流的銷售文案?

唐獎法治獎得主 為環境與大眾扮演守門人吹哨者

摘錄自2020年9月21日中央社報導

唐獎教育基金會21日舉行「唐獎第四屆大師論壇-法治場」,由唐獎法治獎召集人葉俊榮主持,今年因疫情影響,邀請法治獎得主透過視訊分享。

2020年唐獎法治獎得主由位於孟加拉的孟加拉環境法律人協會(BELA)、位於哥倫比亞的實現正義:法律、正義暨社會中心(Dejusticia: The Center forLaw, Justice and Society)、位於黎巴嫩的法律實踐進程組織(The Legal Agenda)等3個非政府組織共同獲得。

 孟加拉環境法律人協會執行長Syeda RizwanaHasan表示,孟加拉面臨空氣品質惡化、森林遭砍伐、河川污染嚴重等環境問題;為了讓民眾瞭解環境正義,協會透過社會宣導,提高民眾對環境保護重要性的認識,並扮演守門人角色,如監督政府要求環境影響評估、食品安全等。

Rizwana提到,非政府組織有時卻會被政府扣上反對發展等莫須有罪名,或被限制集會結社或言論自由,加上經費欠缺、未做好治理工作等內部挑戰,很難吸引或留住好人才;非政府組織扮演公正客觀角色,動員民眾力量來達到永續發展目標,政府應該移除會影響非政府組織運作的障礙,讓組織發揮真正的力量。

法律實踐進程組織創始成員Samer Ghamroun分享,黎巴嫩欠缺真正獨立的司法單位,司法體系受政治或宗教團體干預,因此組織扮演吹哨者角色進行監督,避免權貴人士關說等不當行為積非成是,並將蒐集的資訊與民眾分享,讓大家瞭解司法部門的運作。

為推動司法改革,Samer表示,組織進行廣泛研究,透過雜誌、網站、社群媒體來帶動社會討論,同時也提出法律草案或建議,為弱勢群體爭取權益;但在推動過程中受到司法界很多阻力,加上社會環境影響,法律系學生寧願投身私人企業,卻不願進入非政府組織幫弱勢團體發聲,這都是組織面臨的挑戰。

「實現正義:法律、正義暨社會中心」創始人之一的Rodrigo Uprimny Yepes表示,組織目標是成為學術界和社會行動主義的橋梁,透過融合學術研究,進而擬定和參與公共政策,爭取法治自由的概念,藉此反對歧視和不平等,以實現社會正義。

「實現正義:法律、正義暨社會中心」執行長VivianNewman Pont舉例,哥倫比亞2016年簽署和平進程協定,結束政府與左翼革命武裝力量的內部衝突,組織透過研究發表論述和建議,幫助這段曲折漫長的和平轉型之路。

Rodrigo提到,他們所處社會歧視和貧窮問題嚴重,必須爭取法治自由的概念,反對歧視和不平等,但致力於推動社會正義的非政府組織常被污名化,造成許多理念無法自由傳播,弱勢團體無法獲妥善保障,因此組織也致力於促進民主程序,希望立場不同的團體能共同協商,縮小經濟上的不平等,避免社會分裂。

根據唐獎網站,三個團體的主要貢獻如下:

孟加拉環境法律人協會 (Bangladesh Environmental Lawyers Association) 由 Mohiuddin Farooque 博士於1992年創立,致力於提倡環境正義與法治。該協會是孟加拉最有影響力的環境團體,目前在國內六個城市有設點,並積極參與全球環境正義的維護。面對其國內嚴重的環境污染與貪腐不法,此協會透過公益訴訟、立法倡議、研究出版與公眾意識培養等方法,提倡環境正義與法治。自1994年孟加拉國內第一個成功的公益訴訟,Dr. Mohiuddin Farooque v. Bangladesh & Others (1994) ,該協會已成功提出超過300個環境公益訴訟與多項立法提議。協會所處理過的議題涵蓋了河流污染、工業污染、非法開發、勞工權益、非法採礦、塑膠使用、濕地保護與船舶拆解等面向。

藉由對憲法的創新詮釋,孟加拉環境法律人協會成功突破孟加拉法院過去的解釋,創立公益團體進行訴訟的路徑。其創舉建立了該國後續社會運動者的訴訟基礎,也促成國內法院將環境權納入憲法保障生存權的範圍內。更重要的是,該協會持續為環境與弱勢發聲,挑戰政府的不法。孟加拉環境法律人協會的研究出版與訓練課程,也使許多社區、團體與個人更有環境意識與維護環境的能力。該協會在環境公益訴訟的持續著力,使其得以持續監督環境法律的執行。不僅改善自身國家的法律體系,也對於全球的法治與環境正義有重大貢獻。

實現正義:法律、正義暨社會中心(Dejusticia: The Center for Law, Justice and Society)創立於 2005 年,是設在哥倫比亞的學術研究及社會議題倡議組織,經由持續發起行動、出版文宣及提起訴訟的形式,作出莫大貢獻。身處在一個充滿血腥動盪的過去且社會問題叢生的國度,作為非政府組織,實現正義: 法律、正義暨社會中心堅信學術工作能夠貢獻於社會正義並帶動改革。

實現正義:法律、正義暨社會中心採取獨特的「兩棲」作業模式,將紮實的學術研究與充滿動能的社會運動有效地相結合來處理人權議題。事實上,該組織成員多為人權、憲法及轉型正義的頂尖學者。這些學者們亦有相當多的論著產出,並且都在國內外的知名大學內任教。

在擁有如此學術研究加持的背景下,中心亦著重於透過法律訴訟來強化法治,特別是涉及諸多敏感議題,包含反對(種族及性別)歧視、原住民權利、難民權利、轉型正義及環境惡化的指標案件中,向哥倫比亞國內法院及拉丁美洲國際法律平台,提起訴訟並獲得勝訴。以此,國家體制更加能夠確保眾人皆能享有人權的保障,同時亦能維護環境正義。實現正義: 法律、正義暨社會中心透過教育、公共論辯及國際合作的方式,在賦予弱勢邊緣族群權利並疾呼此類族群的需求能夠被聽見的倡議上,亦是引領在前。因此,促使在地社群和公民參與間有著更加良善的互動循環,進而在哥倫比亞國內以及諸多全球南方國家推動改革。

法律實踐進程組織(The Legal Agenda)自 2009 年創立,即致力透過結合多重專業領域的方式,成功強化了黎巴嫩國內的司法獨立及法治。其中包括了針對司法部門的研究及監督、協助成立法官社團以強化法官的獨立於政治影響力以外、草擬支持司法獨立之法案及尋求相關之聲援,並倡議關於支持司法獨立跟各式社會議題的論辯。

以此,法律實踐進程組織針對弱勢族群,樹立多項關鍵的權利保障及賦予權利的關鍵判決,保護包括針對移工、難民、女同性戀者、男同性戀者、雙性戀者與跨性別者(LGBT)、被強迫失蹤受害者之家屬等群體。為普及法律知識,確保訴訟中當事人的武器平等,法律實踐進程組織也發展辯護範例模式,提供前述弱勢族群法律辯護之指引。除了在黎巴嫩國內為相關倡議之先驅外,法律實踐進程組織也不斷拓展其服務至阿拉伯世界其他國家,並已在突尼西亞成立分支辦公室。

國際新聞
孟加拉
哥倫比亞
黎巴嫩
環境正義
唐獎
永續發展

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

【其他文章推薦】

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

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

※推薦評價好的iphone維修中心