Java 從入門到進階之路(二十五)

在之前的文章我們介紹了一下 Java 中的  集合框架中的Collection 的子接口 List的 增刪改查和與數組間相互轉換的方法,本章我們來看一下 Java 集合框架中的Collection 的子接口 List 的另外一些方法。

我們在使用集合的時候難免會對其中的元素進行排序,因為 Set 集合本身是無序的,所以本章將着重講解 List 集合,如下:

 1 import java.util.ArrayList;
 2 import java.util.Collections;
 3 import java.util.List;
 4 import java.util.Random;
 5 
 6 /**
 7  * 排序集合元素
 8  * 排序集合使用的是集合的工具類 Collections 的靜態方法 sort
 9  * 排序僅能對 List 集合進行,因為 Set 部分實現類是無序的
10  * */
11 public class Main {
12     public static void main(String[] args) {
13         List<Integer> list = new ArrayList<Integer>();
14         Random random = new Random();
15         for(int i=0;i<10;i++){
16             list.add(random.nextInt(100));
17         }
18         System.out.println(list); // [49, 24, 29, 59, 56, 1, 1, 5, 49, 60]
19 
20         Collections.sort(list);
21         System.out.println(list); // [1, 1, 5, 24, 29, 49, 49, 56, 59, 60]
22     }
23 }

在上面的代碼中,我們隨機生成了一些正數並添加到 List 集合中,我們通過 sort 方法,系統變自動按照自然數的排列方法為我們做好了排序,很是方便,那如果 List 中使我們自己定義的內容,比如說一個類,那該如何排序呢,如下:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 排序集合元素
 * 排序集合使用的是集合的工具類 Collections 的靜態方法 sort
 * 排序僅能對 List 集合進行,因為 Set 部分實現類是無序的
 */
public class Main {
    public static void main(String[] args) {
        List<Point> list = new ArrayList<Point>();
        list.add(new Point(1, 2));
        list.add(new Point(2, 3));
        list.add(new Point(4, 2));
        list.add(new Point(2, 5));
        list.add(new Point(9, 3));
        list.add(new Point(7, 1));
        System.out.println(list); // [(1, 2), (2, 3), (4, 2), (2, 5), (9, 3), (7, 1)]
        // Collections.sort(list); // 編譯錯誤,不知道 Point 排序規則
        /**
         * sort 方法要求集合必須實現 Comparable 接口
         * 該接口用於規定實現類事可以比較的
         * 其中一個 compareTo 方法時用來定義比較大小的規則
         * */
        Collections.sort(list);
        System.out.println(list); // [(1, 2), (2, 3), (4, 2), (2, 5), (7, 1), (9, 3)]

    }
}

class Point implements Comparable<Point> { // 定義為泛型 T 類型
    private int x;
    private int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    @Override
    public String toString() {
        return "(" + x + ", " + y + ")";
    }

    /**
     * 當實現了 Comparable 接口后,需要重寫下面的方法
     * 該方法的作用是定義當前對象與給定參數對象比較大小的規則
     * 返回值為一個 int 值,該值表示大小關係
     * 它不關注具體的取值是多少,而關注的是取值範圍
     * 當返回值 >0 時:當前對象不參數對象大
     * 當返回值 <0 時:當前對象比參數對象小
     * 當返回值 =0 時:兩個對象相等
     */
    @Override
    public int compareTo(Point o) {
        /**
         * 比較規則,點到原點的距離長的打
         * */
        int len = this.x * this.x + this.y * this.y;
        int olen = o.x * o.x + o.y * o.y;
        return len - olen;
    }
}

在上面的代碼中,我們跟之前一樣定義了一個 Point 類,然後實例化后存入 list 集合中,如果我們相對 Point 進行排序,如果直接調用 sort 方法會報錯,這是由於編譯器不知道我們定義的 Point 類的排序規則,所以我們需要通過接口 Comparable 接口來自定義排序規則,如下圖:

 

我們可以通過坐標系中點到原點的距離來判斷 Point 的大小,即 x*x+y*y 的大小,然後通過重寫 compareTo 方法來實現 sort 。

實際上雖然能實現,但是並不理想,為了實現一個 sort 方法,要求我們的集合元素必須實現 Comparable 接口並且定義比較規則,這種我們想使用某個功能,而它要求我們修改程序的現象稱為“侵入性”。修改的代碼越多,侵入性越強,越不利於程序的擴展。

我們再來看一下下面的排序:

 1 import java.util.ArrayList;
 2 import java.util.Collections;
 3 import java.util.List;
 4 
 5 public class Main {
 6     public static void main(String[] args) {
 7         List<String> list1 = new ArrayList<String>();
 8         list1.add("Java");
 9         list1.add("c++");
10         list1.add("Python");
11         list1.add("PHP");
12         Collections.sort(list1);
13         System.out.println(list1); // [Java, PHP, Python, c++]
14 
15         List<String> list2 = new ArrayList<String>();
16         list2.add("孫悟空");
17         list2.add("豬八戒");
18         list2.add("唐僧");
19         list2.add("六小齡童");
20         Collections.sort(list2);
21         System.out.println(list2); // [六小齡童, 唐僧, 孫悟空, 豬八戒]
22 
23     }
24 }

