二叉樹的創建與遍歷(遞歸實現)

在樹的基本概念和術語總結一文中介紹了二叉樹的基本結構。

在不知道怎樣用遞歸?按步驟來!一文中介紹了如何使用遞歸。

二叉樹的結構是遞歸的,所以創建、遍歷也可以通過遞歸實現。

下面是一顆二叉樹:

結點的定義:

public class Node {
    Integer value;
    Node leftChild;
    Node rightChild;

    public Node(Integer value) {
        this.value = value;
    }
}

創建

各個結點的值用一個ArrayList集合來保存,根據該集合來創建二叉樹。

按照不知道怎樣用遞歸?按步驟來!中的方法分析如何遞歸地創建一顆二叉樹。

第一步:找到大問題是什麼?

創建一顆二叉樹。

private Node createBinaryTree(ArrayList<Integer> inputList) {
        
}

第二步:找到最簡單問題是什麼?滿足最簡單問題時應該做什麼?

「創建一個空二叉樹」是最簡單的問題,當滿足時,直接返回null

private Node createBinaryTree(ArrayList<Integer> inputList) {   
    if (inputList == null || inputList.isEmpty()) {//最簡單問題
        return null;
    }
}

第三步:找到重複邏輯是什麼?

因為我們把每個結點的值都放在ArrayList集合中了,所以,每創建一個二叉樹結點,都需要從集合中拿值。

對於每個結點而言,它一定有左孩子和右孩子(上圖中結點3的左孩子和右孩子可以看成「值為null的結點」),

所以要確定每個結點的左孩子和右孩子是誰。

所以重複邏輯是:

  1. 從集合中拿值,創建結點。
  2. 確定該結點的左孩子和右孩子。
//大問題
private Node createBinaryTree(ArrayList<Integer> inputList) {
    if (inputList == null || inputList.isEmpty()) {//最簡單問題
        return null;
    }
    Node node = null;//重複邏輯
    Integer value = inputList.remove(0);//重複邏輯
    if (value != null) {
        node = new Node(value);//重複邏輯
        node.leftChild = ?;//重複邏輯
        node.rightChild = ?;//重複邏輯
    }

}

第四步:自己調用自己

先解釋一下上個代碼片段中的問號。

要確定一個結點的左孩子和右孩子是誰,其實就是一個賦值操作,那麼就一定要先有一些可選的結點

比如說,如果我們要確定結點1的左右孩子,那麼結點2、結點5就必須已經被創建出來了,這樣才能進行賦值操作。

那麼如何在進行賦值操作之前創建結點2、結點5呢?答案是自己調用自己。

我們可以把結點2、結點5看成另一顆二叉樹的根結點,只要我們創建好以結點2或結點5為根結點的二叉樹,那麼結點2和結點5自然就被創建出來了。

確定結點2和結點5的左右孩子同理,這樣一直分解下去,直到分解成最簡單問題,或者從集合中拿到null為止。

注意:自己調用自己時參數的變小是通過inputList.remove(0)實現的。

//大問題
private Node createBinaryTree(ArrayList<Integer> inputList) {
    if (inputList == null || inputList.isEmpty()) {//最簡單問題
        return null;
    }
    Node node = null;//重複邏輯
    Integer value = inputList.remove(0);//重複邏輯
    if (value != null) {
        node = new Node(value);//重複邏輯
        node.leftChild = createBinaryTree(inputList);//重複邏輯,自己調用自己
        node.rightChild = createBinaryTree(inputList);//重複邏輯,自己調用自己
    }

}

第五步:返回

返回的是根結點,該根結點被確定為左孩子或右孩子,從而構成一顆更大的二叉樹,直到滿足最大問題的那顆二叉樹被創建成功,此時返回的根結點是真正的解。

//大問題
private Node createBinaryTree(ArrayList<Integer> inputList) {
    if (inputList == null || inputList.isEmpty()) {//最簡單問題
        return null;
    }
    Node node = null;//重複邏輯
    Integer value = inputList.remove(0);//重複邏輯
    if (value != null) {
        node = new Node(value);//重複邏輯
        node.leftChild = createBinaryTree(inputList);//重複邏輯,自己調用自己
        node.rightChild = createBinaryTree(inputList);//重複邏輯,自己調用自己
    }
	return node;//返回
}

遍歷

先序遍歷

第一步:找到大問題是什麼?

先序遍歷一顆二叉樹,打印出每個結點的值。

public void preOrderTraveral(Node node) {
    
}

第二步:找到最簡單問題是什麼?滿足最簡單問題時應該做什麼?

「遍歷一顆空二叉樹」是最簡單問題,此時任何操作都不用做。

public void preOrderTraveral(Node node) {
    if (node == null) {//最簡單問題
        return;
    }
}

第三步:找到重複邏輯是什麼?

打印每個結點的值

public void preOrderTraveral(Node node) {
    if (node == null) {//最簡單問題
        return;
    }
    System.out.print(node.value);//重複邏輯
}

第四步:自己調用自己

先序遍歷的過程:

  1. 遍歷根結點
  2. 先序遍歷左子樹
  3. 先序遍歷右子樹
public void preOrderTraveral(Node node) {
    if (node == null) {//最簡單問題
        return;
    }
    System.out.print(node.value);//重複邏輯
    preOrderTraversal(node.leftChild);//自己調用自己
    preOrderTraversal(node.rightChild);//自己調用自己
}

自己調用自己時參數通過node.leftChildnode.rightChild不斷變小

第五步:返回

不需要返回值。

中序遍歷和後序遍歷同理

完整代碼

//二叉樹結點
public class Node {
    Integer value;
    Node leftChild;
    Node rightChild;

    public Node(Integer value) {
        this.value = value;
    }
}
//二叉樹
public class BinaryTree {

    private Node root;

    public Node getRoot() {
        return root;
    }

    public BinaryTree(ArrayList<Integer> inputList) {
        Node root = createBinaryTree(inputList);
        this.root = root;
    }

	//創建二叉樹
    private Node createBinaryTree(ArrayList<Integer> inputList) {
        if (inputList == null || inputList.isEmpty()) {
            return null;
        }
        Node node = null;
        Integer value = inputList.remove(0);
        if (value != null) {
            node = new Node(value);
            node.leftChild = createBinaryTree(inputList);
            node.rightChild = createBinaryTree(inputList);
        }
        return node;
    }

    //先序遍歷
    public void preOrderTraversal(Node node) {
        if (node == null) {
            return;
        }
        System.out.print(node.value);
        preOrderTraversal(node.leftChild);
        preOrderTraversal(node.rightChild);
    }
	
    //中序遍歷
    public void inOrderTraversal(Node node) {
        if (node == null) {
            return;
        }
        inOrderTraversal(node.leftChild);
        System.out.print(node.value);
        inOrderTraversal(node.rightChild);
    }

