整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          javaScript 函數形參與實參

          javaScript 函數形參與實參

          函數名后面的括號中的內容是一種變量,這個變量叫做參數

          參數是指由外部傳入到函數中的變量,僅作為變量使用,但是該變量可以是任何內容,包括函數。被傳入的參數作為私有變量使用,可以被覆蓋掉。外部傳入的參數可以節省全局變量的定義,甚至保證函數中的部分變量的獨立性。

          1、參數名起名規則和變量名類似,但是有時候可以使用下劃線來起頭

          2、如果有多個參數時,就需要使用逗號分隔

          形參:一個接收實參的變量

          function abc(n,m){
                      console.log(n,m);
                  }

          上述代碼中n、m為形參,這兩個變量的范圍是僅在當前函數語句塊中,在函數外不能調用形參。

          實參:真實的數值、字符串

          abc(5,6);

          在調用函數時,傳入指定的參數為實參,這里5,6為實參。參數傳值是按照順序復賦值的,不能顛倒。

          不填入參數也可以執行,但是這種方式就相當于給形參定義值為undefined 。如abc();

          如果只填入一個值,就表示第一個賦值10,第二個仍然賦值undefined 。如abc(10).

          如果傳入多值,多傳入的參數不會被接受,如abc(5,6,7),這里7是不會被調用的。

          代碼進行單元測試是幾乎每個軟件工程師都要完成的工作。本文以C++語言為基礎,講解如何進行單元測試并生成測試報告。

          前言

          測試是軟件開發過程中一個必須的環節,測試確保軟件的質量符合預期。

          對于工程師自己來說,單元測試也是提升自信心的一種方式。

          直接交付沒有經過測試的代碼是不太好的,因為這很可能會浪費整個團隊的時間,在一些原本早期就可以發現的問題上。而單元測試,就是發現問題一個很重要的環節。

          本文以C++語言為基礎,講解如何進行單元測試并生成測試報告。

          在工具上,我們會使用下面這些:

          • GCC
          • CMake
          • Google Test
          • gcov
          • lcov

          演示項目

          為了方便本文的講解,我專門編寫了一個演示項目作為代碼示例。

          演示項目的源碼可以在我的Github上獲取:paulQuei/gtest-and-coverage。

          你可以通過下面幾條命令下載和運行這個項目:

          git clone https://github.com/paulQuei/gtest-and-coverage.git
          cd gtest-and-coverage
          ./make_all.sh

          要運行這個項目,你的機器上必須先安裝好前面提到的工具。如果沒有,請閱讀下文以了解如何安裝它們。

          如果你使用的是Mac系統,下文假設你的系統上已經安裝了brew包管理器。如果沒有,請通過下面這條命令安裝它:

          /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

          項目結構

          演示項目的目錄結構如下:

          .
          ├── CMakeLists.txt
          ├── googletest-release-1.8.1.zip
          ├── include
          │   └── utility.h
          ├── make_all.sh
          ├── src
          │   └── utility.cpp
          └── test
              └── unit_test.cpp

          這里演示的內容是:以測試一個我們要提供的軟件庫為例,講解如何對其進行單元測試并生成測試報告。

          為了簡單起見,這個軟件庫只有一個頭文件和一個實現文件。

          當然,在實際上的項目中,一個軟件庫會通常包含更多的文件,不過這并不影響我們要說明的問題。

          演示項目中的文件說明如下:

          文件名稱說明make_all.sh入口文件,會執行:編譯,測試和生成報告等所有工作CMakeLists.txt項目的編譯文件googletest-release-1.8.1.zipgoogle test源碼壓縮包utility.h待測試的軟件庫的頭文件utility.cpp待測試的軟件庫的實現文件unit_test.cpp對軟件庫進行單元測試的代碼

          測試環境

          演示項目在如下的環境中測試過。

          • MacBook Pro操作系統:macOS Mojave 10.14.1編譯器:Apple LLVM version 10.0.0 (clang-1000.11.45.2)CMake:cmake version 3.12.1Google Test: 1.8.1lcov: lcov version 1.13
          • Ubuntu操作系統:Ubuntu 16.04.5 LTS編譯器:gcc (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609CMake:cmake version 3.5.1Google Test:1.8.1lcov:lcov version 1.12

          關于CMake

          為了簡化編譯的過程,這里使用CMake作為編譯工具。關于CMake的更多內容請參見請官網:https://cmake.org。

          關于如何安裝CMake請參見這里:Installing CMake。

          另外,你也可以通過一條簡單的命令來安裝CMake:

          Mac系統:

          brew install cmake

          Ubuntu系統

          sudo apt install cmake

          由于篇幅所限,這里不打算對CMake做過多講解,讀者可以訪問其官網或者在網絡上搜尋其使用方法。

          這里僅僅對演示項目中用到的內容做一下說明。演示項目中的CMakeLists.txt內容如下:

          cmake_minimum_required(VERSION 2.8.11) ①
          project(utility) ②
          
          set(CMAKE_CXX_STANDARD 11) ③
          
          set(GTEST googletest-release-1.8.1) ④
          include_directories("./include" "${GTEST}/googletest/include/")
          link_directories("build/gtest/googlemock/gtest/")
          
          SET(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} --coverage") ⑤
          
          add_library(${CMAKE_PROJECT_NAME}_lib src/utility.cpp) ⑥
          
          add_executable(unit_test test/unit_test.cpp) ⑦
          target_link_libraries(unit_test ${CMAKE_PROJECT_NAME}_lib gtest gtest_main pthread) ⑧

          以編號為序,這段代碼說明如下:

          1. 設置使用的CMake最低版本號為2.8.11。
          2. 指定項目的名稱為”utility”,項目名稱可以通過${CMAKE_PROJECT_NAME}進行引用。
          3. 指定使用C++11。
          4. 這里的三行是編譯google test,并將其頭文件路徑和編譯結果的庫文件路徑添加到環境中。因為后面在編譯單元測試代碼的時候需要用到。
          5. 添加--coverage到編譯器flag中,這個參數是很重要的,因為這是生成代碼覆蓋率所必須的。關于該編譯參數的說明見這里:Program Instrumentation Options。
          6. 編譯我們的軟件庫,這里將生成libutility_lib.a庫文件。
          7. 編譯單元測試的可執行文件。
          8. 單元測試的可執行文件需要鏈接我們開發的軟件庫以及google test的庫。另外,google test依賴了pthread,所以這個庫也需要。

          關于測試

          軟件測試有很多種分類方式。從測試的級別來說,可以大致分為:

          • 單元測試
          • 集成測試
          • 系統測試

          這其中,單元測試是最局部和具體的。它通常需要對代碼中的每一個類和函數進行測試。

          單元測試通常由開發者完成,需要針對代碼邏輯進行測試。所以它是一種白盒測試。

          關于xUnit

          xUnit是幾種單元測試框架的總稱。最早源于Smalltalk的單元測試框架SUnit,它是由Kent Beck開發的。

          除此之外,還有針對Java語言的JUnit,針對R語言的RUnit。

          在本文中,我們使用Google開發的xUnit框架:Google Test。

          Google Test介紹

          Google Test的項目主頁在Github上:Github: Google Test。

          實際上,這個項目中同時包含了GoogleTest和GoogleMock兩個工具,本文中我們只會講解第一個。

          Google Test支持的操作系統包含下面這些:

          • Linux
          • Mac OS X
          • Windows
          • Cygwin
          • MinGW
          • Windows Mobile
          • Symbian

          目前有很多的項目都使用了Google Test,例如下面這些:

          • Chromium projects
          • LLVM
          • Protocol Buffers
          • OpenCV
          • tiny-dnn

          編譯Google Test

          關于如何編譯Google Test請參見這里:Generic Build Instructions。

          為了便于讀者使用,我們在演示項目中包含了Google Test 1.8.1的源碼壓縮包。并且在CMake文件中,同時包含了Google Test的編譯和使用配置工作。

          如果使用演示項目,讀者將不需要手動處理Google Test的編譯和安裝工作。

          使用Google Test

          演示項目代碼說明

          為了便于下文說明,演示項目中包含了幾個簡單的函數。

          可以從這里下載源碼以便查看其中的內容:paulQuei/gtest-and-coverage。

          演示項目中的軟件庫包含一個頭文件和一個實現文件。頭文件內容如下:

          // utility.h
          
          #ifndef INCLUDE_UTILITY_
          #define INCLUDE_UTILITY_
          
          enum CalcType {
              ADD,
              MINUS,
              MULTIPLE,
              DIVIDE
          };
          
          class Utility {
          public:
              int ArithmeticCalculation(CalcType op, int a, int b);
          
              double ArithmeticCalculation(CalcType op, double a, double b);
          
              bool IsLeapYear(int year);
          };
          
          #endif

          這個頭文件說明如下:

          • 頭文件包含了三個函數,前兩個用來做int和double類型的四則運算。最后一個判斷輸入的年份是否是閏年。
          • 當然,在實際的工程中,前兩個函數合并實現為一個泛型函數更為合適。但這里之所以分成兩個,是為了查看代碼覆蓋率所用。
          • 關于閏年說明如下:能被4整除但不能被100整除的年份為普通閏年。能被100整除,也同時能被400整除的為世紀閏年。其他都不是閏年。例如:1997年不是閏年,2000年是閏年,2016年是閏年,2100不是閏年。

          這三個函數的實現也不復雜:

          // utility.cpp
          
          #include "utility.h"
          
          #include <iostream>
          #include <limits>
          
          using namespace std;
          
          int Utility::ArithmeticCalculation(CalcType op, int a, int b) {
              if (op==ADD) {
                  return a + b;
              } else if (op==MINUS) {
                  return a - b;
              } else if (op==MULTIPLE) {
                  return a * b;
              } else {
                  if (b==0) {
                      cout << "CANNO Divided by 0" << endl;
                      return std::numeric_limits<int>::max();
                  }
                  return a / b;
              }
          }
          
          double Utility::ArithmeticCalculation(CalcType op, double a, double b) {
              if (op==ADD) {
                  return a + b;
              } else if (op==MINUS) {
                  return a - b;
              } else if (op==MULTIPLE) {
                  return a * b;
              } else {
                  if (b==0) {
                      cout << "CANNO Divided by 0" << endl;
                      return std::numeric_limits<double>::max();
                  }
                  return a / b;
              }
          }
          
          bool Utility::IsLeapYear(int year) {
              if (year % 100==0 && year % 400==0) {
                  return true;
              }
              if (year % 100 !=0 && year % 4==0) {
                  return true;
              }
              return false;
          }

          開始測試

          接下來我們就要對上面這些代碼進行測試了。

          要使用Google Test進行測試,整個過程也非常的簡單。只要進行下面三部:

          1. 創建一個測試用的cpp文件
          2. 為上面這個測試用的cpp文件編寫Makefile(或者CMake文件)。同時鏈接:待測試的軟件庫gtest庫gtest_main庫pthread庫(Google Test使用了這個庫所以需要)
          3. 編寫測試代碼,編譯并運行測試的可執行程序。

          并且,測試代碼寫起來也非常的簡單,像下面這樣:

          #include "utility.h"
          
          #include "gtest/gtest.h"
          
          TEST(TestCalculationInt, ArithmeticCalculationInt) {
              Utility util;
              EXPECT_EQ(util.ArithmeticCalculation(ADD, 1, 1), 2);
              EXPECT_EQ(util.ArithmeticCalculation(MINUS, 2, 1), 1);
              EXPECT_EQ(util.ArithmeticCalculation(MULTIPLE, 3, 3), 9);
              EXPECT_EQ(util.ArithmeticCalculation(DIVIDE, 10, 2), 5);
              EXPECT_GT(util.ArithmeticCalculation(DIVIDE, 10, 0), 999999999);
          }

          是的,就是這么簡單的幾行代碼,就對整數四則運算的函數進行了測試。

          TEST后面所包含的內容稱之為一條case,通常我們會為每個函數創建一個獨立的case來進行測試。一個測試文件中可以包含很多條case。同時,一條case中會包含很多的判斷(例如EXPECT_EQ...)。

          注意:在做單元測試的時候,保證每條case是獨立的,case之間沒有前后依賴關系是非常重要的。

          當然,測試代碼中包含的判斷的多少將影響測試結果的覆蓋率。所以在編寫每條case的時候,我們需要仔細思考待測試函數的可能性,有針對性的進行測試代碼的編寫。

          這段代碼應該很好理解,它分別進行了下面這些測試:

          • 1 + 1=2
          • 2 – 1=1
          • 3 x 3=9
          • 10 / 2=5
          • 10 / 0 > 999999999

          你可能會發現,這段代碼里面甚至沒有main函數。它也依然可以生成一個可執行文件。這就是我們鏈接gtest_main所起的作用。

          在實際的測試過程中,你想判斷的情況可能不止上面這么簡單。下面我們來看看Google Test還能做哪些測試。

          測試判斷

          Google Test對于結果的判斷,有兩種形式:

          • ASSERT_*:這類判斷是Fatal的。一旦這個判斷出錯,則直接從測試函數中返回,不會再繼續后面的測試。
          • EXPECT_*:這類判斷是Nonfatal的。它的效果是,如果某個判斷出錯,則輸出一個錯誤信息,但是接下來仍然會繼續執行后面的測試。

          可以進行的判斷方法主要有下面這些:

          布爾判斷

          FatalNonfatal說明ASSERT_TRUE(condition)EXPECT_TRUE(condition)判斷 condition 為 trueASSERT_FALSE(condition)EXPECT_FALSE(condition)判斷 condition 為 false

          二進制判斷

          FatalNonfatal說明ASSERT_EQ(expected, actual)EXPECT_EQ(expected, actual)判斷兩個數值相等ASSERT_NE(val1, val2)EXPECT_NE(val1, val2)val1 !=val2ASSERT_LT(val1, val2)EXPECT_LT(val1, val2)val1 < val2ASSERT_LE(val1, val2)EXPECT_LE(val1, val2)val1 <=val2ASSERT_GT(val1, val2)EXPECT_GT(val1, val2)val1 > val2ASSERT_GE(val1, val2)EXPECT_GE(val1, val2)val1 >=val2

          說明:

          • EQ:EQual
          • NE:Not Equal
          • LT:Less Than
          • LE:Less Equal
          • GT:Greater Than
          • GE:Greater Equal

          字符串判斷

          FatalNonfatal說明ASSERT_STREQ(expected, actual)EXPECT_STREQ(expected, actual)兩個C string相同ASSERT_STRNE(str1, str2)EXPECT_STRNE(str1, str2)兩個C string不相同ASSERT_STRCASEEQ(exp, act)EXPECT_STRCASEEQ(exp, act)忽略大小寫,兩個C string相同ASSERT_STRCASENE(str1, str2)EXPECT_STRCASENE(str1, str2)忽略大小寫,兩個C string不相同

          浮點數判斷

          FatalNonfatal說明ASSERT_FLOAT_EQ(exp, act)EXPECT_FLOAT_EQ(exp, act)兩個float數值相等ASSERT_DOUBLE_EQ(exp, act)EXPECT_DOUBLE_EQ(exp, act)兩個double數值相等ASSERT_NEAR(val1, val2, abs_err)EXPECT_NEAR(val1, val2, abs_err)val1和val2的差距不超過abs_err

          異常判斷

          FatalNonfatal說明ASSERT_THROW(stmt, exc_type)EXPECT_THROW(stmt, exc_type)stmt拋出了exc_type類型的異常ASSERT_ANY_THROW(stmt)EXPECT_ANY_THROW(stmt)stmt拋出了任意類型的異常ASSERT_NO_THROW(stmt)EXPECT_NO_THROW(stmt)stmt沒有拋出異常

          Test Fixture

          在某些情況下,我們可能希望多條測試case使用相同的測試數據。例如,我們的演示項目中,每條case都會需要創建Utility對象。

          有些時候,我們要測試的對象可能很大,或者創建的過程非常的慢。這時,如果每條case反復創建這個對象就顯得浪費資源和時間了。此時,我們可以使用Test Fixture來共享測試的對象。

          要使用Test Fixture我們需要創建一個類繼承自Google Test中的::testing::Test。

          還記得我們前面說過,我們要盡可能的保證每條測試case是互相獨立的。但是,當我們在多條case之間共享有狀態的對象時,就可能出現問題。

          例如,我們要測試的是一個隊列數據結構。有的case會向隊列中添加數據,有的case會從隊列中刪除數據。case執行的順序不同,則會導致Queue中的數據不一樣,這就可能會影響case的結果。

          為了保證每條case是獨立的,我們可以在每條case的執行前后分別完成準備工作和清理工作,例如,準備工作是向隊列中添加三個數據,而清理工作是將隊列置空。

          這兩項重復性的工作可以由::testing::Test類中的Setup和TearDown兩個函數來完成。

          我們演示用的Utility類是無狀態的,所以不存在這個問題。因此,這里我們僅僅在Setup和TearDown兩個函數中打印了一句日志。

          使用Test Fixture后,我們的代碼如下所示:

          class UtilityTest : public ::testing::Test {
          
          protected:
          
          void SetUp() override {
              cout << "SetUp runs before each case." << endl;
          }
          
          void TearDown() override {
              cout << "TearDown runs after each case." << endl;
          }
          
          Utility util;
          
          };

          這段代碼說明如下:

          1. Setup和TearDown兩個函數標記了override以確認是重寫父類中的方法,這是C++11新增的語法。
          2. 我們的Utility類是無狀態的,因此Setup和TearDown兩個函數中我們僅僅打印日志以便確認。
          3. 將Utility util設置為protected以便測試代碼中可以訪問。(從實現上來說,測試case的代碼是從這個類繼承的子類,當然,這個關系是由Google Test工具完成的)。

          要使用這里定義的Test Fixture,測試case的代碼需要將開頭的TEST變更為TEST_F。

          這里_F就是Fixture的意思。

          使用TEST_F的case的代碼結構如下:

          TEST_F(TestCaseName, TestName) {
            ... test body ...
          }

          這里的TestCaseName必須是Test Fixture的類名。

          所以我們的測試代碼寫起來是這樣:

          TEST_F(UtilityTest, ArithmeticCalculationDouble) {
              EXPECT_EQ(util.ArithmeticCalculation(ADD, 1.1, 1.1), 2.2);
          }
          
          TEST_F(UtilityTest, ArithmeticCalculationIsLeapYear) {
              EXPECT_FALSE(util.IsLeapYear(1997));
              EXPECT_TRUE(util.IsLeapYear(2000));
              EXPECT_TRUE(util.IsLeapYear(2016));
              EXPECT_FALSE(util.IsLeapYear(2100));
          }

          我們針對ArithmeticCalculation方法故意只進行了一種情況的測試。這是為了最終生成代碼覆蓋率所用。

          運行測試

          編寫完單元測試之后,再執行編譯工作便可以運行測試程序以查看測試結果了。

          測試的結果像下面這樣:

          如果測試中包含了失敗的case,則會以紅色的形式輸出。同時,會看到失敗的case所處的源碼行數,這樣可以很方便的知道哪一個測試失敗了,像下面這樣:

          只想有選擇性的跑部分case,可以通過--gtest_filter參數進行過濾,這個參數支持*通配符。

          像下面這樣:

          $ ./build/unit_test --gtest_filter=*ArithmeticCalculationInt
          Running main() from googletest/src/gtest_main.cc
          Note: Google Test filter=*ArithmeticCalculationInt
          [==========] Running 1 test from 1 test case.
          [----------] Global test environment set-up.
          [----------] 1 test from TestCalculationInt
          [ RUN      ] TestCalculationInt.ArithmeticCalculationInt
          CANNO Divided by 0
          [       OK ] TestCalculationInt.ArithmeticCalculationInt (0 ms)
          [----------] 1 test from TestCalculationInt (0 ms total)
          
          [----------] Global test environment tear-down
          [==========] 1 test from 1 test case ran. (0 ms total)
          [  PASSED  ] 1 test.

          如果想要更好的理解這些內容。請讀者下載演示項目之后完成下面這些操作:

          在utility.h和utility.cpp中添加一些新的函數。在新添加的函數中故意包含一個bug。為新添加的函數編寫測試代碼,并測試出函數中包含的bug。

          代碼覆蓋率

          在進行單元測試之后,我們當然希望能夠直觀的看到我們的測試都覆蓋了哪些代碼。

          理論上,如果我們能做到100%的覆蓋我們的所有代碼,則可以說我們的代碼是沒有Bug的。

          但實際上,100%的覆蓋率要比想象得困難。對于大型項目來說,能夠達到80% ~ 90%的語句覆蓋率就已經很不錯了。

          覆蓋率的類型

          先來看一下,當我們在說“覆蓋率”的時候我們到底是指的什么。

          實際上,代碼覆蓋率有下面幾種類型:

          • 函數覆蓋率:描述有多少比例的函數經過了測試。
          • 語句覆蓋率:描述有多少比例的語句經過了測試。
          • 分支覆蓋率:描述有多少比例的分支(例如:if-else,case語句)經過了測試。
          • 條件覆蓋率:描述有多少比例的可能性經過了測試。

          這其中,函數覆蓋率最為簡單,就不做說明了。

          語句覆蓋率是我們最常用的。因為它很直觀的對應到我們寫的每一行代碼。

          而分支覆蓋率和條件覆蓋率可能不太好理解,需要做一下說明。

          以下面這個C語言函數為例:

          int foo (int x, int y) {
              int z=0;
              if ((x > 0) && (y > 0)) {
                  z=x;
              }
              return z;
          }

          這個函數中包含了一個if語句,因此if語句成立或者不成立構成了兩個分支。所以如果只測試了if成立或者不成立的其中之一,其分支覆蓋率只有 1/2=50%。

          而條件覆蓋率需要考慮每種可能性的情況。

          對于if (a && b)這樣的語句,其一共有四種可能的情況:

          1. a=true, b=true
          2. a=true, b=false
          3. a=false, b=true
          4. a=false, b=false

          請讀者思考一下:對于三層if嵌套,每個if語句包含三個布爾變量的代碼,如果要做到100%的條件覆蓋率,一共要測試多少種情況。

          很顯示,在編寫代碼的時候,盡可能的減少代碼嵌套,并且簡化邏輯運算是一項很好的習慣。

          便于測試的代碼也是便于理解和維護的,反之則反。

          有了這些概念之后,我們就可以看懂測試報告中的覆蓋率了。

          gcov

          gcov是由GCC工具鏈提供的代碼覆蓋率生成工具。它可以很方便的和GCC編譯器配合使用。

          通常情況下,安裝好GCC工具鏈,也就同時包含了gcov命令行工具。

          對于代碼覆蓋率工具所做的工作,可以簡單的理解為:標記一次運行過程中,哪些代碼被執行過,哪些沒有執行。

          因此,即便沒有測試代碼,直接運行編譯產物也可以得到代碼的覆蓋率。只不過,通常情況下這樣得到的覆蓋率較低罷了。

          使用

          這里我們以另外一個簡單的代碼示例來說明gcov的使用。

          這段代碼如下:

          // test.c
          
          #include <stdio.h>
          
          int main (void) {
          
            for (int i=1; i < 10; i++) {
                if (i % 3==0)
                  printf ("%d is divisible by 3\n", i);
                if (i % 11==0)
                  printf ("%d is divisible by 11\n", i);
            }
          
            return 0;
          }

          這是一個僅僅包含了main函數的c語言代碼,main函數的邏輯也很簡單。

          我們將這段代碼保存到文件test.c。

          要通過gcov生成代碼覆蓋率。需要在編譯時,增加參數--coverage:

          gcc --coverage test.c

          --coverage等同于編譯參數-fprofile-arcs -ftest-coverage以及在鏈接時增加-lgcov。

          此處的編譯結果除了得到可執行文件a.out,還會得到一個test.gcno文件。該文件包含了代碼與行號的信息,在生成覆蓋率時會需要這個文件。

          很顯然,帶--coverage編譯參數得到的編譯產物會比不帶這個參數要包含更多的信息,因此編譯產物會更大。所以這個參數只適合在需要生成代碼覆蓋率的時候才加上。對于正式發布的編譯產物,不應該添加這個編譯參數。

          當我們執行上面編譯出來的可執行文件a.out時,我們還會得到每個源碼文件對應的gcda后綴的文件。由test.gcno和test.gcda這兩個文件,便可以得到代碼的覆蓋率結果了。

          關于這兩個文件的說明請參見這里:Brief description of gcov data files

          只需要通過gcov指定源文件的名稱(不需要帶后綴):gcov test,便可以得到包含覆蓋率的結果文件 test.c.gcov了。

          回顧一下我們剛剛的操作內容:

          $ gcc --coverage test.c
          $ ll
          total 72
          -rwxr-xr-x  1 Paul  staff    26K 11 10 14:41 a.out
          -rw-r--r--  1 Paul  staff   240B 11 10 14:41 test.c
          -rw-r--r--  1 Paul  staff   720B 11 10 14:41 test.gcno
          $ ./a.out 
          3 is divisible by 3
          6 is divisible by 3
          9 is divisible by 3
          $ ll
          total 80
          -rwxr-xr-x  1 Paul  staff    26K 11 10 14:41 a.out
          -rw-r--r--  1 Paul  staff   240B 11 10 14:41 test.c
          -rw-r--r--  1 Paul  staff   212B 11 10 14:42 test.gcda
          -rw-r--r--  1 Paul  staff   720B 11 10 14:41 test.gcno
          $ gcov test
          File 'test.c'
          Lines executed:85.71% of 7
          test.c:creating 'test.c.gcov'
          
          $ ll
          total 88
          -rwxr-xr-x  1 Paul  staff    26K 11 10 14:41 a.out
          -rw-r--r--  1 Paul  staff   240B 11 10 14:41 test.c
          -rw-r--r--  1 Paul  staff   623B 11 10 14:42 test.c.gcov
          -rw-r--r--  1 Paul  staff   212B 11 10 14:42 test.gcda
          -rw-r--r--  1 Paul  staff   720B 11 10 14:41 test.gcno

          我們可以cat test.c.gcov一下,查看覆蓋率的結果:

                  -:    0:Source:test.c
                  -:    0:Graph:test.gcno
                  -:    0:Data:test.gcda
                  -:    0:Runs:1
                  -:    0:Programs:1
                  -:    1:// test.c
                  -:    2:
                  -:    3:#include <stdio.h>
                  -:    4:
                  -:    5:int main (void) {
                  -:    6:
                 20:    7:  for (int i=1; i < 10; i++) {
                  9:    8:      if (i % 3==0)
                  3:    9:        printf ("%d is divisible by 3\n", i);
                  9:   10:      if (i % 11==0)
              #####:   11:        printf ("%d is divisible by 11\n", i);
                  9:   12:  }
                  -:   13:
                  1:   14:  return 0;
                  -:   15:}

          這個結果應該還是很容易理解的,最左邊一列描述了代碼的覆蓋情況:

          • -: 表示該行代碼被覆蓋了
          • 整數: 表示被執行的次數
          • #####:表示該行沒有被覆蓋

          lcov

          gcov得到的結果是本文形式的。但很多時候,我們可能希望得到更加美觀和便于瀏覽的結果。

          此時就可以使用lcov了。

          lcov是gcov工具的圖形前端。它收集多個源文件的gcov數據,并生成描述覆蓋率的HTML頁面。生成的結果中會包含概述頁面,以方便瀏覽。

          lcov支持我們前面提到的所有四種覆蓋率。

          這個鏈接是lcov生成的報告樣例:lcov – code coverage report。

          安裝

          lcov并非包含在GCC中,因此需要單獨安裝。

          Mac系統

          brew install lcov

          Ubuntu系統

          sudo apt install lcov

          使用

          對于lcov的使用方法可以通過下面這條命令查詢:

          lcov --help

          通過輸出我們可以看到,這個命令的參數有簡短(例如-c)和完整(例如--capture)兩種形式,其作用是一樣的。

          這里主要關注的下面這幾個參數:

          • -c 或者 --capture 指定從編譯產物中收集覆蓋率信息。
          • -d DIR 或者 --directory DIR 指定編譯產物的路徑。
          • -e FILE PATTERN 或者 --extract FILE PATTERN 從指定的文件中根據PATTERN過濾結果。
          • -o FILENAME 或者 --output-file FILENAME 指定覆蓋率輸出的文件名稱。

          另外還有需要說明的是:

          • lcov默認不會打開分支覆蓋率,因此我們還需要增加這個參數來打開分支覆蓋率的計算:--rc lcov_branch_coverage=1
          • lcov輸出的仍然是一個中間產物,我們還需要通過lcov軟件包提供的另外一個命令genhtml來生成最終需要的html格式的覆蓋率報告文件。同樣的,為了打開分支覆蓋率的計算,我們也要為這個命令增加--rc lcov_branch_coverage=1參數

          最后,make_all.sh腳本中包含的相關內容如下:

          COVERAGE_FILE=coverage.info
          REPORT_FOLDER=coverage_report
          lcov --rc lcov_branch_coverage=1 -c -d build -o ${COVERAGE_FILE}_tmp
          lcov --rc lcov_branch_coverage=1  -e ${COVERAGE_FILE}_tmp "*src*" -o ${COVERAGE_FILE}
          genhtml --rc genhtml_branch_coverage=1 ${COVERAGE_FILE} -o ${REPORT_FOLDER}

          這段代碼從我們前面編譯的結果中收集覆蓋率結果,并將結果輸出到coverage.info_tmp文件中。但是這里面會包含非項目源碼的覆蓋率(例如google test),所以我們又通過另外一條命令來指定”src”文件夾進行過濾。最后,通過genhtml得到html格式的報告。

          可以通過瀏覽器查看覆蓋率報告的結果,像下面這樣:

          從這個報告的首頁,我們已經可以看到代碼的語句覆蓋率(Lines),函數覆蓋率(Functions)以及分支覆蓋率(Branches)。而對于條件覆蓋率可以從詳細頁面中看到。如下圖所示:

          在上面這張圖中,我們可以看到哪些代碼被覆蓋了,哪些沒有。而對于對于if-else之類的語句,也能很清楚的看到條件覆蓋率的覆蓋情況。例如,對于代碼的27行,只覆蓋了if成立時的情況,沒有覆蓋if不成立時的情況。

          更進一步

          本文中,我們已經完整的完成了從編寫單元測試到覆蓋率生成的整個過程。

          但實際上,對于這項工作我們還可以做得更多一些。例如下面這兩項工作:

          使用Google Mock

          Google Mock是Google Test的擴展,用于編寫和使用C++ Mock類。

          在面向對象的編程中,Mock對象是模擬對象,它們以預先設定的方式模仿真實對象的行為。程序員通常會創建一個Mock對象來測試某個其他對象的行為,這與汽車設計師使用碰撞測試假人來模擬人類在車輛碰撞中的動態行為的方式非常相似。

          關于Google Mock的更多內容請參見:Google Mock的文檔。

          持續集成

          對于演示項目的覆蓋率報告是通過手動執行腳本文件生成的。

          而在實際的項目中,可能同時有很多人在開發同一個項目,每一天項目中都會有很多次的代碼提交。我們不可能每次手動的執行編譯和生成覆蓋率報告結果。這時就可以借助一些持續集成的工具,定時自動地完成項目的編譯,測試和覆蓋率報告結果的生成工作。

          可以在持續集成工具中包含我們編寫的腳本,然后將覆蓋率報告的html結果發布到某個Web服務器上,最后再以郵件的形式將鏈接地址發送給大家。

          這樣就可以很方便的讓整個團隊看到所有模塊的測試結果和覆蓋率情況了。

          完成了一整套這樣的工作,可以非常好的提升整個項目的質量。

          輯部 發自 凹非寺

          量子位 報道 | 公眾號 QbitAI

          “一起花光比爾蓋茨的8000萬美金,來不來?”

          23年前,李開復跟張亞勤這樣“畫餅”,于是亞洲最牛的計算機研究院就此誕生!

          如今,他們一個是最具影響力的VC代表,他創辦的創新工場已成為很多技術創新和前沿科技企業的精準捕手,他出版的書籍,不少登上暢銷書排行榜。

          另一個則是清華智能產業研究院院長、清華智能科學講席教授,前不久他剛當選中國工程院外籍院士。加之此前美國藝術與科學院院士、澳洲國家工程院院士,成為“三院院士”。

          結果在MEET2022智能未來大會的現場,兩人時隔多年首次同臺,在近兩百萬觀眾面前,揭秘相識往事,也分享了各自對于科技發展趨勢的看法。

          從網友的反應上看,這次巔峰對話足以滿足他們的期待。甚至還吸引了數十家主流媒體關注報道。

          巔峰對話還有哪些亮點?以及十余位頂級AI大咖分享更多精彩內容,老樣子,我們詳細道來,一文看盡。

          李開復張亞勤揭秘相識往事

          李開復張亞勤的巔峰對話環節,主要討論了三個方面。

          首先,他們回憶起23年前回國創建微軟亞洲研究院MSRA的事情。

          當時李開復給張亞勤打電話,就“畫了很大的餅”。他們想一同打造中國計算機的黃埔軍校,以此證明給全世界看,中國人也能做最頂級的科研。

          結果就在張亞勤決定回國,到北京第一天就被李開復修理了。

          嗯,理發的理。

          張亞勤回憶到,當時跟沈向洋一同回國,頭發因為很長時間沒打理,他們就被李開復帶去理發了。

          如今回過頭看,當初說要建立個亞洲最牛、全球一流的計算機實驗室這一個目標,在張亞勤看來已經實現,尤其在培養人才這方面。

          而且過程中,也有讓他們感到意外和大受震撼的進展。

          比如李開復舉例,誰能想到后來的AI四小龍的創始團隊,都有微軟亞洲研究院的背景。

          還有像現在頂尖高校、大企業CTO以及一些創業公司,都有特別多當時培養的人才。

          我們感覺特別欣慰,有種桃李滿天下的感覺。

          接著,他們探討了當下最流行議題和技術風向。

          比如元宇宙。

          李開復認為,它肯定會到來的,但五年之內不會有特別巨大的公司或應用出現。

          張亞勤則補充,要用開放的心態去看待元宇宙。

          一方面,如果說,元宇宙是真實世界與虛擬世界的融合,但以真實世界為主的話。

          很多公司已經在做了,目前產品形態是技術的一種拓展。

          另一方面,要說元宇宙是完全的虛擬世界,和真實世界沒關系,那可能走得就太遠了一點。現在也有不少炒作,技術也并不成熟,還需要不斷地發展。

          再比如,科學家創業的熱議趨勢。

          兩位老朋友一致認為,科學家創業需要一個企業家伙伴。

          張亞勤還補充道,科學家還需要專注。如果決定創業,那就出來做這件事。他認為科學家同時上課做科研,還要管理公司是很困難的。

          最后他們放眼未來,有哪些領域和賽道值得看好。

          張亞勤提及了AI與生物計算和生命科學交叉、無人駕駛和智慧交通,以及IOT。

          而李開復Pick的第一個與張亞勤相同,除此之外還有機器人領域,尤其在工業制造上的應用,以及自然語言理解。

          尤其是自然語言理解,李開復認為它在近幾年的發展跟當年CNN、DNN一樣,正從感知智能迅速邁向認知智能。未來AI一旦超越人類,就能做很多輔助、取代人類的工作。

          而至于自身的未來小目標,張亞勤還是繼續3.0人生——把AIR做起來,李開復則是想用行動證明做高科技的投資回報要比互聯網更高。

          哦對,這當中還有個小插曲。

          當兩位被問到,如果有項超能力——可以復制對方的能力,那會如何選擇。

          李開復首先就說,會復制張亞勤12歲就能讀大學的天才能力。

          而張亞勤,最想復制李開復吃遍美食還不胖”的能力。

          此外,亞勤還說想復制他對未來的洞察,以及可以用簡單的語言把復雜事物表述總結出來的能力。

          李開復和張亞勤的巔峰對話,由量子位總編輯李根主持,在對話環節最后,他表示能夠促成開復和亞勤的這樣一次“老友對談”,是量子位一直以來的愿望——

          不僅是因為兩位大咖今時今日的地位和成就,更是因為他們在23年前作出的回中國的決定,某種程度上來講,奠定了如今智能未來的基礎。

          而且更關鍵的是,開復和亞勤,還都在繼續為產業培育人才、鼓勵創新,是中國智能產業領域當之無愧的兩座高峰。

          清華張亞勤:下個十年是AI與生物制藥融合的大好時機

          實際上,在巔峰對話開始前,清華大學智能科學講席教授、清華智能產業研究院院長張亞勤,還以開場主題演講的形式,分享了他對趨勢——特別是AI+生命科學的判斷。

          清華智能產業研究院AIR于2020年成立,其使命是用人工智能技術賦能產業推動社會進步。

          清華AIR選擇了三個方向作為突破點:智能交通、智慧物聯、智慧醫療。張亞勤這次分享的重點是智慧醫療方向中,人工智能如何賦能生命科學。

          他認為整個信息產業過去三十年最大的突破就是數字化,從開始的內容數字化、企業數字化,到現在進入物理世界的數字化和生物世界的數字化。

          一方面我們的身體從大腦、器官,到細胞、蛋白質、基因、分子都在數字化,另一方面人工智能算法、算力和系統的快速進展讓大量數據有了使用的場所。

          以前新藥研發需要超過十幾年的周期,十億美元的投入, AI正在改變這種狀況。

          新冠疫苗去年年底進入臨床試驗,今年大規模使用,這可能是人類歷史上最快的一次計算機科學包括人工智能加速疫苗開發的例子。

          另外遷移學習用少量原始數據加上動物模型快速發現了對罕見病的藥物,幾何深度學習找出了廣譜、穩定的新冠抗體,對變種株也有效,Swin Transformer用于測序基因里90%的未編碼部分……

          張亞勤總結道,AI和生命科學有很多可合作的地方,能讓生物制藥更快速、精準、安全,更經濟、普惠。

          但同時也有很多壁壘,算法的透明性、可解釋性、隱私安全、倫理等挑戰,以及如何把兩個行業無縫連接起來。

          由此研究院提出了「AI+生命科學破壁計劃」作為前沿研究任務,跨越兩個領域的鴻溝、打破壁壘促進AI與生命科學的深度交叉融合,構建AI+生命科學的研究和技術生態。

          張亞勤看見了生物世界的數字化和AI技術的進展,相信下個十年是生物制藥和人工智能融合的大好時機,也是行業發展的最大的機遇。

          百度吳甜:技術創新持續為產業發展注入新動能

          百度集團副總裁、深度學習技術及應用國家工程實驗室副主任吳甜解讀了技術創新與產業發展的關系。

          根據中國信息通信研究院的數據,2020年我國數字經濟已經達到了39.2萬億元,占GDP總值的38.6%,位居世界第二。未來這個數值的絕對值和相對比例都會持續增加,數字產業化和產業數字化齊頭并進。

          產業發展角度,可以看到產業使用人工智能的場景廣泛且分散,技術與產業的結合越來越深入、專業,未來前景會更大更廣闊。

          技術發展角度,人工智能呈現出明顯的融合創新趨勢,包括軟硬一體融合、跨模態多技術融合、知識與深度學習融合、技術與場景融合。

          雖然底層技術越變越復雜,但所幸能夠通過開源開放的人工智能平臺降低門檻,使AI開發變得越來越容易。

          如金融領域常見的智能合同解析與管理場景,傳統都是靠人工方式從合同中提取三十多個維度信息,效率低,而保險的產品迭代速度又很快,相應的保險條款也在增加和變化,人工識別一份合同需要30分鐘。技術工程師在開發平臺上使用ERNIE訓練了條款智能解析模型,并持續進行迭代優化,部署到保險業務平臺中,提供智能解析能力,對合同文本實現了智能解析,達到通過智能輔助后單份合同解析時長縮短為1分鐘。

          像這樣的變化,在各個行業當中都在發生。

          吳甜總結道,一方面是產業的需求越來越旺盛,越來越多和廣泛,另一方面技術本身也給我們帶來新的想象空間,技術創新持續為產業當中運用人工智能技術注入新的動能,注入新的活力。

          IBM謝東:如何讓技術創新驅動環境智能和企業可持續發展

          IBM副總裁、大中華區首席技術官謝東博士為我們分享「加速科技創新,共贏可持續未來」的議題。

          從全球發展狀況來看,可持續發展是我們共同面對的戰略議題。世界經濟論壇2021年全球風險報告指出,未來十年企業面臨前的三大業務風險都與環境相關。

          在中國雙碳目標下,可持續發展不光是我們所有企業的社會責任,更加已經成為企業必須面對的戰略議題。對于企業應該如何面對這些挑戰,新技術突破會給行業帶來哪些轉變?

          謝東博士從三個維度做了梳理。

          企業治理角度,IBM非常注重可持續發展問題,早在50年前,制定了首個企業環境的政策,2000年提出二氧化碳減排目標;與全球各行業客戶建立可持續發展咨詢委員會。

          當中還為助力中國企業實現碳中和制定四階段戰略建議,包括確保合規、優化流程及供應鏈、重塑業務、引領行業。

          基于環境問題,IBM推出環境智能套件,涵蓋人工智能、數據分析、環境數據分層、混合云、物聯網與區塊鏈。

          在技術平臺助力環境議題和創新的維度,以IBM位于蘇黎世的云上自主化學實驗室RoboRXN為例,全球可以通過網絡直接訪問到實驗室,遠程完成了從文獻檢索到一些科研探索,再到功能驗證各個環節。

          過去兩年,化學實驗室RoboRXN采用的免費AI模型,已經為學生、科學家和實驗者完成了近100萬次反應預測。

          而背后能支撐這一系列環境和可持續發展創新的底層計算技術又是怎樣的?謝東博士提到了最新推出的2nm芯片技術、帶有片內AI加速器的處理器Telum,以及前不久發布的突破127 量子位量子處理器。謝東博士認為,量子計算機規模化商用可能已經在不遠的未來了。

          小冰李笛:AI相比人類創作者,不存在瓶頸期

          小冰公司首席執行官李笛認為,有時候人們會過于高估人工智能在IQ方向的進展,卻低估了人工智能在EQ方面蘊藏的巨大潛力。

          那些出現在人類身邊、與人類共存的「AI being」都應該有自己擅長和不擅長的領域,有自己的性格和觀念,無所不知、無所不能的AI反而是面目不清的。

          在迪拜世博會中國館,正在展出AI畫家夏語冰的一系列水墨畫作品《山水精神》。

          夏語冰除了創作能力也有著自己的面容、口音和創作觀念,與另一位AI畫家山東大哥完全不同。

          李笛指出,如果要賦予AI創造力,它對不同事情的觀念要有一致性,并反映在其所創造的東西上,才能讓人類不感到違和。

          當人工智能習得一定創作能力的時候,和人類創作者區別是什么?

          第一,人類創作到了巔峰之后便開始滑坡,人工智能沒有巔峰,要么是停滯的、要么會繼續向上攀登,時間周期非常久。

          第二,人類在同一時間只能專注地做一件事情,但人工智能是可以高并發的。

          創造力只是小冰框架中的一小部分,最難的是如何賦予AI有趣的靈魂,真正和人類交流。

          李笛看到人工智能在EQ方面蘊藏的巨大潛力,他相信我們這一代是與多樣的人工智能生活在一起的第一代人類。

          Rokid祝銘明:元宇宙更應專注虛實融合

          Rokid創始人CEO祝銘明則在大會上探討了AR智能眼鏡行業的應用落地探索。

          當前大家談元宇宙,很多人談的是創想與未來,Rokid關注的是技術落地能力,主要有5個方面:

          感知——理解——協同——展現(光學技術、圖形引擎)——數字資產/內容(創作、生產工具)

          祝銘明介紹,Rokid是一家產品平臺型公司,除了上述五種能力,還會考慮一些載體去做和大家進行交互,也根據自己思考分成了四個象限。

          橫軸代表以穿戴性、佩戴性為出發點去衡量,從專用場景到日常佩戴(從左到右)。

          縱軸是以展現能力為一個衡量點去思考,從內容屬性到工作屬性(從上到下)。

          第一層,感知能力,如半導體、傳感器等技術。

          第二層,關注在感知基礎上如何理解世界,理解周邊的環境、理解人、理解事。

          第三層為協同,深度思考人和人、人和事物之間的協同關系,但不是創造虛擬世界,而是融合真實世界和數字世界。

          第四層,視覺和感官層的展現能力,背后涉及光學、圖形引擎、算法、空間引擎等技術。

          最后,為數字資產(數字內容生產)。包括創作工具、生產工具、管理、安全等方面的能力。

          過程中,祝銘明還強調,Rokid做人機交互有著不同的階段,從最早指令型的人機交互,到后面圖形化的所見即所得的人機交互,對人類越來越友好。

          在分享的最后,他提出了自己對于元宇宙的思考。

          如果元宇宙是一種發展方向,那我們覺得元宇宙不應該是局限于虛擬世界,如何將人與真實世界和虛擬世界做一個完整的融合,不應該割裂開,這是我們一直在主導的事情。

          他看到了人機交互的巨大潛力,他相信在未來,真實世界跟數字世界將進行融合而非割裂。

          亞信科技歐陽曄:5G把AI 能力投送到邊緣


          亞信科技首席技術官、高級副總裁歐陽曄帶來了《5G網絡助推邊緣AI》的主題演講。

          以2006年AI第三次發展浪潮開始作為節點到現在的15年間,通信領域與AI相關的學術成果發表數量是之前15年的6.42倍。同時隨著5G技術與業務的發展,云端智能需向邊緣遷移。

          通信技術作為數字化轉型的基礎設施,該如何利用5G通信技術把AI能力投送到千行百業的邊緣觸點?

          歐陽曄博士介紹了5G網絡投送AI能力到達邊緣的三種模式:

          • 5G網絡切片,可以理解成在現有的公有網絡里構建一層專用的高速隧道。
          • 5G獨立專網,企業搭建的私有網絡。
          • 5G混合專網,專網與公網共享基站的模式。

          AI能力投送到邊緣后并不是就能直接應用到各種to B和to C場景,而是通過第五代移動通信邊緣計算平臺承載多種通用目的技術(如AI,數字孿生,數據治理與AIoT等)構建云邊端協同整體方案。

          隨后歐陽曄介紹了基于五代移動通信邊緣計算平臺的智慧電廠、智慧工地和智慧園區3個典型場景案例。

          歐陽曄指出通信和AI兩個領域的發展相關性將越來越強,他相信在未來,應用層廠家、通信基礎設施廠家以及運營商合作伙伴要共同努力,共同觸及通信人工智能未來十年的發展。

          京東何曉冬:對話本質上是博弈與決策,語言只是一種表現形式

          京東集團副總裁、京東探索研究院常務副院長何曉冬則分享了多模態智能人機交互技術在復雜場景中的進化,以及技術落地給人類創造價值。

          提到人工智能,往往會想到語音識別,圖像識別、人臉識別、甚至機器翻譯。

          對話智能是種什么智能?某種程度上講是一種融合性智能,前面提到單點基礎技術都被融合在其中。

          簡單說,對話智能就是希望打造一個機器,它能夠自如像人一樣跟你對話交流溝通關懷,完成任務。

          表現上看,它是種非常自然地交互方式;從技術上看,它需要感知智能、情感智能、認知智能、多輪對話管理。

          何曉冬認為,對話即決策,本質上來說對話本質上是博弈與決策,語言只是一種表現形式。

          接著,何曉冬介紹了在京東是如何迭代技術、讓這項技術為更多用戶所用、創造更多的價值。

          簡單來說,兩種模式并行:打造前沿的技術能力,同時把前沿的技術推向千行百業應用落地。

          剛剛過去的雙十一,何曉冬團隊通過智能人機對話系統打造的京東智能客服言犀,累計服務了超過7.4億咨詢量、16.5萬的第三方商家,智能物流預約外呼超過了193萬通電話,完成2.1億次的質量檢測,在整個京東的售前、售中、售后、物流各個環節實現了客服服務全鏈路的場景智能化。

          大會現場何博士還給我們演示了智能人機對話系統服務成都顧客的真實案例~

          而為了讓機器人做得更好,京東還打造了五個維度的服務評價質量指數,來評價機器人和人之間的差距,展示京東在智能人機對話領域深刻的沉淀。

          除了服務京東本身以外,他們的多模態智能人機交互技術還運用到更多行業當中去,比如政府的政務熱線、金融行業的業務客服等。

          展望未來五年,人工智能的三大支柱數據、算力、算法,都會得到進一步升級場景、系統、算力。

          數據升級成持續運作的“活”場景數據;單點的算法進一步提升至綜合性的AI系統,包括多算法互相協同、聯合優化,這樣才能打造真正端到端、高價值的AI系統。

          商湯楊帆:AI算法下一個時代是端到端系統化整合

          商湯科技聯合創始人、商湯集團副總裁楊帆認為,賦能產業升級是AI的核心價值所在。

          今天在各行各業都有對AI的剛需存在。

          如工業檢測分析的痛點是效率低、漏檢率高和標準不統一、檢測人員水平差異大等。城市管理分析中事故的偶發性高、分散,需要大量人力投入。

          楊帆說,眼下AI企業會越來越面臨一種「幸福的煩惱」。

          幸福之處在于剛需大量存在,煩惱之處在于剛需碎片化、場景多樣化,AI企業提供技術創新的成本,包括邊際成本比較高,造成了AI產業進一步發展面臨的供需匹配失調的問題。

          要解決這些煩惱一方面需要有通用能力的基礎設施為人工智能產業創新提供支撐,另一方面需要跨組織之間的聯合和協作。

          楊帆從在商湯做算法的經歷出發,總結出算法的三個時代。

          第一個時代像手工業,非常依賴個體科學家的個人水平。

          第二個時代就是過去這5年,像工業化流水線,能夠用更多系統把算法創造的各個環節整合打通,持續的規?;纳a技術創新。

          下一個時代該是什么?楊帆認為技術創新會走向更加通用、低成本高效,就像工業流水線趨勢是自動化智能化。

          從底層基礎設施,到硬件,再到軟件和上游應用,形成端到端系統化模式,把各個環節進行更加標準化的定義以及有機組合。

          端到端整合可以帶來更高的安全性以及更低的網絡時延,同時把算法打造成像樂高積木塊一樣,提供給產業內的大家共同去打造有價值的應用。

          楊帆看到了行業剛需當下沒有被很好的滿足,他相信平臺化、規模化、低成本高效率的工具體系,會讓整個產業技術創新走得更快。

          思謀劉樞:AI技術正在成為一種新型生產要素

          思謀科技聯合創始人兼技術負責人劉樞在大會分享了思謀科技如何用AI推動制造業數字化智能化轉型。

          人工智能在推動經濟發展的同時,也在創造虛擬勞動力,去做人類不想做、做不好、不能做的事情,同時當人工智能在很多行業落地的時候,可以拉動其上下游協同發展和創新。

          因此作為兩年即長成獨角獸的思謀科技,認為“人工智能技術正在成為一種新的生產要素”。

          埃森哲曾預測到2035年,人工智能可以將年經濟增長率額外提升1.6%,人工智能作為單獨技術將額外帶來8千億美金增長,而如果作為生產要素去評估,將帶來6萬億美金的規模增長。

          再來看制造業的發展,總共經歷了三個階段:自動化-信息化-智能化,如今智能制造蘊含著巨大發展機遇。

          智能制造,關鍵在于智能——即讓制造擁有大腦,自動化只是手臂,把決策變為現實。但實際落地過程中,思謀科技遇到了些有意思的問題,這與熟悉的自然場景有許多不同。

          首先,數據極度短缺。在工業場景里面,很多時候每一種缺陷的圖片數量都達不到10。

          第二,工業驗收要求非常高。以手機為例,如果要求手機成品良率99%,假設一臺手機含200個零件,那么每個零件良率都需達到99.99%。

          第三,被檢形態非常多。常用器件就可能有成百上千種不同的形狀。

          第四,缺陷難以區分。

          劉樞認為,只有當系統可以自動實現算法組合和部署,人類只需要少量定制化算法設置的時候,才有可能實現AI跨領域規模產業化。

          如果沒有自動實現算法組合和部署的系統,在高端制造業實現AI全面產業化會非常艱難。

          以智能手機為例,零件供應商平均來講有400個,每個供應商有五個制程,每個制程又有15條產線,如果一條產線都做一個模型,大概要做3萬個模型。

          再放眼全行業前五的品牌,每個品牌6款產品,則需要90萬個不同的算法模型,這其中還不算第二年、第三年的軟硬件升級迭代。

          為了達到這一目標,思謀科技研發了AI算法平臺SMAP,以及沉淀了AI Know-How的DataFlow系統。

          最后,劉樞還分享了智能制造的核心原則:普適性,計算為先和永不間斷的學習。

          當AI系統設計能夠自動化,當AI部署和運營能夠自動化的時候,就一定能夠實現新一代智能產業的變革。

          數牘科技蔡超超:隱私計算,構建下一代數據流通底層的關鍵設施

          數牘科技聯合創始人兼CTO蔡超超分享的主題是《隱私計算構建下一代數據流通底層的關鍵設施》。

          剛才我們提到智能駕駛場景,就和隱私計算有很大的相關性。

          智能汽車在運行過程中產生大量圖片、音頻甚至位置數據,都涉及到用戶的隱私。這些數據的高效開發利用需要在保護數據安全的情況下進行,需要用到隱私計算。

          隱私計算是一種在數據不可見的前提下,讓信息進行價值流通的工程和技術體系,涉及多方安全計算,聯邦學習、可信執行環境、差分隱私、同態加密、區塊鏈等多種技術。

          蔡超超同時認為隱私計算體系不是一個單一的系統,它其實是一個網絡,一個底層平臺,包含了不同的參與方。

          每個參與方的主體可能是人、是車或其他設備,這些主體都會有自己的ID,比如身份證、電話號碼、設備號,在數據合作之前需要有共同的語言把ID有效統一對齊起來,才能進行安全的數據協作。

          基于隱私計算的ID系統可以做到匿名化、原始ID和敏感信息不可追溯、不可還原。

          接下來,讓多方在不交換原始數據的前提下進行安全合規的數據協作,應用于反欺詐、反洗錢、精準營銷、聯合風控等一系列場景。

          蔡超超看到了有數據價值交換的地方就有隱私計算的需求,他相信隱私計算平臺發展過程中需要注重安全可靠性、有完整的數據科學應用體系以及工業級落地能力。

          智駕周圣硯:以規?;又悄荞{駛平權時代

          智駕科技創始人兼CEO周圣硯在大會上分享了智駕視角下自動駕駛產業以及今后發展是如何的。

          一開場,周圣硯就舉了一個小例子:如果問消費者,什么品牌汽車做的比較好,消費者能輕易列出答案。但如果問自動駕駛有哪些比較好的公司,可能大多數消費者都沒辦法答出。

          為什么會有這樣的現象?如果回顧互聯網行業的發展,就會發現它之所以能蓬勃發展,是因為覆蓋了最廣大用戶群體。

          回顧過去幾年自動駕駛的發展一直非常曲折,原因在于大家一直在技術路徑和商業模式上產生強烈的爭議。如今這些爭議依舊存在,但同時也確實感受到自動駕駛正在實現并產生社會的正向價值。

          SAE把自動駕駛從工程學的角度分了L0-L5不同駕駛等級,智駕科技MAXIEYE今天從解決問題的角度重新分解自動駕駛等級。

          首先,即第一個等級,需要解決的是安全問題,比如車輛的緊急制動系統。

          第二個等級,駕駛過程中的舒適性問題,比如高速公路實現的全速巡航系統。

          第三個等級,解決出行效率問題。智駕科技MAXIEYE認為在結構化道路,比如城市道路和高速公路,可以實現點到點的自動駕駛功能。

          第四個等級,優化交通能源的問題,比如干線無人物流。前三個等級叫做人機共駕,最后一個等級才叫做無人駕駛。

          最后,他希望與行業一起迎接智能駕駛科技平權時代的到來。

          從市場維度,產品全面下探最廣泛的5-15萬元車型,將覆蓋最廣大的用戶群體;從消費者維度,提供消費者用得起愿意用的智能駕駛產品;從產業鏈維度,全行業開放共創,建立行業共識和技術協同,全產業鏈去共同打造智能駕駛科技平權時代。

          周圣硯看到自動駕駛需要覆蓋更廣大用戶群體,他相信未來AI將以數據驅動方式助力智能駕駛系統越用越聰明。

          自動駕駛圓桌論壇:量產、安全,變局時刻

          大會的最后階段,自動駕駛行業大佬們圍繞「量產」展開了激烈討論。

          先來介紹一下各位嘉賓:

          騰訊交通平臺部總經理、自動駕駛總經理蘇奎峰

          過去一年騰訊從自動駕駛測試工具鏈,以及智能聯網示范區、智慧高速等車路協同解決方案兩個方面助力產業發展。

          無人駕駛公司馭勢科技聯合創始人、首席系統架構師彭進展。

          馭勢科技開展了無人車在多個場景的商業化運營,擁有在機場、工廠等場景幾百臺車7x24小時、365天持續不斷的運營能力。

          無人卡車公司主線科技CEO張天雷。

          主線科技專注于自動駕駛卡車,在幾個港口物流樞紐還有京津高速、京滬高速上運行的車輛規模有150輛車左右,每天都在持續地運行。

          那么開始第一個話題,2021年怎么就成了自動駕駛量產集中的一年?

          首先三位嘉賓都認為政策很關鍵,三個團隊創業之初都獲得了資金支持,來自國家自然科學基金。

          另外今年從北上廣深到武漢、長沙、無錫再到衡陽,無論一線還是二三線城市都開始積極推動無人駕駛落地。

          張天雷提出第二個因素:場景。

          張天雷覺得物流場景尤其是封閉的完全無人的,還有高速以及一些城區限定區域內的場景,從今年開始包括到明年年底很有可能有很多批量的應用出來。

          彭進展的角度是技術進展,無人駕駛如果不能把安全員拿掉,就體現不出真正的價值。

          只有真正把安全員拿掉,你的客戶和合作伙伴才會相信這件事真的能成功。

          最后蘇奎峰總結發言,政策、場景和技術全都交匯在今年這一點,無人駕駛量產終于到來。

          第二個話題:量產之后,大眾都「看見」了自動駕駛,未來行業會面臨哪些新的挑戰?

          雖然問題比較寬泛,不過三位的表達不約而同的集中在了安全這個點。

          蘇奎峰提到,只要自動駕駛的量產規模大了,原本的一些小概率事件也會變成常發事件,這不代表技術不好,但確實有許多長尾的問題需要預見和克服。

          他強調:

          我們在安全性、穩定性上要有敬畏心。

          彭進展認為無人駕駛在安全上的優勢在于實時性,實時監控反映,實時通過AI去控制。

          雖然理論上可以計算出無人駕駛事故概率就是遠遠低于人類駕駛,但實際中還需要做進一步驗證。

          每天都會發生人為因素引起的交通事故,但對于大眾來說并不算什么新聞。期待有一天,大眾對自動駕駛出事故也有一個平常的心態。

          張天雷則指出沒有一個系統能夠百分之百的保證總是正常運行,我們要做的是把出錯的代價降到最小,核心的問題是不要有人員的傷亡。

          在任何時候,自動駕駛的安全性永遠排在第一位。為了系統的安全性,付出再多代價也是需要的。

          圓桌討論的最后一部分,是每人分享一件行業中最感到意外的事。

          蘇奎峰:

          到頭來是新能源加速了自動駕駛落地。

          彭進展:

          震撼最大的是行業真的做到把安全員拿掉了。

          張天雷:

          特斯拉投入巨大精力做數據驅動,造了世界上排行第五的超算機群來訓練模型,這是中小型國家都做不到的。

          從那時開始,大家明白了一個道理,自動駕駛是個軍備競賽。

          因為看見,所以相信

          過去的一年,是復雜變化的一年。

          但前沿科技始終是社會發展的重要動力,也蘊藏著無比的機遇。AI大模型、自動駕駛、生物計算等領域正在加速改變世界,前沿計算、新型儲能等方向新探索不斷涌現。

          與此同時,前沿技術的落地也愈發如火如荼。新技術、新產品讓我們的生活越來越好,越來越有趣。

          不過一切也并非一帆風順。

          量子位創始人兼CEO孟鴻表示,前沿科技的發展總是起起伏伏,發展的范式會改變,上升的道路會改變,但前進的趨勢不會改變。

          今年到場的來賓,都是因為對前沿科技有一份堅定的相信,進而選擇在這個方向上不斷推動世界前進。

          整場大會下來可以看到,他們今年交出的商業化落地答卷,在更深入現實的地方被交出。

          而這也只是今年諸多技術創新案例中的一隅。

          作為人工智能年度最佳落地參考,「2021人工智能年度評選」結果也已揭曉。在過去2個月時間里,共有數百家科技企業、機構和個人報名參與評選。

          最終評選出50大領航企業、20大最具價值創業公司、30大創業領袖、20大技術領袖、10大最佳產品以及10大最佳解決方案等在內人工智能領域年度獎項。

          這些無一不在印證本次MEET智能未來大會主題:因為看見,所以相信。

          希望讓更多人看到前沿科技的進展和落地,讓更多人進一步相信前沿科技背后蘊藏的巨大價值。

          那么這一年,你看見了什么?從而又相信著什么?

          Ps,也許量子位最新發布的「2021人工智能年度評選」,可以給你參考,鏈接在此:https://mp.weixin.qq.com/s/E3wcXr3PA0uZAZ1N-lgThg。

          Pps,如果想回顧精彩內容,回放鏈接在此!
          微吼:http://live.vhall.com/127740714
          微博:https://weibo.com/l/wblive/p/show/1022:2321324707747747987514
          百家號:https://live.baidu.com/m/media/multipage/liveshow/index.html?room_id=5008651533
          CSDN:https://live.csdn.net/room/wl5875/tVtNmdeX
          斗魚:https://v.douyu.com/show/85BAvqrrERB7G4Lm?ap=1

          — 完 —

          量子位 QbitAI · 頭條號簽約

          關注我們,第一時間獲知前沿科技動態


          主站蜘蛛池模板: 国产一区二区三区免费观在线| 韩国资源视频一区二区三区| 国产精品第一区第27页| 无码人妻品一区二区三区精99 | 一区二区三区免费视频网站| 国产在线精品一区在线观看| 国产精品538一区二区在线| 一区二区三区福利视频| 国产高清一区二区三区四区| 亚洲国产一区国产亚洲| 国产精品一区二区久久精品| 国模无码视频一区二区三区| 国产一区三区三区| 精产国品一区二区三产区| 国产在线一区二区三区av| 日本一区二区不卡视频| 亚洲一区在线视频| 无码人妻精品一区二区三区蜜桃| 久久国产三级无码一区二区| 亚洲欧美日韩国产精品一区| 一区二区三区免费在线观看| 一级特黄性色生活片一区二区| 日本香蕉一区二区三区| 怡红院一区二区三区| 精品3d动漫视频一区在线观看| 国产伦一区二区三区免费| 亚洲一区二区高清| 亚洲一区二区三区播放在线| 怡红院AV一区二区三区| 夜夜精品无码一区二区三区| 久久精品一区二区三区中文字幕 | 中文字幕日韩人妻不卡一区 | 无码日本电影一区二区网站| 亚洲一区二区三区在线观看蜜桃| 日韩精品一区二区三区中文字幕 | 日韩欧国产精品一区综合无码| 国产av一区二区精品久久凹凸 | 日韩精品久久一区二区三区| 韩国精品一区二区三区无码视频| 国产一区二区三区在线观看免费| 麻豆AV无码精品一区二区|