在上面的排序中,當我們對字母或漢字進行排序時,其實是比的第一個字的 Unicode 碼,那如果我們不使用 Comparable 的接口該如何自定義我們想要的實現規則呢?比如根據字符串的長度來進行排序,其實 sort 有一個額外的重載方法來實現我們想要的結果,如下:

 1 import java.util.ArrayList;
 2 import java.util.Collections;
 3 import java.util.Comparator;
 4 import java.util.List;
 5 
 6 public class Main {
 7     public static void main(String[] args) {
 8         /**
 9          * 重載的 sort 方法要求傳入一個額外的比較器
10          * 該方法不再要求集合元素必須實現 Comparable 接口
11          * 並且不再使用集合元素資深的比較規則排序了
12          * 而是根據給定的這個額外的比較器的比較規則對集合元素進行排序
13          * 實際開發中也推薦使用這種方式進行集合元素排序
14          * 若集合元素是自定義的
15          * 創建比較器時推薦使用匿名內部類的形式
16          */
17         List<String> list1 = new ArrayList<String>();
18         list1.add("Java");
19         list1.add("c++");
20         list1.add("Python");
21         list1.add("PHP");
22         MyComparator myComparator1 = new MyComparator();
23         Collections.sort(list1, myComparator1); // 重載 sort
24         System.out.println(list1); // [c++, PHP, Java, Python]
25 
26         List<String> list2 = new ArrayList<String>();
27         list2.add("孫悟空");
28         list2.add("豬八戒");
29         list2.add("唐僧");
30         list2.add("六小齡童");
31         // 匿名內部類形式創建
32         Comparator<String> myComparator2 = new Comparator<String>() {
33             @Override
34             public int compare(String o1, String o2) {
35                 return o1.length() - o2.length();
36             }
37         };
38         Collections.sort(list2, myComparator2); // 重載 sort
39         System.out.println(list2); // [唐僧, 孫悟空, 豬八戒, 六小齡童]
40 
41     }
42 }
43 
44 /**
45  * 定義一個額外的比較器
46  * 該方法用來定義 o1 和 o2 的比較
47  * 若返回值 >0:o1>o2
48  * 若返回值 <0:o1<o2
49  * 若返回值 =0:兩個對象相等
50  */
51 class MyComparator implements Comparator<String> {
52     @Override
53     public int compare(String o1, String o2) {
54         /**
55          * 字符串中字符多的大
56          * */
57         return o1.length() - o2.length();
58     }
59 }

    

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

【其他文章推薦】

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

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

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

※幫你省時又省力,新北清潔一流服務好口碑

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

鋰電池再生利用,新創事業 FreeWire 推行動充電車

  特斯拉(Tesla)高調宣布鋰電池儲能系統,其中針對企業用戶的「Powerpack」,100 度電售價 25,000 美元,已將平均儲能成本拉低到相當驚人的每度電 250 美元,一般認為若平均儲能成本降到每度電 100 美元,將引爆能源儲存革命,特斯拉挾 GigaFactory 的威力,正全速逼近這個目標,不過,卻有一個小型新創事業,認為現在就可以做到。   這家新創事業 FreeWire 初期募資金額不過 42.5 萬美元,加上美國海軍資助 50 萬美元,如何能超越家大業大的特斯拉?其實原理也不難,就是採用二手電池。   FreeWire 、日產(Nissan)與 NEC 合資的汽車能源供應公司(Automotive Energy Supply Corporation,AESC)合作,AESC 是僅次於 Panasonic,全球第二大車用鋰電池供應商,市佔率達 21%,2014 年銷售最佳的電動車是 Nissan Leaf,其電池正是由 AESC 供應,Nissan 每個月都會測試電池,每六個月就汰換效能已經衰退的鋰電池,數量以千計,對 Nissan 來說庫存這些二線電池是個麻煩,但這些電池的效能或許已經不不敷電動車所需,拿來做為能源儲存用途卻還很有用。   於是,FreeWire 以新電池六分之一的價格取得這些二手電池,第一步,是取之於電動車用之於電動車,將這些二手電池組裝成總容量 48 度電的行動充電車,專供電動車在本來沒有設置充電座的停車場、機場、企業廠區等處充電,行動充電車可以推到停車場任何一個停車格,幫電動車充電,如此一來,停車場可以省下設置大量充電座的成本,卻能提供身為少數的電動車主充電服務,而這些二手電池在每天充放電循環 2 次的情況下,還可以有 5 年的壽命。  
 

    由於使用二手電池,FreeWire 裝置的每度電成本只有 100 美元,執行長阿卡迪‧索西諾夫(Arcady Sosinov)表示,電池產業界要到 2030 年才能達到的成本目標,他們用二手電池壓低成本,所以現在就已經做到。   阿卡迪‧索西諾夫的野心不只是為電動車行動充電,他認為二手電池的商機相當廣大,同樣的系統也可用來取代柴油發電機,為沒有電力供應之處供電,或是作為備援電力,而鋰電池供電比起柴油發電機有更大的優勢,那就是不會產生噪音與廢氣。如果要在戶外辦一場蚊子電影院,使用鋰電池系統顯然更好,而許多開發中國家的手機基地台因電網不穩定都有備用電源需求,以往這些取代柴油發電機的系統生意由奇異的獨拉松獨佔,如今以二手電池成本之低,也可與之競爭。   更進一步,二手電池系統也可進軍特斯拉正大張旗鼓進入的家庭與企業能源儲存領域,不過,二手電池的發展,也不是只會和特斯拉打對台,因為特斯拉發展電動車也一樣會面臨汰換大量二手電池,這些二手電池若都可再利用製成能源儲存裝置,對特斯拉也是一項利多。   FreeWire 利用二手電池的想法也給能源儲存業界一個啟發,過去鋰電池效能會衰退是產業界的一大問題,但換個方向思考,開啟電池的分級使用,反而可開創許多價格彈性商機。     本文全文授權轉載自《科技新報》─〈〉

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

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

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

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