    //後序遍歷
    public void postOrderTraversal(Node node) {
        if (node == null) {
            return;
        }
        postOrderTraversal(node.leftChild);
        postOrderTraversal(node.rightChild);
        System.out.print(node.value);
    }
}
//測試
public static void main(String[] args) {
    List<Integer> list = Arrays.asList(new Integer[]{1, 2, 3, null, null, 4, null, null, 5, null, 6});
    ArrayList inputList = new ArrayList(list);

    BinaryTree binaryTree = new BinaryTree(inputList);
    Node root = binaryTree.getRoot();
    System.out.print("先序遍歷:");
    binaryTree.preOrderTraversal(root);
    System.out.print("\n中序遍歷:");
    binaryTree.inOrderTraversal(root);
    System.out.print("\n後序遍歷:");
    binaryTree.postOrderTraversal(root);
}

如有錯誤,還請指正。

文章首發於微信公眾號『行人觀學』

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

【其他文章推薦】

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

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

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

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

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

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

聚甘新

java併發之synchronized

Java為我們提供了隱式(synchronized聲明方式)和顯式(java.util.concurrentAPI編程方式)兩種工具來避免線程爭用。

本章節探索Java關鍵字synchronized。主要包含以下幾個內容。

  • synchronized關鍵字的使用;
  • synchronized背後的Monitor(管程);
  • synchronized保證可見性和防重排序;
  • 使用synchronized注意嵌套鎖定。

使用方式

synchronized 關鍵字有以下四種使用方式。

  1. 實例方法
  2. 靜態方法
  3. 實例方法中的代碼塊
  4. 靜態方法中的代碼塊
// 實例方法同步和實例方法代碼塊同步
public class SynchronizedTest {
    private int count;
    public void setCountPart(int num) {
        synchronized (this) {
            this.count += num;
        }
    }
    public synchronized void setCount(int num) {
        this.count += num;
    }
}
// 靜態方法同步和靜態方法代碼塊同步
public class SynchronizedTest {
    private static int count;
    public static void setCountPart(int num) {
        synchronized (SynchronizedTest.class) {
            count += num;
        }
    }
    public static synchronized void setCount(int num) {
        count += num;
    }
}

使用關鍵字synchronized實現同步是在JVM內部實現處理,對於應用開發人員來說它是隱式進行的。

每個Java對象都有一個與之關聯的monitor。

當線程調用實例同步方法時,會自動獲取實例對象的monitor。

當線程調用靜態同步方法時,會自動獲取該類Class實例對象的monitor。

Class實例:JVM為每個加載的class創建了對應的Class實例來保存class及interface的所有信息;

Monitor(管程)

Monitor 直譯為監視器,中文圈裡稱為管程。它的作用是讓線程互斥,保護共享數據,另外也可以向其它線程發送滿足條件的信號

如下圖,線程通過入口隊列(Entry Queue)到達訪問共享數據,若有線程佔用轉移等待隊列(Wait Queue),線程訪問共享數據完后觸發通知或轉移到信號隊列(Signal Queue)。

關於管程模型

網上查詢很多文章,大多數羅列 “ Hasen 模型、Hoare 模型和 MESA模型 ”這些名詞,看過之後我還是一知半解。本着對知識的求真,查找溯源,找到了以下資料。

為什麼會有這三種模型?

假設有兩個線程A和B,線程B先進入monitor執行,線程A處於等待。當線程A執行完準備退出的時候,是先退出monitor還是先喚醒線程A?這時就出現了Mesa語義, Hoare語義和Brinch Hansen語義 三種不同版本的處理方式。

Mesa Semantics

Mesa模型中 線程只會出現在WaitQueue,EntryQueue,Monitor。

當線程B發出信號告知線程A時,線程A從WaitQueue 轉移到EntryQueue並等待線程B退出Monitor之後再進入Monitor。也就是先通知再退出。

Brinch Hanson Semantics

Brinch Hanson模型和Mesa模型類似區別在於僅允許線程B退出Monitor后才能發送信號給線程A。也就是先退出再通知。

Hoare Semantics

Hoare模型中 線程會分別出現在WaitQueue,EntryQueue,SignalQueue,Monitor中。

當線程B發出信號告知線程A並且退出Monitor轉移到SignalQueue,線程A進入Monitor。當線程A離開Monitor后,線程B再次回到Monitor。

https://www.andrew.cmu.edu/course/15-440-kesden/applications/ln/lecture6.html

https://cseweb.ucsd.edu/classes/sp17/cse120-a/applications/ln/lecture8.html

Java裏面monitor是如何處理?

我們通過反編譯class文件看下Synchronized工作原理。

public class SynchronizedTest {
    private int count;
    public void setCountPart(int num) {
        synchronized (this) {
            this.count += num;
        }
    }
}

編譯和反編譯命令

javac SynchronizedTest.java
javap -v SynchronizedTest

我們看到兩個關鍵指令 monitorentermonitorexit

monitorenter

Each object has a monitor associated with it. The thread that executes monitorenter gains ownership of the monitor associated with objectref. If another thread already owns the monitor associated with objectref, the current thread ……

每個對象都有一個關聯monitor。

線程執行 monitorenter 時嘗試獲取關聯對象的monitor。

獲取時如果對象的monitor被另一個線程佔有,則等待對方釋放monitor后再次嘗試獲取。

如果獲取成功則monitor計數器設置為1並將當前線程設為monitor擁有者,如果線程再次進入計數器自增,以表示進入次數。

monitorexit

The current thread should be the owner of the monitor associated with the instance referenced by objectref……

線程執行monitorexit 時,monitor計數器自減,當計數器變為0時釋放對象monitor。

原文:https://docs.oracle.com/javase/specs/jvms/se6/html/Instructions2.doc9.html

可見性和重排序

在介紹Java併發之內存模型的時候,我們提到過線程訪問共享對象時會先拷貝副本到CPU緩存,修改后返回CPU緩存,然後等待時機刷新到主存。這樣一來另外線程讀到的數據副本就不是最新,導致了數據的不一致,一般也將這種問題稱為線程可見性問題

不過在使用synchronized關鍵字的時候,情況有所不同。線程在進入synchronized後會同步該線程可見的所有變量,退出synchronized后,會將所有修改的變量直接同步到主存,可視為跳過了CPU緩存,這樣一來就避免了可見性問題。

另外Java編譯器和Java虛擬機為了達到優化性能的目的會對代碼中的指令進行重排序。但是重排序會導致多線程執行出現意想不到的錯誤。使用synchronized關鍵字可以消除對同步塊共享變量的重排序。

局限與性能

synchronized給我們提供了同步處理的便利,但是它在某些場景下也存在局限性,比如以下場景。

  • 讀多寫少場景。讀動作其實是安全,我們應該嚴格控制寫操作。替代方案使用讀寫鎖readwritelock。如果只有一個線程進行寫操作,可使用volatile關鍵字替代。
  • 允許多個線程同時進入場景。synchronized限制了每次只有一個線程可進入。替代方案使用信號量semaphore。
  • 需要保證搶佔資源公平性。synchronized並不保證線程進入的公平性。替代方案公平鎖FairLock。

關於性能問題。進入和退出同步塊操作性能開銷很小,但是過大範圍設置同步或者在頻繁的循環中使用同步可能會導致性能問題。

可重入,在monitorenter指令解讀中,可以看出synchronized是可重入,重入一般發生在同步方法嵌套調用中。不過要防止嵌套monitor死鎖問題。

比如下面代碼會直接造成死鎖。

    private final Object lock1 = new Object();
    private final Object lock2 = new Object();
    public void method1()   {
        synchronized (lock1) {
            synchronized (lock2) {
            }
        }
    }
    public void method2()   {
        synchronized (lock2) {
            synchronized (lock1) {
            }
        }
    }

現實情況中,開發一般都不會出現以上代碼。但在使用 wait() notify() 很可能會出現阻塞鎖定。下面是一個模擬鎖的實現。

  1. 線程A調用lock(),進入鎖定代碼執行。
  2. 線程B調用lock(),得到monitorObj的monitor后等待線程B喚醒。
  3. 線程A執行完鎖定代碼后,調用unlock(),在嘗試獲取monitorObj的monitor時,發現有線程佔用,也一直掛起。
  4. 這樣線程A B 就互相干瞪眼!
public class Lock{
protected MonitorObj monitorObj = new MonitorObj();
    protected boolean isLocked = false;
    public void lock() throws InterruptedException{
        synchronized(this){
            while(isLocked){
                synchronized(this.monitorObj){
                    this.monitorObj.wait();
                }
            }
            isLocked = true;
        }
    }
    public void unlock(){
        synchronized(this){
            this.isLocked = false;
            synchronized(this.monitorObj){
                this.monitorObj.notify();
            }
        }
    }
}

總結

本文記錄Java併發編程中synchronized相關的知識點。

歡迎大家留言交流,一起學習分享!!!

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

【其他文章推薦】

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

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

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

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

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

聚甘新

這樣用技術,程序猿更幸福

作為久經職場而又富有責任心的猿外,每天上班的第一件事,便是連上生產服務器,top free ps 一頓命令熱身猛如虎,然後匯總出業務服務的狀態、系統指標等,看到一切正常,心裏才算踏實。

不知道有多少盡職盡責的朋友們,每天都重複的做着如此机械而又簡單的事情。說句實話,其實和机械狗沒啥區別。本着做事認真、追求極致的態度,那我們為什麼不能打造一款這樣的机械狗呢?

關注過猿外的朋友們都應該知道,在之前的文章中,猿外曾經提到過,守護服務的監控應用——看門狗。不錯,要打造的机械狗,就是看門狗。

接下來就給大家簡單聊一聊,看門狗的背景來源以及實現思路,希望能給正在尋找守護服務監控解決方案的朋友們,一點實現思路。下面的內容十分燒腦,請大家坐穩扶好。

1. 什麼是看門狗?

在由單片機構成的微型計算機系統中,由於單片機的工作,常常會受到來自外界電磁場的干擾,造成程序的跑飛,而陷入死循環,程序的正常運行被打斷,由單片機控制的系統無法繼續工作,會造成整個系統的陷入停滯狀態,發生不可預料的後果,所以出於對單片機運行狀態進行實時監測的考慮,便產生了一種專門用於監測單片機程序運行狀態的芯片,稱“看門狗”——摘自“百度百科”。

相信有不少朋友,看到上面一段非人話的描述,就想直接刪了此篇熊文,溜之大吉。大家,心莫慌,猿外再舉個貼近生活的栗子解釋一下。

猿外家養了一條 dog ,經常陪孩子玩,孩子時不時的撒一把狗糧給 dog;
如果孩子睡着,長時間未撒狗糧,dog 就主動把孩子叫醒;
繼續讓孩子撒狗糧,然後 dog 吃到孩子撒的狗糧,就高興的狂吠;
如果 dog 跑走了,孩子也不撒狗糧了,孩子也就可以睡覺了。

剝開栗子,內行看門道,外行看熱鬧,把上面內容翻譯一遍:

原話:猿外家養了一條 dog,經常陪孩子玩,孩子時不時的撒一把狗糧給 dog;
翻譯:存在兩個進程:子進程(應用服務)、父進程(守護進程),子進程和父進程兩個進程間一直保持心跳通訊;

原話:如果孩子睡着,長時間未撒狗糧, dog 就主動把孩子叫醒;
翻譯:子進程與父進程心跳通訊中斷,父進程則負責啟動子進程,完成子進程的服務守護;

原話:繼續讓孩子撒狗糧,然後 dog 吃到孩子撒的狗糧,就高興的狂吠;
翻譯:子進程與父進程實時通訊,父進程實時監控子進程的狀態,並實時進行報警通知;

原話:如果 dog 跑走了,孩子也不撒狗糧了,孩子也就可以睡覺了。
翻譯:父進程down了,子進程與父進程的通訊也就無法保持了,子進程也一併退出。

不知道朋友們通過上面的栗子剖析,對看門狗了解了多少呢?為了更清晰的給你們說清楚,猿外再給大家上個一目瞭然的圖吧。

如上圖所示,猿外主要把看門狗定位為:集服務守護、指標採集、日誌歸集、自動化報警於一體的監控系統。說白了,有了看門狗,媽媽再也不用擔心我的應用服務出問題了。

洋洋洒洒鋪墊這麼多,那到底該如何實現呢?

2. 如何實現?

猿外先給大家畫個腦圖,主要分五步走,希望朋友們跟着猿外的腳步,莫掉隊。

相信絕大部分朋友通過猿外的腦圖,已經對看門狗應用了解個八九不離十。猿外再稍微闡述一下:

實現方式:看門狗應用在實現過程中也走了一些彎路。剛開始技術選型的時候,考慮到看門狗應該對應用零侵入、低耦合,於是採用javaagent植入方式進行實現,但是萬萬沒想到的是開發、調試過程比較麻煩,一遇到問題,小夥伴就排查半天,在第一版上線后,猿外迅速帶領小夥伴,採用插件化方式進行第二版迭代。

服務守護:採用 J2SE 1.5 java.lang 包中新添加的 ProcessBuilder 類來完成子進程的啟動、停止、重啟(完成子服務的守護功能)。

指標採集:通過 JMX 方式連接子服務,獲取子服務的內存佔用、CPU 使用、線程數等指標。

日誌歸集:主要站在 flume 的肩膀上,集成到項目中並進行二次開發,存儲採用 elasticsearch。

報警通知:主要提供郵箱通知、QQ 通知、微信實時通知。

其中每個實現細節猿外就不再進行深入展開了,感興趣的朋友歡迎關注微信公眾號四猿外(si-yuanwai),後台留言進行交流。