刺激銷量?北京6月起收取電動車充電服務費

北京市發改委於5月7日發佈了《關於本市電動汽車充電服務收費有關問題的通知》,從2015年6月1日起,提供電動汽車充電服務的充電設施經營單位在收取電費的同時,可按充電電量額外收取充電服務費,每千瓦時收費上限標準為當日本市92號汽油每升最高零售價的15%。各經營單位可在不超過上限標準情況下,制定具體收費標準。   其充電服務費上限標準隨油價變動自行動態調整。如2015年4月29日本市92號汽油最高零售價為6.46元人民幣(下同)/升,則充電服務收費上限標準為6.46元的15%,即0.97元/度。油價上升,充電服務費相應上升油價下降,充電服務費相應下降。   北京市發改委副主任高朋指出,根據測算,此標準可以確保電動汽車動力成本低於燃油汽車。以本市銷售相對較好的北汽E150EV電動汽車為例(100公里平均耗電16度),當油價在6-10元/升區間變動時,充電服務費為每度電0.9元-1.5元。按國家發展改革委檔,對向電力公司直接報裝的充電服務設施,按大工業用電價格標準執行,按此測算,加上電價費用,電動汽車動力成本約為同款燃油汽車的50%-60%左右。   對此有觀點認為,發改委此舉會影響電動汽車銷量,降低消費者對電動車的購買慾。汽車產業分析師張志勇指出,目前,電動車推廣最大的障礙是充電問題,《通知》中規定了電動車充電服務費,可以鼓勵一些民營資本來加入電動車充電網路的建設,此舉將加快北京地區的充電網路建設。   張志勇還指出,即使充電設施經營單位額外收取充電服務費,這個成本也是遠遠低於燃油車的用車成本,這對消費者來看並不能產生多大影響。因此《通知》發布後不僅不會影響電動車的銷量,反而會增加消費者購買電動車的信心。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

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

※幫你省時又省力,新北清潔一流服務好口碑

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

特斯拉:將調整以符合中國充電標準

美國電動車大廠特斯拉(Tesla)表示,在中國發布全國電動車充電標準後,該公司將修改新生產的車輛,以便用戶可在符合新標準的充電設施,享受充電服務。    特斯拉在中文網站發布公告:「特斯拉將全面支持新國標,修改新生產車輛以符合新國標的規定… 隨著未來幾年中國充電基礎設施的飛速發展,特斯拉用戶將徹底消除對於充電的顧慮。」    特斯拉的充電規格和中國不相容,是消費者不敢購買電動車的一大阻力。不過,中國當局對此尚未提出明確的時間表,電動車充電的新標準何時出爐仍不得而知。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

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

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

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

深圳電動車熱:東部公交今年將投放565輛純電動車

5月13日,深圳市坪山新區召開新區公交業務座談會,東部公交公司計畫在2015年投放565輛純電動車輛,並將於近期採取公開招標的方式選定車輛更新解決方案。   東部公交公司在坪山新區內運營的公交線路有61條,運力1043台。坪山新區的500米公交網站覆蓋率為92%,公交線路基本覆蓋至坪山新區每個社區。   而目前,東部公交公司在坪山新區運營的新能源線路共16條,運力309輛,占東部公交新能源總運力的35%,其中純電動大巴150輛,混合動力大巴159輛。   2014年東部公交公司在坪山新區投放了134輛純電動大巴。根據坪山新區內運營的線路現狀,東部公交將繼續加大在坪山新區投放新能源車輛的力度,計畫2015年內在坪山新區投放70輛新能源車輛。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

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