羅里吧嗦,寫了這麼多。羅馬並非一日建成的,實現途中踩過的坑、吃過的苦頭,剎那間全部湧上心頭。不過看門狗應用,已經在生產上推廣使用,自上線以來還廣受好評,猿外現在每天來的第一件事,由原來的系統巡檢變成了沖咖啡,幸福指數陡然上升。

最後,猿外想說的是:簡單的事重複做,你就是專家;重複的事用心做,你就是贏家。沒錯,這話說的沒毛病,不過成為專家之餘,大家不妨稍做創新,看看有沒有可以用的技術輪子,說不定會改變机械的工作方式,提升工作效率,提高幸福指數呢。

歡迎大家關注我的公眾號:四猿外。
我準備了一些純手打的高質量PDF,有好友贊助的也有我自己的,大家可以免費領取:
深入淺出Java多線程、HTTP超全匯總、Java基礎核心總結、程序員必知的硬核知識大全、簡歷面試談薪的超全乾貨。
別看數量不多,但篇篇都是乾貨,看完的都說很肝。

領取方式:掃碼關注后,在公眾號後台回復:666

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

【其他文章推薦】

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

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

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

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

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

聚甘新

Oracle SQL調優系列之SQL Monitor Report

@

目錄

  • 1、SQL Monitor簡介
  • 2、捕捉sql的前提
  • 3、SQL Monitor 參數設置
  • 4、SQL Monitor Report
    • 4.1、SQL_ID獲取
    • 4.2、Text文本格式
    • 4.3、Html格式
    • 4.4、ACTIVE格式
    • 4.5 SQL Monitoring list
  • 5、SQL Monitor Report查詢
    • 5.1、查看所有的sql monitor report
    • 5.2、查看某個sql的sql monitor report
    • 5.3、查看某個sql的整體性能
    • 5.4、查看整個系統的性能

1、SQL Monitor簡介

sql monitor是oracle官方提供的自動監控符合特定條件的SQL,用於收集執行時的細節信息的監控工具,常用於sql調優和系統性能監控

2、捕捉sql的前提

sql monitor 捕捉sql的前提:

  • 并行執行的sql語句
  • 單次執行消耗的CPU或IO超過5秒
  • statistics_level級別必須是TYPICAL 或者ALL
  • 使用/* +MONITOR*/ HINT的SQL語句

3、SQL Monitor 參數設置

  • STATISTICS_LEVEL必須設置為:’TYPICAL’(缺省)或者 ‘ALL’
  • CONTROL_MANAGEMENT_PACK_ACCESS設置為:’DIAGNOSTIC+TUNING’

查看statistics_level參數

show parameter statistics_level;

建議還是改變Session就可以

alter session set statistics_level=ALL;

查看參數CONTROL_MANAGEMENT_PACK_ACCESS

show parameter CONTROL_MANAGEMENT_PACK_ACCESS;

4、SQL Monitor Report

本博客採用DBMS_SQLTUNE包DBMS_SQLTUNE.report_sql_monitor的方式獲取,報告格式有:’TEXT’,’HTML’,’XML’ ,’ACTIVE’,其中’ACTIVE’只在11g R2以後才支持

4.1、SQL_ID獲取

sql monitor使用,必須在sql中使用/* +MONITOR*/ Hint,然後數據會存在v$sql_monitor表裡

隨意找條sql,注意要加/*+ moniotr*/


select /*+ moniotr*/ a.user_code, a.full_name, a.user_pwd, c.unit_code, c.unit_name
  from base_user a
  left join (select ur.user_code, ur.unit_code
               from t_user_role ur
              where ur.user_role < 10) b
    on a.user_code = b.user_code
  left join t_unit_info c
    on b.unit_code = c.unit_code
 where c.unit_code in
       (select uinfo.unit_code
          from t_unit_info uinfo
         start with uinfo.unit_code = '15803'
        connect by prior uinfo.unit_code = uinfo.para_unit_code);
     

提供sql查詢,獲取sql_id

select sql_id,sql_text from v$sql_monitor where sql_text like '%t_unit_info%

4.2、Text文本格式

將上面查詢到的sql_id改下,然後執行如下SQL:

SET LONG 1000000
SET LONGCHUNKSIZE 1000000
SET LINESIZE 1000
SET PAGESIZE 0
SET TRIM ON
SET TRIMSPOOL ON
SET ECHO OFF
SET FEEDBACK OFF
spool report_sql_monitor_text.txt
SELECT DBMS_SQLTUNE.REPORT_SQL_MONITOR(
  SQL_ID => 'g9rtj389t0g66',
  TYPE => 'TEXT',
  REPORT_LEVEL => 'ALL') AS REPORT
FROM dual;
spool off

獲取到text格式的sql monitor

4.3、Html格式

SET LONG 1000000
SET LONGCHUNKSIZE 1000000
SET LINESIZE 1000
SET PAGESIZE 0
SET TRIM ON
SET TRIMSPOOL ON
SET ECHO OFF
SET FEEDBACK OFF
spool report_sql_monitor_html.html
SELECT DBMS_SQLTUNE.REPORT_SQL_MONITOR(
  SQL_ID => 'g9rtj389t0g66',
  TYPE => 'HTML',
  REPORT_LEVEL => 'ALL') AS REPORT
FROM dual;
spool off

獲取到對應報告,可以看到執行計劃、Buffer Gets 等等信息

4.4、ACTIVE格式

ACTIVE格式需要下載相應的flash組件、腳本,詳細見SQL Monitor Report 使用詳解

SET LONG 1000000
SET LONGCHUNKSIZE 1000000
SET LINESIZE 1000
SET PAGESIZE 0
SET TRIM ON
SET TRIMSPOOL ON
SET ECHO OFF
SET FEEDBACK OFF
spool report_sql_monitor_active.html
SELECT DBMS_SQLTUNE.REPORT_SQL_MONITOR(
  SQL_ID => '2rjh5d5k2yujz',
  TYPE => 'ACTIVE',
  REPORT_LEVEL => 'ALL',
  BASE_PATH => 'http://ip/script') AS REPORT
FROM dual;
spool off

4.5 SQL Monitoring list

如果要獲取所有sql monitor,就可以使用如下SQL:

SET LONG 1000000
SET LONGCHUNKSIZE 1000000
SET LINESIZE 1000
SET PAGESIZE 0
SET TRIM ON
SET TRIMSPOOL ON
SET ECHO OFF
SET FEEDBACK OFF
SPOOL report_sql_monitor_list.html
SELECT dbms_sqltune.report_sql_monitor_list(
  type         => 'HTML',
  report_level => 'ALL') AS report
FROM dual;
SPOOL OFF

5、SQL Monitor Report查詢

提供sql monitor常用的查詢腳本

5.1、查看所有的sql monitor report

  • 查看所有的sql monitor report
   select dbms_sqltune.report_sql_monitor from dual;

5.2、查看某個sql的sql monitor report

  • 查看某個sql的sql monitor report
  SELECT DBMS_SQLTUNE.report_sql_monitor(sql_id => '2rjh5d5k2yujz', type => 'TEXT') from dual;

5.3、查看某個sql的整體性能

  • 查看某個sql的整體性能
   SELECT DBMS_SQLTUNE.report_sql_monitor_list(sql_id=>'2rjh5d5k2yujz',type =>'TEXT',report_level => 'ALL') AS report FROM dual;

5.4、查看整個系統的性能

  • 查看整個系統的性能
   SELECT DBMS_SQLTUNE.report_sql_monitor_list(type =>'TEXT',report_level => 'ALL') AS report FROM dual;

相關SQL腳本下載:sql download

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

【其他文章推薦】

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

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

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

※超省錢租車方案

FB行銷專家,教你從零開始的技巧

聚甘新

基礎拾遺—-多線程,基礎拾遺—-多線程

基礎拾遺

基礎拾遺——特性詳解

基礎拾遺——webservice詳解

基礎拾遺——redis詳解

基礎拾遺——反射詳解

基礎拾遺——委託、事件詳解

基礎拾遺——接口詳解

基礎拾遺——泛型詳解

基礎拾遺—–依賴注入

基礎拾遺—–數據註解與驗證

基礎拾遺—–mongoDB操作

基礎拾遺—-RabbitMQ

基礎拾遺—CLR

基礎拾遺—-多線程

前言

我們知道c# 程序是自上而下的,但有的時候部分程序使用時間較長比如下載文檔什麼的。這是就可以用到線程。線程可以理解為是程序的執行路徑,每個線程都定義了一個獨特的控制流。如果您的應用程序涉及到複雜的和耗時的操作,那麼設置不同的線程執行路徑往往是有益的,每個線程執行特定的工作。

1.線程的生命周期

線程生命周期開始於 System.Threading.Thread 類的對象被創建時,結束於線程被終止或完成執行時。

下面列出了線程生命周期中的各種狀態:

未啟動狀態:當線程實例被創建但 Start 方法未被調用時的狀況。

就緒狀態:當線程準備好運行並等待 CPU 周期時的狀況。

不可運行狀態:下面的幾種情況下線程是不可運行的:

  已經調用 Sleep 方法

  已經調用 Wait 方法

  通過 I/O 操作阻塞

死亡狀態:當線程已完成執行或已中止時的狀況。

2.多線程的優缺點

2.1.優點

  1. 可以使用線程將代碼同其他代碼隔離,提高應用程序的可靠性。
  2. 可以使用線程來簡化編碼。
  3. 可以使用線程來實現併發執行。
  4. 可以提高CPU的利用率

2.2.缺點

  1. 線程開的越多,內存佔用越大。
  2. 協調和管理代碼的難度加大,需要CPU時間跟蹤線程。
  3. 線程之間對共享資源的訪問會相互影響,必須解決競用共享資源的問題。
  4. 銷毀線程需要了解可能發生的問題並對那些問題進行處理。

3.線程的實現

3.1.異步委託

關於委託基礎拾遺——委託、事件詳解這有詳細介紹,我們都知道調用委託Delegate()或者Delegate?.Invoke()。進行執行,但是主線程的代碼是從上至下進行執行的,那麼我們想要委託方法進行一個新的線程只需BeginInvoke生成異步方法調用即可。

3.3.1.實現

        public delegate void ThreadDelegate();
        static void MethodDelegata()
        {
            Console.WriteLine("MethodDelegata");
        }
        static void Main(string[] args)
        {
            ThreadDelegate d = MethodDelegata;
            //BeginInvoke 兩個參數一個是執行完后回調方法,一個是返回結果,如委託有參數載氣前方添加即可。
            d.BeginInvoke(null,null);
            Console.WriteLine("Main");
            Console.ReadKey();
        } 

執行結果如下

 3.1.1.獲取線程返回值

線程執行時有可能執行時間過長,如果我們要獲取線程的返回值,這是就需要不回線程的狀態和利用線程的回調方法。

  • 檢測等待線程狀態
       public delegate int ThreadDelegate(int i);
        static int MethodDelegata(int i)
        {
            Console.WriteLine("MethodDelegata" + i);
            Thread.Sleep(1000);
            return 100;

        }
        static void Main(string[] args)
        {
            ThreadDelegate d = MethodDelegata;
            //BeginInvoke 兩個參數一個是執行完后回調方法,一個是返回結果
            IAsyncResult ar = d?.BeginInvoke(1, null, null);//獲取線程執行狀態
            Console.WriteLine("Main");
            while (!ar.IsCompleted) {//線程是否已執行完成,未完成執行
                Console.WriteLine(".");
                Thread.Sleep(10);//減少線程監測頻率
            }
            int res = d.EndInvoke(ar);//獲取線程的返回值
            Console.WriteLine(res);
            Console.ReadKey();
        }

結果如下

·  

我們如果不用while 的方式去等待方法執行結束,可以  ar.AsyncWaitHandle.WaitOne(1000); 但我們預估執行時間如果小於實際執行時間的化,返回值就獲取不到了。

 bool isEnd = ar.AsyncWaitHandle.WaitOne(1000);
                if (isEnd)
            {
                int res = d.EndInvoke(ar);//獲取線程的返回值
                Console.WriteLine(res);

            }

View Code

  • 利用 d?.BeginInvoke(1, callBackobject) 回調方法
       public delegate int ThreadDelegate(int i);
        static int MethodDelegata(int i)
        {
            Console.WriteLine("MethodDelegata" + i);
            Thread.Sleep(1000);
            return 100;

        }
        static void Main(string[] args)
        {
            ThreadDelegate d = MethodDelegata;
            //BeginInvoke 兩個參數一個是執行完后回調方法,一個是返回結果
            IAsyncResult ar = d?.BeginInvoke(1, CallBack, d);//獲取線程執行狀態
            Console.WriteLine("Main");
         
            Console.ReadKey();
        }
        /// <summary>
        /// 結束回調方法
        /// </summary>
        /// <param name="ar"></param>
        private static void CallBack(IAsyncResult ar)
        {
            var obj=ar.AsyncState as ThreadDelegate;
            int res = obj.EndInvoke(ar);
            Console.WriteLine("線程結束,結果為:"+res);
        }

 我們通過lamda表達式優化一下上面的代碼

     static void Main(string[] args)
        {
            ThreadDelegate d = MethodDelegata;
            //BeginInvoke 兩個參數一個是執行完后回調方法,一個是返回結果
            //IAsyncResult ar = d?.BeginInvoke(1, CallBack, d);//獲取線程執行狀態
            d?.BeginInvoke(1, ar => {
                int res = d.EndInvoke(ar);
                Console.WriteLine("線程結束,結果為:" + res);
            }, null);
            Console.WriteLine("Main");
            Console.ReadKey();
        }

3.2.Thread 類