※幫你省時又省力,新北清潔一流服務好口碑

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

氣候變遷衝擊 2050年前全球經濟損失恐達241兆元

摘錄自2019年11月20日中央通訊社綜合報導

最新分析報告顯示,隨著越來越多的旱澇災情和農作物歉收,危及經濟成長,威脅基礎建設,氣候變遷恐直接造成2050年前全球經濟損失7.9兆美元(約新台幣241兆元)。

英國經濟學人資訊社(EIU)今天(20日)公布氣候變遷韌性指數(Climate Change Resilience Index),發現以當前趨勢來看,氣溫暖化帶來的衝擊在2050年以前,將讓全球經濟成長下滑3%。這項指數用來衡量全球82大經濟體的準備程度。

氣候變遷引發的極端氣候事件頻傳,這項報告評估各國暴露在氣候變遷帶來的損失,結果發現非洲地區風險最高,區域國內生產毛額(GDP)恐因此萎縮4.7%。

世界最大經濟體美國被認為是受到衝擊程度最小的國家之一。但經濟學人資訊社提到,美國總統川普的政策代表在對抗氣候變遷戰爭中「短暫地倒退」。

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

【其他文章推薦】

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

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

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

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

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

人為噪音是全球污染源 研究:軟體動物也受害

摘錄自2019年11月20日中央通訊社報導

一份20日公布的研究報告指出,人為噪音應被視同「全球主要污染源」,參與研究的英國女皇大學(Queen’s University Belfast)科學家刊登在英國皇家學會(Royal Society)生物學通訊(Biology Letters)的文章指出:「我們發現噪音可影響許多種兩棲和節肢動物、鳥類、魚類、哺乳類、軟體動物和爬蟲類。」

這份研究顯示,人為噪音充斥人類生活環境,來源包括都市人口密集區的交通工具和工業設施、飛機和船艇,例如船艇的螺旋槳運轉聲可對鯨類的聲納傳播造成干擾,並因此導致迷失方向的鯨群大規模擱淺。

針對多項個別研究進行整合分析,科學家孔克(Hansjoerg Kunc)和施密特(Rouven Schmidt)得出結論:多數物種對噪音有反應,並非只有少數物種對噪音特別敏感。孔克警告,人為噪音整體而言仍嚴重干擾自然環境。研究人員也提到,人為噪音污染和動物對噪音污染的反應必須放在生態系統的整體脈絡中檢視,尤其是在研議保育措施時。

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

【其他文章推薦】

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

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

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

※幫你省時又省力,新北清潔一流服務好口碑

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

Linux系統如何使用Fuser命令

本文不再更新,可能存在內容過時的情況,實時更新請訪問原地址:Linux系統如何使用Fuser命令;

什麼是Fuser命令?

fuser命令是一個非常聰明的unix實用程序,用於查找正在使用某個文件、目錄或socket的進程。 它還提供有關擁有該進程的用戶和訪問類型的信息。。fuser工具显示了使用指定文件或文件系統的每個進程的進程ID(PID)。

安裝

如果你的精簡版運行fuser提示如下信息:

-bash: fuser: command not found

請執行如下命令安裝:

[winbert@winbert-server ~]$ sudo yum -y install psmisc

如何使用fuser命令?

man命令可用於查看任何命令的幫助手冊,但是學習新知識(尤其是linux命令)的最佳方法是通過閱讀真實的示例,並且不斷地在終端中鍵入命令。 在終端中運行以下命令,以獲取有關fuser實用程序的使用選項的信息。

[winbert@winbert-server ~]$ fuser
No process specification given
Usage: fuser [-fMuvw] [-a|-s] [-4|-6] [-c|-m|-n SPACE] [-k [-i] [-SIGNAL]] NAME...
       fuser -l
       fuser -V
Show which processes use the named files, sockets, or filesystems.

  -a,--all              display unused files too
  -i,--interactive      ask before killing (ignored without -k)
  -k,--kill             kill processes accessing the named file
  -l,--list-signals     list available signal names
  -m,--mount            show all processes using the named filesystems or block device
  -M,--ismountpoint     fulfill request only if NAME is a mount point
  -n,--namespace SPACE  search in this name space (file, udp, or tcp)
  -s,--silent           silent operation
  -SIGNAL               send this signal instead of SIGKILL
  -u,--user             display user IDs
  -v,--verbose          verbose output
  -w,--writeonly        kill only processes with write access
  -V,--version          display version information
  -4,--ipv4             search IPv4 sockets only
  -6,--ipv6             search IPv6 sockets only
  -                     reset options

  udp/tcp names: [local_port][,[rmt_host][,[rmt_port]]]

如何查看使用某個目錄的進程

fuser序可以與-v選項一起使用,該選項以詳細模式運行該工具。 verbose選項用於在計算機屏幕上生成詳細輸出,因此用戶可以實時查看實用程序正在執行的操作。