3.2.1.不帶參數

        static void MethodThread()
        {
            Console.WriteLine("MethodDelegata");//第二個參數最多執行時間
            Thread.Sleep(1000);
        }
        static void Main(string[] args)
        {
            Thread t = new Thread(MethodThread);//創建了thread 對象單位啟動
        //Thread t = new Thread(()=> { Console.WriteLine("MethodDelegata"); Thread.Sleep(1000);});//可直接用lamda表達式 
            t.Start();
            Console.WriteLine("Main");
            Console.ReadKey();
        }

3.2.2.帶參數 

Start(obj) 傳參:定義方法如果有參數必須object
        static void MethodThread(object s) { Console.WriteLine("MethodDelegata"); Thread.Sleep(1000); } static void Main(string[] args) { //創建了thread 對象單位啟動
            Thread t = new Thread(MethodThread); t.Start("wokao");//傳遞參數
            Console.WriteLine("Main"); Console.ReadKey(); }
對象傳參:定義存放數據和線程方法的類
   class Program
    {
       
        static void Main(string[] args)
        {
            //創建了thread 對象單位啟動
            ClassThead c = new ClassThead("1");
            Thread t = new Thread(c.MethodThread);
            t.Start();//傳遞參數
            Console.WriteLine("Main");
            Console.ReadKey();
        }

    }
    public class ClassThead
    {
        private string wr;
        public ClassThead(string s)
        {
            this.wr = s;
        }
        public  void MethodThread()
        {
            Console.WriteLine("MethodDelegata");
            Thread.Sleep(1000);

        }
    }

3.2.3 前台線程和後台線程

  1.     前台線程:只要存在有一個前台線程在運行,應用程序就在運行。
  2.     後台線程:應用程序關閉時,如果後台線程沒有執行完,會被強制性的關閉
  3.     默認情況下,用Thread類創建的線程是前台線程,線程池中的線程總是後台線程。
  4. thread.IsBackground = true; 設置為後台程序
   static void MethodThread()
        {
            Console.WriteLine("MethodDelegata");
            Thread.Sleep(10000);

            Console.ReadKey();

        }
        static void Main(string[] args)
        {
            Thread t = new Thread(MethodThread);
            t.IsBackground = true;//當main執行結束后,不管t是否執行結束程序都關閉
            t.Start();//傳遞參數
            Console.WriteLine("Main");
        }

thread.Abort() 終止線程的執行。調用這個方法,會拋出一個ThreadAbortException類型的異常。

thread.Join() 將當前線程睡眠,等待thread線程執行完,然後再繼續執行當前線程。

3.3.線程池threadPool

上面已經說了線程是為後台線程,在這多線程的操作推薦使用線程池線程而非新建線程。因為就算只是單純的新建一個線程,這個線程什麼事情也不做,都大約需要1M的內存空間來存儲執行上下文數據結構,並且線程的創建與回收也需要消耗資源,耗費時間。而線程池的優勢在於線程池中的線程是根據需要創建與銷毀,是最優的存在。但是這也有個問題,那就是線程池線程都是後台線程,主線程執行完畢后,不會等待後台線程而直接結束程序。

 //如果帶參數必須為object
        static void MethodThreadPool(object obj)
        {
            Console.WriteLine("MethodDelegata"+Thread.CurrentThread.ManagedThreadId);//當前線程id
            Thread.Sleep(1000);
         }
        static void Main(string[] args)
        {
            ThreadPool.QueueUserWorkItem(MethodThreadPool);// 必須帶參數
            ThreadPool.QueueUserWorkItem(MethodThreadPool);
            ThreadPool.QueueUserWorkItem(MethodThreadPool);
            ThreadPool.QueueUserWorkItem(MethodThreadPool);
            ThreadPool.QueueUserWorkItem(MethodThreadPool);
            Console.WriteLine("Main");
            Console.ReadKey();
        }

3.4. Task

  1. Task是架構在Thread之上的,也就是說任務最終還是要拋給線程去執行。
  2. Task跟Thread不是一對一的關係,比如開10個任務並不是說會開10個線程,這一點任務有點類似線程池,但是任務相比線程池有很小的開銷和精確的控制
  3. 可以將任務入隊到線程池中異步執行。
  4. 線程池入隊的任務無法取消
  5. 沒有回調方法,可以使用委託實現回調

3.4.1.任務的定義

方法1

var t1 = new Task(() => TaskMethod("Task 1"));
t1.Start();
Task.WaitAll(t1);//等待所有任務結束 

方法2

Task.Run(() => TaskMethod("Task 2"));

方法3

  Task.Factory.StartNew(() => TaskMethod("Task 3")); 直接異步的方法 
  //或者
  var t3=Task.Factory.StartNew(() => TaskMethod("Task 3"));
  Task.WaitAll(t3);//等待所有任務結束

案列

 static void Main(string[] args)
        {
            var t1 = new Task(() => TaskMethod("Task 1"));
            var t2 = new Task(() => TaskMethod("Task 2"));
            t2.Start();
            t1.Start();
            Task.WaitAll(t1, t2);
            Task.Run(() => TaskMethod("Task 3"));
            Task.Factory.StartNew(() => TaskMethod("Task 4"));
            //標記為長時間運行任務,則任務不會使用線程池,而在單獨的線程中運行。
            Task.Factory.StartNew(() => TaskMethod("Task 5"), TaskCreationOptions.LongRunning);

            Console.WriteLine("主線程執行業務處理.");
            //創建任務
            Task task = new Task(() =>
            {
                Console.WriteLine("使用System.Threading.Tasks.Task執行異步操作.");
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine(i);
                }
            });
            //啟動任務,並安排到當前任務隊列線程中執行任務(System.Threading.Tasks.TaskScheduler)
            task.Start();
            Console.WriteLine("主線程執行其他處理");
            task.Wait();
            Thread.Sleep(TimeSpan.FromSeconds(1));
            Console.ReadLine();
        }

        static void TaskMethod(string name)
        {
            Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
                name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
        }

View Code

3.4.2.async/await

async是contextual關鍵字,await是運算符關鍵字。

async/await 結構可分成三部分:

  1. 調用方法:該方法調用異步方法,然後在異步方法執行其任務的時候繼續執行;
  2. 異步方法:該方法異步執行工作,然後立刻返回到調用方法;
  3. await 表達式:用於異步方法內部,指出需要異步執行的任務。一個異步方法可以包含多個 await 表達式(不存在 await 表達式的話 IDE 會發出警告)。
class Program
    {
        async static void AsyncFunction()
        {
            await Task.Delay(1);
            Console.WriteLine("使用System.Threading.Tasks.Task執行異步操作.");
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(string.Format("AsyncFunction:i={0}", i));
            }
        }
        public static void Main()
        {
            Console.WriteLine("主線程執行業務處理.");
            AsyncFunction();
            Console.WriteLine("主線程執行其他處理");
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(string.Format("Main:i={0}", i));
            }
            Console.ReadLine();
        }
    }

4.線程爭用與死鎖

  class Program
    {
        static void ChangeState(object obj)
        {
            ClassThead c = obj as ClassThead;
            while (true)
            {
                c.MethodThread();
            }
        }
        //如果帶參數必須為object

        static void Main(string[] args)
        {
            ClassThead c = new ClassThead();
            Thread t = new Thread(ChangeState);
            t.Start(c);
            Console.WriteLine("Main");
            Console.ReadKey();
        }

    }
    public class ClassThead
    {
        private int state = 6;
        public void MethodThread()
        {
            state++;
            if (state == 6)
            {
                Console.WriteLine("MethodDelegata");
                Thread.Sleep(1000);
            }
            state = 6;
        }
    }

View Code

可以從上面的方法中看到執行結果為空,雖然他在執行但是state一直都是>6的。所以是不執行的。

但如果開啟兩個線程的結果是什麼呢?

是執行的因為多個線程有可能是在執行時另一個線程給他賦值了。所以我們就要給對象加鎖

        static void ChangeState(object obj)
        {
            ClassThead c = obj as ClassThead;
            while (true)
            {
                lock (c)
                {
                    c.MethodThread();
                }
            }
        }

注:但是有可能會出現線程爭用一直等待的情況,所以在編程過程設計好鎖的順序

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

【其他文章推薦】

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

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

※超省錢租車方案

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

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

聚甘新

測試人員遇到Android APP崩潰和無響應手足無措?,基於Python的Appium環境搭建合集

這2天,在測APP兼容性時,遇到APP奔潰閃退的情況。將問題反饋給開發后,開發自己調試后,沒有復現。由於又是遠程,base地不在一塊,我總不能把手機寄過去吧,那也太費事了。

所以就想到,提供明確的報錯日誌,讓開發定位問題,豈不是就很方便了,也解決了遠程的問題。

那如何抓取到Crash日誌呢,我又沒開發調試工具,也不可能在短時間內搭建一套開發環境。尋思答案后,最終得到了完美解決,且聽細細道來。

了解Crash

我們先來簡單了解下Crash:Crash,就是崩潰。anr(Application Not Responding — 程序無響應)是Crash的一種。程序正常運行中,可能會出現未捕獲到的異常,這就會造成崩潰。

常見Crash異常

NullPointerException  空指針

ClassCastException  類型轉換異常

IndexOutOfBoundsException  下標越界異常

ActivityNotFoundException Activity  未找到異常

IllegalStateException  非法狀態異常

ArrayIndexOutOfBoundsException  數組越界異常

SecurityException  安全異常

NoSuchMethodException  方法未找到異常

SQLException  操作數據庫異常

抓取奔潰和無響應日誌

對於開發人員來說,抓取日誌是很方便的,但對於測試人員來說,就不是太方便了。大多都是直接dos窗口下執行adb命令來抓取日誌,而每次都敲命令也是很麻煩。

所以通過adb程序與bat命令組合使用來抓取日誌,就要方便很多了,短短几秒鐘,可以輕鬆搞定日誌的抓取,期不期待。

環境準備

安裝JDK和ADB,這個安裝很簡單,可參見以前的博文,基於Python的Appium環境搭建合集。

bat文件製作

環境準備好后,就來寫bat文件了。

捕獲Crash異常的bat文件命令

命令參考如下,製作成logcat.bat文件,logcat.bat文件可以放置任意位置。注意:如果adb沒有配置到環境變量中,則需要將logcat.bat文件放到adb對應文件夾中。

@ECHO OFF
for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"

SET timeStamp=%dt:~0,4%-%dt:~4,2%-%dt:~6,2%_%dt:~8,2%-%dt:~10,2%-%dt:~12,2%
SET mutID=_mut

@ECHO ON
adb logcat -v time > .\"%mutID%_%timeStamp%_logcat.log"

pause

上述命令實現原理:該工具的原理是bat文件調用adb工具,將手機運行日誌拉到本地,並將實時日誌也記錄到本地。

當手機需要重現Crash、或者某一段時間內已經發生過Crash,點擊我們製作的bat文件,logcat文件中的命令會將手機的logcat日誌拉下來並實時記錄,直到你關閉cmd窗口。

然後在拉下來的txt中尋找FATAL關鍵字,附近上下文即為Crash日誌。

捕獲ANR異常的bat文件命令

anr:全稱為Application Not Responding,意思為程序無響應。

命令參考如下,製作成anr.bat文件,anr.bat文件可以放置任意位置。注意:如果adb沒有配置到環境變量中,則需要將anr.bat文件放到adb對應文件夾中。

@ECHO OFF
for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
SET timeStamp=%dt:~0,4%-%dt:~4,2%-%dt:~6,2%_%dt:~8,2%-%dt:~10,2%-%dt:~12,2%
SET mutID=_mut
@ECHO ON
adb pull data/anr/traces.txt traces_%timeStamp%.txt

實現原理與捕獲Crash異常是一樣的,只是該命令是針對發生anr的情況。

具體實踐

捕獲Crash異常具體用法:

①將android手機連接電腦,開啟開發者模式並允許usb調試;

②運行logcat.bat文件

③如果手機程序已經發生過crash,10秒后關閉cmd窗口;如果是想重現crash,則在手機端重現后即可關閉cmd窗口;

④在logcat.bat的同級目錄下會生成一份log文件,從文件中搜查FATAL關鍵字,便可找到崩潰代碼。

查看報錯日誌,報錯如下所示:

如上所示截圖,就是測試過程中,發生奔潰的日誌了,將日誌貼在bug里,既方便開發排查問題,又節約協作時間。

使用優點

使用bat文件捕獲日誌,有如下幾個有點:手機無需root;無需開發環境支持;方便保存、查找日誌;操作簡單。

以上就是捕獲報錯日誌的操作步驟了,希望對有需要的博友有所幫助。

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

【其他文章推薦】

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

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

※回頭車貨運收費標準

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

※超省錢租車方案

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

聚甘新

汎德和台達電合作,為北市增添電動車充電站

電源管理及散熱解決方案廠商台達電10日宣布,BMW台灣總代理汎德選定台達的電動車充電解決方案,並捐贈給台北市政府,將在今年3月底前,為台北市20處公用停車場設置40台具有網路通訊功能、IP55防塵防水與時尚精巧的外型設計的台達智能電動車交流充電機,為越來越多的BMW i系列以及搭配J1772 Type1規格的電動車提供更便捷的充電服務,同時也強化了台達在台灣的充電站普及率。

台達副總裁暨電源系統事業群總經理鄭安強調,台達十分樂意與夥伴攜手實現智能綠生活,很榮幸可以滿足BMW台灣總代理汎德對充電站的嚴謹要求,包括其高度可靠度以及智能化。事實上,台達電動車充電解決方案已獲得許多國家的肯定,並且在歐洲、台灣以及大中華區累積不少成功案例。