[winbert@winbert-server ~]$ fuser -v .
                     USER        PID ACCESS COMMAND
/home/winbert:       winbert    1435 ..c.. bash

上面的輸出显示,以詳細模式運行時,fuser會提供有關USERPIDACCESSCOMMAND的信息。 ACCESS下的c字符表示訪問類型,表示“當前目錄”。 訪問類型很多,例如e(正在運行的可執行文件),r(根目錄),f(打開文件。在默認显示模式下省略f),F(用於寫入的打開文件,在默認显示模式下省略F)和 m(mmap文件或共享庫)。

查看使用你tcp或udp套接字的進程?

有時您需要使用TCP和UDP套接字查找進程。 為了查找這些進程,需要使用-n選項。 -n選項用於選擇相應的名稱空間。

[root@huidukongjian-h4 docker]# fuser -v -n tcp 80
                     USER        PID ACCESS COMMAND
80/tcp:              root      27411 F.... docker-proxy

默認情況下,fuser將同時在IPv6和IPv4套接字中查找,但是可以使用-4-6選項更改默認選項。 -4選項代表IPv4-6選項代表IPv6。 請注意,fuser僅將PID輸出到stdout,其他所有內容都發送到stderr。

fuser -v -n tcp 80命令的結果显示,使用docker的進程的進程ID為27411,而用於啟動該進程的命令為docker-proxy。 進程ID(PID)可以以多種方式使用,其中之一是進程終止。 與PID一起使用時,kill命令根據該進程ID終止進程。 fuser還可用於終止訪問特定文件的進程。 在以下命令中,-k選項用於終止正在使用在端口123上運行的tcp偵聽器的進程。為確保用戶不會殺死錯誤的進程,使用-i選項詢問用戶是否 在終止進程之前進行確認。

fuser -k  123/tcp

使用帶有-i選項的fuser -k命令在終止進程之前要求用戶進行確認。 用戶可以用y回答“是”,或者用N回答不殺死進程。

fuser -i -k 123/tcp
123/tcp:             12216
Kill process 12216 ? (y/N)
Use The -6 Option To Look For IPv6 Sockets.

以下命令以詳細模式使用fuser,並嘗試查找在端口123上運行的IPv6套接字。

fuser -v -n tcp -6 123

查找佔用某個文件系統的進程

-m選項可與fuser命令一起使用,以查找訪問文件文件系統上文件的進程。 此選項需要文件名作為輸入參數。 -m選項非常有用,尤其是當用於發現正在訪問文件系統的進程並標識要殺死的進程時。

以下命令显示所有訪問“ example.txt”所在的文件系統的進程。 仔細查看-m選項如何與fuser一起使用。

[root@huidukongjian-h4 docker]# fuser -v -m data/v2/config.json 
                     USER        PID ACCESS COMMAND
/root/docker-v2/data/v2/config.json:
                     root     kernel mount /
                     root          1 .rce. systemd
                     root          2 .rc.. kthreadd
                     root          3 .rc.. rcu_gp
                     root          4 .rc.. rcu_par_gp
                     root          6 .rc.. kworker/0:0H-kbl
                     root          8 .rc.. mm_percpu_wq
                     root          9 .rc.. ksoftirqd/0
                     root         10 .rc.. rcu_sched
                     root         11 .rc.. migration/0
                     root         12 .rc.. watchdog/0
                     root         13 .rc.. cpuhp/0
                     root         16 .rc.. netns
                     root         17 .rc.. kauditd
                     root         18 .rc.. khungtaskd
                     root         19 .rc.. oom_reaper
                     root         20 .rc.. writeback
                     root         21 .rc.. kcompactd0
                     root         22 .rc.. ksmd
                     root         23 .rc.. khugepaged
                     root         24 .rc.. crypto
                     root         25 .rc.. kintegrityd
                     root         26 .rc.. kblockd
                     root         27 .rc.. tpm_dev_wq
                     root         28 .rc.. md
                     root         29 .rc.. edac-poller
                     root         30 .rc.. watchdogd
                     root         42 .rc.. kswapd0
                     root         93 .rc.. kthrotld
                     root         94 .rc.. acpi_thermal_pm
                     root         95 .rc.. kmpath_rdacd
                     root         96 .rc.. kaluad
                     root         97 .rc.. ipv6_addrconf
                     root         98 .rc.. kstrp
                     root        326 .rc.. scsi_eh_0
                     root        327 .rc.. scsi_tmf_0
                     root        329 .rc.. kworker/0:1H-kbl
                     root        361 .rc.. ata_sff
                     root        363 .rc.. scsi_eh_1
                     root        365 .rc.. scsi_tmf_1
                     root        366 .rc.. scsi_eh_2
                     root        367 .rc.. scsi_tmf_2
                     root        387 .rc.. xfsalloc
                     root        390 .rc.. xfs_mru_cache
                     root        391 .rc.. xfs-buf/vda1
                     root        394 .rc.. xfs-data/vda1
                     root        395 .rc.. xfs-conv/vda1
                     root        396 .rc.. xfs-cil/vda1
                     root        397 .rc.. xfs-reclaim/vda
                     root        398 .rc.. xfs-log/vda1
                     root        399 .rc.. xfs-eofblocks/v
                     root        400 .rc.. xfsaild/vda1
                     root        486 .rce. systemd-journal
                     rpc         541 .rce. rpcbind
                     root        543 Frce. auditd
                     root        545 .rce. sedispatch
                     root        558 .rc.. rpciod
                     root        559 .rc.. kworker/u3:0
                     root        561 .rc.. xprtiod
                     root        582 Frce. sssd
                     polkitd     585 .rce. polkitd
                     root        589 .rce. rngd
                     dbus        593 frce. dbus-daemon
                     chrony      612 .rce. chronyd
                     root        652 Frce. sssd_be
                     root        668 Frce. sssd_nss
                     root        671 .rc.. ttm_swap
                     root        672 .rc.. nfit
                     root        675 frce. systemd-logind
                     root        683 Frce. gssproxy
                     root        740 frce. NetworkManager
                     root        743 Frce. tuned
                     root        814 frce. systemd-udevd
                     root        889 frce. sshd
                     root        890 Frce. rsyslogd
                     root        895 frce. agetty
                     root        898 frce. crond
                     root        899 frce. agetty
                     root      21821 .rc.. kworker/u2:0-flu
                     root      25475 frce. sshd
                     root      25480 .rce. systemd
                     root      25485 frce. (sd-pam
                     root      25491 frce. sshd
                     root      25492 frce. bash
                     root      25705 Frce. containerd
                     root      25706 Frce. dockerd
                     root      26375 .rc.. kworker/u2:1-eve
                     root      27251 Fr.e. containerd-shim
                     root      27267 F...m v2
                     root      27273 Fr.e. containerd-shim
                     root      27295 ....m sh
                     root      27400 .rce. docker-proxy
                     root      27411 .rce. docker-proxy
                     root      27416 Fr.e. containerd-shim
                     root      27432 ....m sh
                     root      27478 ....m sh
                     root      27479 F...m nginx
                     root      27480 ....m sleep
                     (unknown)  27481 F...m nginx
                     root      27561 ....m sleep
                     root      27705 .rc.. kworker/0:0-xfs-
                     root      27765 .rc.. kworker/0:1-xfs-
                     root      27836 .rc.. kworker/0:2-even
                     root      27860 frce. sshd
                     root      27883 frce. sshd
                     sshd      27884 frce. sshd

fuser還可用於將特定指令發送到某個進程。 當與-k選項一起使用時,fuser命令將KILL指令發送給進程。 有很多指令可以發送給運行中的進程,-l選項有助於查找可以與fuser一起使用的指令列表。

[root@huidukongjian-h4 docker]# fuser -l
HUP INT QUIT ILL TRAP ABRT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT
CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH POLL PWR SYS

本文不再更新,可能存在內容過時的情況,實時更新請訪問原地址:Linux系統如何使用Fuser命令;

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

【其他文章推薦】

※想知道網站建置網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計後台網頁設計

※不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

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

※帶您來看台北網站建置台北網頁設計,各種案例分享

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

GraphicsLab Project 之 Screen Space Planar Reflection

作者:i_dovelemon

日期:2020-06-23

主題:Screen Space Planar Reflection, Compute Shader

引言

        前段時間,同事發來一篇講述特化版本的 Screen Space Reflection 實現 Planar Reflection 的文章。出於好奇,實驗了下,看看效果如何。如下是目前實現出來的基礎版本的效果:

 原理

        對於上圖來說, Water Plane 表示水面,上半部分為實際場景的山體,下半部分為以水面為鏡像進行反射之後的山體效果。

        對於山體上某一個點(圖中白色點)來說,它對應的鏡像點為黃色點。

        我們可以從 Screen Position 以及 Depth Texture 信息,計算出來白點的世界坐標位置 WorldPosition

        然後可以以 Water Plane 所在的平面對該 WorldPosition 作鏡像操作,得到 ReflectionPosition

        得到 ReflectionPosition 之後,我們就能夠計算出來 ReflectionPostion 所對應的屏幕坐標 Reflection Screen Position

        根據前面的操作,我們就可以知道,此時 Reflection Screen Position 所反射的顏色即為 Screen Positon 所表示的顏色。

        基礎原理十分簡單,但是實際實現的時候,會發現有很多問題。接下里一一講述。

問題

閃爍

        根據上面的原理,可以想到,有多個像素可能會被反射到相同的位置,如下圖所示:

         這樣由於 GPU 執行順序的不確定性,就會導致畫面出現閃爍,如下所示:

        針對這樣的問題,我們實際需要的反射點是最近的反射點。可以考慮使用 HLSL 中提供的 InterlockedMin/InterlockedMax (參考[1],[2]) 之類的指令,在寫入數據時進行大小比較,從而實現保存最近反射點的功能。

        前面的指令雖然能夠實現大小比較,以此進行排序。但是根據前面的描述,我們實際保存的是反射點的顏色。沒有辦法只根據顏色進行排序,所以我們需要保存其他便於排序的信息,這裏選擇使用反射點的 Screen Position。並且按照如下方式進行編碼,從而實現獲取最近反射點的效果:

                        uint2 SrcPosPixel = uint2(DepthPos.x, DepthPos.y);
                        uint2 ReflPosPixel = ReflPosUV * uint2(ReflectWidth, ReflectHeight);

                        int Hash = SrcPosPixel.y << 16 | SrcPosPixel.x;
                        int dotCare = 0;
                        InterlockedMin(HashResult[ReflPosPixel], Hash, dotCare);

Encode and Sort

孔洞

        根據先前算法的描述,我們知道,我們先要根據 Depth 信息和 Screen Position 信息計算出 World Positon,然後鏡像之後,在轉化為新的屏幕坐標。在這一系列操作中,由於數值計算的不精確性,導致有些地方沒有存儲到有效的反射點位置信息,從而導致最終显示時畫面上有孔洞的情況,如下圖所示:

        幸運的是,從結果看這些孔洞並不會聚集在一起,形成大塊的黑塊。對於這種情況,我們只要在生成反射貼圖的時候,檢測到沒有保存有效位置信息時,遍歷下周圍的像素,尋找到一個擁有有效像素的值即可解決這個問題,如下代碼所示:

        uint Hash = HashTexture[id.xy].x;
        if (Hash == 0x0FFFFFFF)
            Hash = HashTexture[uint2(id.x, id.y + 1)].x;
        if (Hash == 0x0FFFFFFF)
            Hash = HashTexture[uint2(id.x, id.y - 1)].x;
        if (Hash == 0x0FFFFFFF)
            Hash = HashTexture[uint2(id.x + 1, id.y)].x;
        if (Hash == 0x0FFFFFFF)
            Hash = HashTexture[uint2(id.x - 1, id.y)].x;

        if (Hash != 0x0FFFFFFF)
        {
            uint x = Hash & 0xFFFF;
            uint y = Hash >> 16;
            ReflectionTexture[id.xy] = ColorTexture[uint2(x, y)];
        }
        else
        {
            ReflectionTexture[id.xy] = float4(0.0f, 0.0f, 0.0f, 0.0f);
        }

Hole

        如下是修正孔洞之後的效果:

實現

        本文的代碼是使用 Unity 實現的,實現起來比較簡單。比較坑的地方在於 Unity 裏面獲取 Projection Matrix 要通過 GL.GetGPUProjectionMatrix (文獻[3]) 轉化一下才能變成傳遞到 GPU 上用於渲染的投影矩陣。如下是功能核心的 Compute Shader 代碼:

// Each #kernel tells which function to compile; you can have many kernels
#pragma enable_d3d11_debug_symbols
#pragma kernel SSPRClear_Main
#pragma kernel SSPRHash_Main
#pragma kernel SSPRResolve_Main

//-----------------------------------------------------------------
float4x4 VPMatrix;
float4x4 InvVPMatrix;
uint Width;
uint Height;
uint ReflectWidth;
uint ReflectHeight;

//--------------------------------------------------------------------
RWTexture2D<int> ClearHashTexture;

[numthreads(8, 8, 1)]
void SSPRClear_Main(uint3 id : SV_DispatchThreadID)
{
    if (id.x < ReflectWidth && id.y < ReflectHeight)
    {
        ClearHashTexture[id.xy] = 0x0FFFFFFF;
    }
}

//---------------------------------------------------------------
Texture2D<float> DepthTex;
RWTexture2D<int> HashResult;

#define DownSampleFactor (1)

float3 Unproject(float3 clip)
{
    float4 clipW = float4(clip, 1.0f);
    clipW = mul(InvVPMatrix, clipW);
    clipW.xyz = clipW.xyz / clipW.w;
    return clipW.xyz;
}

float2 Project(float3 world)
{
    float4 worldW = float4(world, 1.0f);
    worldW = mul(VPMatrix, worldW);
    worldW.xy = worldW.xy / worldW.w;
    worldW.xy = (worldW.xy + float2(1.0f, 1.0f)) / 2.0f;
    return worldW.xy;
}

[numthreads(8, 8, 1)]
void SSPRHash_Main(uint3 id : SV_DispatchThreadID)
{
    for (uint i = 0; i < DownSampleFactor; i++)
    {
        for (uint j = 0; j < DownSampleFactor; j++)
        {
            uint2 DepthPos = uint2(id.x * DownSampleFactor + i, id.y * DownSampleFactor + j);
            if (DepthPos.x < Width && DepthPos.y < Height)
            {
                float depth = DepthTex.Load(int3(DepthPos.x, DepthPos.y, 0)).x;

                if (depth > 0.0f)
                {
                    float2 uv = (DepthPos.xy * 1.0f) / float2(Width, Height);
                    uv = uv * 2.0f - float2(1.0f, 1.0f);
                    uv.y = -uv.y;

                    float3 PosWS = Unproject(float3(uv, depth));

                    if (PosWS.y > 0.0f)
                    {
                        float3 ReflPosWS = float3(PosWS.x, -PosWS.y, PosWS.z);
                        float2 ReflPosUV = Project(ReflPosWS);

                        uint2 SrcPosPixel = uint2(DepthPos.x, DepthPos.y);
                        uint2 ReflPosPixel = ReflPosUV * uint2(ReflectWidth, ReflectHeight);

                        int Hash = SrcPosPixel.y << 16 | SrcPosPixel.x;
                        int dotCare = 0;
                        InterlockedMin(HashResult[ReflPosPixel], Hash, dotCare);
                    }
                }
            }
        }
    }
}

//------------------------------------------------------------------------------
Texture2D<int> HashTexture;
Texture2D<float4> ColorTexture;
RWTexture2D<float4> ReflectionTexture;

[numthreads(8, 8, 1)]
void SSPRResolve_Main(uint3 id : SV_DispatchThreadID)
{
    if (id.x < ReflectWidth && id.y < ReflectHeight)
    {
        uint Hash = HashTexture[id.xy].x;
        if (Hash == 0x0FFFFFFF)
            Hash = HashTexture[uint2(id.x, id.y + 1)].x;
        if (Hash == 0x0FFFFFFF)
            Hash = HashTexture[uint2(id.x, id.y - 1)].x;
        if (Hash == 0x0FFFFFFF)
            Hash = HashTexture[uint2(id.x + 1, id.y)].x;
        if (Hash == 0x0FFFFFFF)
            Hash = HashTexture[uint2(id.x - 1, id.y)].x;

        if (Hash != 0x0FFFFFFF)
        {
            uint x = Hash & 0xFFFF;
            uint y = Hash >> 16;
            ReflectionTexture[id.xy] = ColorTexture[uint2(x, y)];
        }
        else
        {
            ReflectionTexture[id.xy] = float4(0.0f, 0.0f, 0.0f, 0.0f);
        }
    }
}

ScreenSpacePlanarReflection

結論

        本文只是探索這個方法的可能性,更加複雜的實現,更加高效的優化可以參考文獻[4][5],這也是本文主要參考的對象。

        相比於傳統的繪製場景兩邊的方法來說,這個方案的性能更加高效,同時也沒有 SSR 那樣的高需求。在條件滿足的情況下,使用該方案能夠帶來顯著的效果提升,推薦可以嘗試。

        完整代碼在這裏:https://github.com/idovelemon/UnityProj/tree/master/ScreenSpacePlanarReflection

參考文獻

[1] HLSL-InterlockedMax

[2] HLSL-InterlockedMin

[3] GL.GetGPUProjectionMatrix

[4] Screen Space Planar Reflection

[5] Optimized Pixel Projected Reflections for Planar Reflectors

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

【其他文章推薦】

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

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

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

※幫你省時又省力,新北清潔一流服務好口碑

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

歐洲各國豪雨不斷 洪水土石流頻傳

摘錄自2019年11月27日公視報導

美澳野火肆虐,在歐洲則是飽受洪災侵襲,包括義大利、法國和希臘,當地從上個週末以來就豪雨不斷;各地接連發生洪水和土石流災情,至少已經傳出有九人死亡。

有的汽車卡在樹上,有的掉進泥池裡,所有東西都被大水沖得四散各地,連路面也跟著崩塌毀損,每戶民宅裡外都是一片狼藉。這是希臘西部這幾天遭受暴雨襲擊過後的景象,面對天災,居民有苦難言。

當地居民說,「水勢洶洶而來,當我們呼叫人在地下室的孩子時,什麼東西都沒有了,門啊、窗啊,洗衣機都在庭院裡了,你去那邊看看庭院的狀況,原本停了五台車,現在一台也不剩。」類似的豪雨災情,同樣出現在義大利北部,靠近山區的一座高架橋不敵洪水與土石流,應聲斷裂、坍塌,所幸目前沒有發現人員傷亡。

另一個為強降雨所苦的地區是法國南部,其中,瓦爾省境內受到洪患影響最大的幾座城鎮,短短48小時之內就累積了三個月的降雨量。許多地方河川潰堤,導致嚴重淹水,而等到星期一部分地區水位退去之後,有4500個住戶停電。

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

【其他文章推薦】

※想知道網站建置網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計後台網頁設計

※不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

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

※帶您來看台北網站建置台北網頁設計,各種案例分享

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