台達電指出,台達智能電動車交流充電機擁有網路通訊功能、內建RFID讀卡機與7kW電源容量,能協助系統管理廠商為電動車車主提供更便利的服務。另外,這款通過台灣CNS標準認證的交流充電機具有IP55防塵防水與防破壞(IK8)機體設計,除了相當堅固外,時尚精巧的外型設計更能節省空間,而台達充電站管理系統(Site Management System, SMS)能進行遠端支援及能源管理的功能,提升充電基地營運效率。

台達電並表示,台達電動車充電解決方案逐步於全球協助夥伴建立住宅及商業應用的高效、快速與方便的電動車充電設備。例如,台達的120kW直流超快速電動車充電機於挪威及瑞典的高速公路能夠同時提供四台電動車快充的服務。台達其它直流與交流技術也於香港國際機場、上海的商業大樓與台灣的日月潭旅客租車服務支援電動交通。

(本文內容由授權使用。)

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

【其他文章推薦】

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

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

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

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

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

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

第七屆中國國際新能源汽車論壇2017之電池前沿技術與前景

毋庸置疑,電池是新能源汽車的核心部件。當前比較主流的電池包括超級電容器、金屬氫化物鎳電池、鋰離子電池、燃料電池。超級電容器的特點是可承受瞬間大電流充放電,但儲電量低,不能驅動車輛長時間的使用;金屬氫化物電池具備大電流充放電能力,安全性好,但是比容量低,體積較大;鋰離子電池的電壓在這幾類電池中最高,比容量高,但它的是安全性、低溫性能差;燃料電池從去年開始走進更多人的視線,能量儲備充足,可快速補充燃料,但成本高,瞬間輸出能力差,致命的缺陷是不能進行能量的回饋,導致驅動的車輛不能只用燃料電池實現刹車時能量的回收。

站在“風口”的新能源汽車正在經歷“冰火兩重天”:一面是整個行業不斷高速擴張銷量加速,但另一面,作為新能源汽車“心臟”的動力電池供應卻出現不足,影響新能源整車產量從量上看,今年新能源產銷帶來的動力電池需求依然將進一步放大。但在下游原材料價格暴漲以及上游整車廠價格打壓的雙重壓力下,什麼樣的動力電池企業能夠實現突圍?業內人士預計,在短暫的火爆期之後,成本和技術導向或使得今年動力電池行業將進入洗牌期。而在霧霾圍城、PM2.5屢屢爆表的現狀下,發展並普及新能源汽車具有重要的現實意義。而因新能源汽車井噴所帶來的大量退役動力電池,引發了行業的未雨綢繆。

新能源汽車對於電池的需求量仍處於巨大的增長空間,並且總體而言,動力電池的安全性與新能源汽車的使用要求還存在一定差距,中國國際新能源汽車論壇—致力於打造全球規模最大,最國際化的新能源汽車論壇的第七屆大會攜手上海市嘉定區人民政府將會專門設立動力電池板塊,進行為期2天的技術探討及分享,屆時國內外知名的整車商,動力電池知名供應商及零部件企業高層領導等將前來分享各自對於目前動力市場的發展前景看法及介紹最前沿的技術,同時,也會側重於目前存在的難點——梯次利用及回收和技術方面進行更深層次的交流。

本屆大會將於2017年5月17-19日在上海舉辦,大會涉及七個論壇、頒獎典禮、研討會及晚宴。屆時將會有全球範圍內的整車製造商、電網電力公司、電池廠商、零部件供應商、核心技術提供商和政府官員等600多位行業人士一起,對新能源汽車產業面臨的挑戰,機遇與對策各方面進行為期三天更深層次並具有建設和戰略性的探討,期待您的參與。

會議結構

若您對峰會有更多要求,請撥打021-6045 1760與我們聯繫,謝謝理解和支持!
我們期待與貴單位一起出席於2017年5月17-19日在上海舉辦的第七屆中國國際新能源汽車論壇2017,以利決策!
想瞭解詳細內容,請登陸官方網站:
連絡人:Summer(謝清)
電話:+86 21-6045 1766
傳真:+86 21-6047 5887
郵箱: market@ourpolaris.com

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

【其他文章推薦】

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

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

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

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

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

Nissan 無人駕駛電動車預計2020量產

日本汽車廠商Nissan 宣布,該公司歐洲的首次無人駕駛汽車測試將在倫敦進行,2017 年下半年有望在歐洲市場推出配置半自動駕駛的SUV,這一車款已經在日本市場上市。

Nissan 對於無人駕駛技術的研發非常重視,同時在應用方面表現得非常謹慎。此次在倫敦進行測試的無人駕駛車採用的技術短期內不會應用在量產車上,測試的將是一輛LEAF 電動車,配置了雷達、鐳射和鏡頭,預期在2020 年會應用到量產車上。Nissan 會邀請監管機構和政府工作人員來體驗無人駕駛車,測試的過程中車內會安排司機監控,以避免意外狀況的發生,測試不會向大眾開放。

Nissan 並不是第一家在英國進行無人駕駛公共道路測試的公司,Volvo 將在英國的公共道路上進行100 台無人駕駛汽車的測試。

汽車廠商認為無人駕駛技術能夠有效地提升乘車的安全性,減少車禍的死亡率,但這一技術的推廣仍面臨許多挑戰,公眾對於無人駕駛技術存在諸多質疑。

據倫敦經濟學院最新報告顯示,大約有55% 的英國司機表示在無人駕駛汽車中非常不自在,83% 的司機更擔心無人駕駛汽車發生故障,85% 的司機認為無人駕駛系統無法跟人互動。

(合作媒體:。圖片出處:)

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

【其他文章推薦】

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

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

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

※回頭車貨運收費標準

傳亞光供應車載鏡頭於美系電動車供應鏈

市場傳出,光學零件大廠亞光車載鏡頭於 2016 年第四季打進美國電動車大廠供應鏈,去年11月已開始出貨,單月出貨量約2-3萬顆, 2017年出貨則可望進一步放量成長,為營運增添動能。

對此,亞光董事長賴以仁表示,不評論客戶訂單,但他強調,今年在包括車用、虛擬實境 (VR) 等運動攝影機方面,訂單表現都不錯,消費型相機的需求亦有回溫,預估今年營收及獲利表現可望優於去年;同時,今年美國 CES 展中受矚目的先進駕駛輔助系統 (ADAS),亞光布局雷射測距應用於瞄準儀的時間已久,而在雷射測距及 HUD(抬頭顯示器)方面,也都是 ADAS 應用的重要零組件。

據悉,亞光出貨美國電動車廠的車載鏡頭主要為雷射測距,用於自動駕駛系統;除美國電動車市場外,亞光的車載鏡頭也間接切入歐洲車廠,今年布局重點包括 ADAS 等重要零組件。

亞光去年全年營收 179 億元,年減 1.6%,惟受惠產品組合優化,獲利優於營收表現,其去年前三季稅後淨利 2.97 億元,每股盈餘1.06元,已優於 2015 年全年表現。

(本文內容由授權使用)

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

【其他文章推薦】

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

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

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

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

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

※超省錢租車方案