Spring 核心技術(1)

接上篇:Spring 框架概述

version 5.1.8.RELEASE

這部分參考文檔涵蓋了 Spring Framework 所有絕對不可或缺的技術。

其中最重要的是 Spring Framework 的控制反轉(IoC)容器。在介紹完 Spring 框架的 IoC 容器之後,緊接着全面介紹 Spring 的面向切面編程(AOP)技術。Spring Framework 有自己的 AOP 框架,它在概念上易於理解,並且成功地定位了 Java 企業編程中 AOP 需求的 80% 最佳擊球點。

Spring 提供與 AspectJ (目前功能最豐富,也是Java企業領域中最成熟的 AOP 實現)的集成。

1. IoC容器

本章介紹 Spring 的控制反轉(IoC)容器。

1.1 Spring IoC 容器和 Bean 簡介

本章介紹了 Spring Framework 控制反轉(IoC)的實現原理。IoC 也稱為依賴注入(DI)。通過這個機制,對象可以通過構造方法參數、工廠方法參數以及通過工廠方法構建或返回的實例上設置的屬性來定義它們的依賴關係(即它們使用的其他對象)。然後容器在創建 bean 時注入這些依賴項。這個過程從根本上反轉了 Bean 自身通過直接調用構造方法或服務定位模式等機制來控制實例化或定位其依賴的模式,因此叫做控制反轉。

org.springframework.beansorg.springframework.context 包是 Spring 框架的 IoC 容器的基礎。BeanFactory 接口提供了一種能夠管理任何類型對象的高級配置機制。ApplicationContext 是 BeanFactory 的子類。它補充的內容有:

  • 更容易與 Spring 的 AOP 功能集成
  • 消息資源處理(用於國際化)
  • 事件發布
  • 應用層特定的上下文,例如在 Web 應用程序中使用的 WebApplicationContext

簡而言之,BeanFactory 提供了配置框架和基本功能,ApplicationContext 添加了更多針對企業級的功能。ApplicationContextBeanFactory 完整的超集,在本章中僅用它描述 Spring IoC 容器。有關使用 BeanFactory 而不是 ApplicationContext的更多信息 請參考 BeanFactory。

在 Spring 中,構成應用程序架構並由 Spring IoC 容器管理的對象稱為 beans。bean 是一個由 Spring IoC 容器實例化、組裝或管理的對象。除此之外,bean 只是應用程序中眾多對象之一。Bean 及其之間的依賴關係反映在容器使用的配置元數據中。

1.2 容器概覽

org.springframework.context.ApplicationContext 接口代表 Spring IoC 容器,負責實例化、配置和組裝 bean。容器通過讀取配置元數據獲取有關需要實例化、配置和組裝對象的指令。配置元數據以 XML、Java 註解或 Java 代碼錶示,通過它可以表示構成應用的對象以及對象之間豐富的依賴關係。

Spring 提供了多種 ApplicationContext 接口實現。在傳統單機應用中,通常會創建一個 ClassPathXmlApplicationContextFileSystemXmlApplicationContext 的實例。雖然 XML 是定義配置元數據的傳統格式,但你也可以通過提供少量 XML 配置聲明容器啟用對其他元數據格式的支持后使用 Java 註解或代碼作為元數據格式。

在大多數應用程序方案中,不需要顯式使用代碼來實例化 Spring IoC 容器實例。例如,在 Web 應用程序場景中,應用程序文件 web.xml 中一個 8 行左右的 web 描述模板 XML 就足夠了(請參閱 Web 應用程序快速實例化 ApplicationContext)。如果你使用 Spring Tool Suite(一個基於 Eclipse 的開發環境),只需點擊幾下鼠標或按幾下鍵盤即可輕鬆創建此模板配置。

下圖是 Spring 工作原理的高級視圖。應用程序類與配置元數據相結合,在 ApplicationContext 創建並初始化之後,即可擁有完全配置且可執行的系統或應用程序。

1.2.1 配置元數據

如上圖所示,Spring IoC 容器使用一系列配置元數據。這些配置元數據描述了Spring 容器在應用程序中如何實例化,配置和組裝對象。

傳統配置元數據使用簡單直觀的 XML 格式,本章大部分內容也是用 XML 來表達 Spring IoC 容器的關鍵概念和功能。

XML 不是唯一的配置元數據格式。Spring IoC 容器與實際編寫配置元數據的格式完全解耦。目前,許多開發人員為其 Spring 應用程序選擇基於 Java 的配置。

有關在 Spring 容器中使用其他形式的元數據的信息,請參閱:

  • 基於註解的配置:Spring 2.5 引入了對基於註解的配置元數據的支持。
  • 基於Java的配置:從 Spring 3.0 開始,Spring JavaConfig 項目提供的許多功能成為 Spring Framework 核心的一部分。因此,你可以使用 Java 而不是 XML 文件來定義應用程序類外部的 bean。要使用這些新功能,請參閱 @Configuration@Bean@Import,和 @DependsOn 註解。

Spring 配置信息由至少一個(通常不止一個) 必須由容器進行管理的 bean 定義組成。基於 XML 的配置元數據將這些 bean 配置為頂級元素 <beans/> 內的 <bean/> 元素。基於 Java 的配置通常在使用 @Configuration 註解的類中使用帶有 @Bean 註解的方法。

這些 bean 定義對應構成應用程序的實際對象。我們一般會定義服務層對象,數據訪問對象(DAO),展示層對象(例如 Struts Action 實例),基礎結構對象(例如 Hibernate SessionFactories、JMS Queues 等)。一般不會在容器中配置細粒度的域對象,因為通常由 DAO 和業務邏輯負責創建和加載域對象。然而,你可以使用 Spring 集成 AspectJ 來配置非 IoC 容器創建的對象。請參閱使用 Spring 和 AspectJ 進行域對象的依賴注入。

以下示例显示了基於 XML 的配置元數據的基本結構:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="..." class="...">①②
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <bean id="..." class="...">
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <!-- more bean definitions go here -->

</beans>

① id 屬性是一個標識單個 bean 定義的字符串

② class 屬性使用完整的類名定義 bean 的類型

id 屬性的值表示協作對象。在此示例中未包含用於引用協作的對象的 XML。有關更多信息,請參閱依賴。

1.2.2 實例化容器

提供給 ApplicationContext 構造函數的位置路徑是一個資源字符串,它允許容器從各種外部資源加載配置元數據,例如本地文件系統、Java 環境變量等。

ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");

在了解了 Spring 的 IoC 容器之後,你可能想要了解有關 Spring 資源抽象化(參考資源描述)的更多信息,特別是 Resource 路徑用於構建應用程序上下文(請參考應用程序上下文和資源路徑),它提供了一種便捷的機制從 URI 語句中定義的位置讀取 InputStream。。

以下示例展示了服務層對象配置文件(services.xml):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- services -->

    <bean id="petStore" class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl">
        <property name="accountDao" ref="accountDao"/>
        <property name="itemDao" ref="itemDao"/>
        <!-- additional collaborators and configuration for this bean go here -->
    </bean>

    <!-- more bean definitions for services go here -->

</beans>

以下示例展示了數據訪問對象文件(daos.xml):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="accountDao"
        class="org.springframework.samples.jpetstore.dao.jpa.JpaAccountDao">
        <!-- additional collaborators and configuration for this bean go here -->
    </bean>

    <bean id="itemDao" class="org.springframework.samples.jpetstore.dao.jpa.JpaItemDao">
        <!-- additional collaborators and configuration for this bean go here -->
    </bean>

    <!-- more bean definitions for data access objects go here -->

</beans>

在前面的示例中,服務層由 PetStoreServiceImpl 類和兩個數據訪問對象 JpaAccountDaoJpaItemDao(基於 JPA 對象關係映射標準)組成。property 元素的 name 屬性指的是 JavaBean 屬性的名稱,ref 屬性指向另一個 bean 定義的名稱。元素 idref 之間的這種聯繫表達了協作對象之間的依賴關係。有關配置對象的依賴關係的詳細信息,請參閱依賴關係。

編寫基於XML的配置元數據

通常,每個單獨的 XML 配置文件都對應着架構中的邏輯層或模塊,讓 bean 定義在多個 XML 文件中生效會非常有用。

如上一節中所示,應用程序上下文構造函數可以使用多個 Resource 位置,它可以從這些 XML 片段中加載 bean 定義。另外也可以使用一個或多個 <import/> 元素從其他文件加載 bean 定義。以下示例展示了如何執行此操作:

<beans>
    <import resource="services.xml"/>
    <import resource="resources/messageSource.xml"/>
    <import resource="/resources/themeSource.xml"/>

    <bean id="bean1" class="..."/>
    <bean id="bean2" class="..."/>
</beans>

在前面的例子中,從三個文件中加載外部 Bean 定義,分別是 services.xml、messageSource.xml 和 themeSource.xml。對於執行導入的定義文件來說,所有路徑都是相對路徑,因此 services.xml 必須與執行導入的文件位於相同的目錄或環境變量, messageSource.xml 和 themeSource.xml 必須位於導入文件路徑下方的 resources 目錄中。正如你所見,前邊的斜杠會被忽略掉。鑒於提供的都是相對路徑,所以最好不要使用斜杠。這些文件中包括根據 Spring Schema 定義的正確的 XML Bean 在內的內容都會被導入,包括頂級元素 <beans/>

雖然可以使用相對路徑“../”引用父目錄中的文件,但不建議這樣使用,因為這樣做會使得當前應用依賴程序之外的文件。非常不建議使用 classpath:URL(例如,classpath:../services.xml)引用文件,因為運行時解析過程會選擇“最近”的環境變量根目錄,然後查找其父目錄。環境變量配置的更改可能導致目錄選擇不正確。

可以使用完整的資源位置替代相對路徑,例如,file:C:/config/services.xml 或 classpath:/config/services.xml。然而需要注意應用程序的配置將會與特定的絕對路徑耦合。通常最好為這些絕對路徑保持間接聯繫,例如通過在運行時通過“$ {…}”佔位符替代 JVM 系統屬性。

命名空間本身提供了導入指令的功能。Spring 提供的一系列 XML 命名空間中提供了除普通 bean 定義之外的其他配置功能,例如 context 和 util 命名空間。

Groovy Bean 定義 DSL

作為外化配置元數據的另一個示例,bean 定義也可以在 Spring 的 Groovy Bean 定義 DSL 中表示,就像 Grails 框架。通常此類配置位於“.groovy”文件中,其結構如下例所示:

beans {
    dataSource(BasicDataSource) {
        driverClassName = "org.hsqldb.jdbcDriver"
        url = "jdbc:hsqldb:mem:grailsDB"
        username = "sa"
        password = ""
        settings = [mynew:"setting"]
    }
    sessionFactory(SessionFactory) {
        dataSource = dataSource
    }
    myService(MyService) {
        nestedBean = { AnotherBean bean ->
            dataSource = dataSource
        }
    }
}

此配置樣式在很大程度上等同於 XML bean 定義,同樣支持 Spring 的 XML 配置命名空間。它還允許通過 importBeans 指令直接導入 XML bean 定義文件。

1.2.3 使用容器

ApplicationContext 是一個高級工廠接口,主要負責維護不同 bean 及其依賴項的註冊。通過使用 T getBean(String name, Class<T> requiredType) 方法可以獲得 Bean 的實例。

通過 ApplicationContext 可以讀取 bean 定義並訪問它們,如下例所示:

// create and configure beans
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");

// retrieve configured instance
PetStoreService service = context.getBean("petStore", PetStoreService.class);

// use configured instance
List<String> userList = service.getUsernameList();

使用 Groovy 配置時,初始化程序看起來非常相似。不同的是使用了支持 Groovy 的上下文實現類(也支持 XML bean 定義)。以下示例展示了 Groovy 配置:

ApplicationContext context = new GenericGroovyApplicationContext("services.groovy", "daos.groovy");

最靈活的使用方式是 GenericApplicationContext 與讀取器委派結合使用,例如針對 XML 文件使用 XmlBeanDefinitionReader,如以下示例所示:

GenericApplicationContext context = new GenericApplicationContext();
new XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml", "daos.xml");
context.refresh();

還可以使用針對 Groovy 文件使用 GroovyBeanDefinitionReader ,如以下示例所示:

GenericApplicationContext context = new GenericApplicationContext();
new GroovyBeanDefinitionReader(context).loadBeanDefinitions("services.groovy", "daos.groovy");
context.refresh();

你可以在相同的 ApplicationContext 中混合使用此類讀取器委託, 從不同的配置源讀取 bean 定義。

你可以使用 getBean 方法來獲取 Bean 實例。ApplicationContext 接口還有一些其他方法可以獲取 bean,但理想情況下你的應用程序不應該使用它們。實際上,你的應用程序代碼根本不應該調用 getBean()方法,也應該不依賴於 Spring API。例如,Spring 集成的 Web 框架為各種 Web 框架組件(如控制器和 JSF 託管的 bean)提供依賴注入,以便通過元數據聲明對特定 bean 的依賴關係,例如自動裝配註解。

  • 我的CSDN:https://blog.csdn.net/liweitao7610
  • 我的博客園:https://www.cnblogs.com/aotian/
  • 我的簡書:https://www.jianshu.com/u/6b6e162f1fdc

【精選推薦文章】

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

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

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

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

List集合去重方式及效率對比

List集合相信大家在開發過程中幾乎都會用到。有時候難免會遇到集合里的數據是重複的,需要進行去除。然而,去重方式有好幾種方式,你用的是哪種方式呢?去重方式效率是否是最高效、最優的呢?今天就給大家講解一下List集合去重的常見及常用的四種方式。

01

實現思路:使用兩個for循環遍歷集合所有元素,然後進行判斷是否有相同元素,如果有,則去除。這種方式是大部分最先想到的,也是最簡單的實現方式。其中,這種方式可以保證List集合原來的順序不變。

代碼實現:

/**
* notes:使用兩個for循環實現List去重
@param list
@return
*/
public static List repeatListWayOne(List<String> list){
   for(int i = 0;i < list.size();i++){
       for(int j = i+1;j < list.size();j++){
           if(list.get(i).equals(list.get(j))){
               list.remove(j);
           }
       }
   }
   return list;
}

 

02

實現思路:我們知道HashSet實現了Set接口,不允許出現重複元素。可以基於這個想法,把List集合所有元素存入HashSet對象,接着把List集合元素全部清空,最後把HashSet對象元素全部添加至List集合中,這樣就可以保證不出現重複元素。而HashSet有一個構造函數,在初始化時可以直接添加元素。其中,HashSet不能保證順序不變,所以此方式不能保證List集合原來的順序不變。

代碼實現:

/**
* notes:使用HashSet實現List去重
@param list
@return
*/
public static List repeatListWayTwo(List<String> list){
  //初始化HashSet對象,並把list對象元素賦值給HashSet對象
  HashSet set = new HashSet(list);
  //把List集合所有元素清空
  list.clear();
  //把HashSet對象添加至List集合
  list.addAll(set);
  return list;
}

 

03

實現思路:TreeSet集合也是實現Set接口,是一個有序的,並且無重複元素集合。同理,我們可以根據上面方式二的思想進行去重。其中,去重后的List集合可以保證和原來的順序一致。

代碼實現:

/**
* notes:使用TreeSet實現List去重
@param list
@return
*/
public static List repeatListWayThird(List<String> list){
   //初始化TreeSet對象,並把list對象元素賦值給TreeSet對象
   TreeSet set = new TreeSet(list);
   //把List集合所有元素清空
   list.clear();
   //把TreeSet對象添加至List集合
   list.addAll(set);
   return list;
}

 

04

實現思路:利用List集合contains方法循環遍歷,先創建新的List集合,接着循環遍歷原來的List集合,判斷新集合是否包含有舊集合,如果有,則不添加至新集合,否則添加。最後,把舊集合清空,把新集合元素賦值給舊集合。

代碼實現:

/**
* notes:利用List集合contains方法循環遍歷去重
@param list
@return
*/
public static List repeatListWayFourth(List<String> list){
   //新建新List集合,用於存放去重后的元素
   List<String> newList = new ArrayList<String>();
   //循環遍歷舊集合元素
   for(int i = 0; i < list.size(); i++ ){
       //判斷新集合是否包含有,如果不包含有,則存入新集合中
       boolean isContains = newList.contains(list.get(i));
       if(!isContains){
           newList.add(list.get(i));
       }
   }
   //把List集合所有元素清空
   list.clear();
   //把新集合元素添加至List集合
   list.addAll(newList);
   return list;
}

上面給大家介紹了四種List集合去重方式。那麼,哪種方式效率是最好的呢?下面就演示一下進行對比。

為了演示方式,隨機生成0-500之間的20000個整数字符串,並存入List集合,並在相應代碼打印相關時間進行對比。其中,隨機生成List集合代碼如下:

/**
* 隨機生成0-500之間的20000個整数字符串,並存入List集合
@return
*/
public static List<String> getRandomList(){
   List<String> list = new ArrayList<String>();
   //隨機生成20000個整数字符串
   for(int i = 1; i <= 20000; i++){
       //任意取[0,500)之間整數,其中0可以取到,500取不到
       int number = new Random().nextInt(500);
       String number_str = "geshan"+number;
       list.add(number_str);
   }
   return list;
}

為了保證List集合元素一致,創建四個List集合,分別對應List去重方式。效率對比代碼如下:

public static void main(String[] args){
   //隨機生成0-500之間的1000個整数字符串List集合
   List<String> list = getRandomList();

   //為了演示四種方式效率,創建四個List集合,保證List集合元素一致
   //方式一List集合
   List<String> oneList = new ArrayList<>();
   oneList.addAll(list);
   //方式二List集合
   List<String> twoList = new ArrayList<>();
   twoList.addAll(list);
   //方式三List集合
   List<String> thirdList = new ArrayList<>();
   thirdList.addAll(list);
   //方式四List集合
   List<String> fourthList = new ArrayList<>();
   fourthList.addAll(list);

   System.out.println("方式一:使用兩個for循環實現List去重");
   System.out.println("原來集合大小:"+oneList.size()+",集合元素>>"+oneList);
   Date oneDateBegin = new Date();
   repeatListWayOne(oneList);
   System.out.println("集合去重大小:"+oneList.size()+",集合元素>>"+oneList);
   Date oneDateEnd = new Date();
   System.out.println("去重所需時間:"+(oneDateEnd.getTime()-oneDateBegin.getTime())+"毫秒");

   System.out.println("方式二:使用HashSet實現List去重");
   System.out.println("原來集合大小:"+twoList.size()+",集合元素>>"+twoList);
   Date twoDateBegin = new Date();
   repeatListWayTwo(twoList);
   System.out.println("集合去重大小:"+twoList.size()+",集合元素>>"+twoList);
   Date twoDateEnd = new Date();
   System.out.println("去重所需時間:"+(twoDateEnd.getTime()-twoDateBegin.getTime())+"毫秒");

   System.out.println("方式三:使用TreeSet實現List去重");
   System.out.println("原來集合大小:"+thirdList.size()+",集合元素>>"+thirdList);
   Date thirdDateBegin = new Date();
   repeatListWayThird(thirdList);
   System.out.println("集合去重大小:"+thirdList.size()+",集合元素>>"+thirdList);
   Date thirdDateEnd = new Date();
   System.out.println("去重所需時間:"+(thirdDateEnd.getTime()-thirdDateBegin.getTime())+"毫秒");

   System.out.println("方式四:利用List集合contains方法循環遍歷去重");
   System.out.println("原來集合大小:"+fourthList.size()+",集合元素>>"+fourthList);
   Date fourthDateBegin = new Date();
   repeatListWayFourth(fourthList);
   System.out.println("集合去重大小:"+fourthList.size()+",集合元素>>"+fourthList);
   Date fourthDateEnd = new Date();
   System.out.println("去重所需時間:"+(fourthDateEnd.getTime()-fourthDateBegin.getTime())+"毫秒");
}

多次運行結果如下:

第一次四種方式運行時間如下:223、10、16、30;

第二次四種方式運行時間如下:164、10、17、43;

第三次四種方式運行時間如下:164、9、16、37;

綜合代碼及運行時間對比,方式二是最好的去重方式,代碼最簡潔、耗時最短。你平時List集合去重,方式用對了嗎?

【精選推薦文章】

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

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

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

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

設計模式之迭代器與組合模式(四)

因為這系列篇幅較長,所以在這裏也不進行任何鋪墊,直奔主題去啦。

利用組合設計菜單

我們要如何在菜單上應用組合模式呢?一開始,我們需要創建一個組件接口來作為菜單和菜單項的共同接口,讓我們能夠用統一的做法來處理菜單和菜單項。換句話說,我們可以針對菜單或菜單項調用相同的方法。

讓我們從頭來看看如何讓菜單能夠符合組合模式的結構:

實現菜單組件

好了,我們開始編寫菜單組件的抽象類;請記住,菜單組件的角色是為恭弘=恭弘=恭弘=叶 恭弘 恭弘 恭弘節點和組合節點提供一個共同的接口。

public abstract class MenuComponent {
   
    public void add(MenuComponent menuComponent) {
        throw new UnsupportedOperationException();
    }
    public void remove(MenuComponent menuComponent) {
        throw new UnsupportedOperationException();
    }
    public MenuComponent getChild(int i) {
        throw new UnsupportedOperationException();
    }
  
    public String getName() {
        throw new UnsupportedOperationException();
    }
    public String getDescription() {
        throw new UnsupportedOperationException();
    }
    public double getPrice() {
        throw new UnsupportedOperationException();
    }
    public boolean isVegetarian() {
        throw new UnsupportedOperationException();
    }

    public abstract Iterator<MenuComponent> createIterator();
 
    public void print() {
        throw new UnsupportedOperationException();
    }
}

讓我們來看菜單類。別忘了,這是組合類圖裡的恭弘=恭弘=恭弘=叶 恭弘 恭弘 恭弘類,它實現組合內元素的行為。

public class MenuItem extends MenuComponent {
 
    String name;
    String description;
    boolean vegetarian;
    double price;
    
    public MenuItem(String name, 
                    String description, 
                    boolean vegetarian, 
                    double price) 
    { 
        this.name = name;
        this.description = description;
        this.vegetarian = vegetarian;
        this.price = price;
    }
  
    public String getName() {
        return name;
    }
  
    public String getDescription() {
        return description;
    }
  
    public double getPrice() {
        return price;
    }
  
    public boolean isVegetarian() {
        return vegetarian;
    }

    public Iterator<MenuComponent> createIterator() {
        return new NullIterator();
    }
 
    public void print() {
        System.out.print("  " + getName());
        if (isVegetarian()) {
            System.out.print("(v)");
        }
        System.out.println(", " + getPrice());
        System.out.println("     -- " + getDescription());
    }

}

我們已經有了菜單項,還需要組合類,這就是我們叫做菜單的。別忘了,此組合類可以持有菜單項或其他菜單。

public class Menu extends MenuComponent {
    Iterator<MenuComponent> iterator = null;
    ArrayList<MenuComponent> menuComponents = new ArrayList<MenuComponent>();
    String name;
    String description;
  
    public Menu(String name, String description) {
        this.name = name;
        this.description = description;
    }
 
    public void add(MenuComponent menuComponent) {
        menuComponents.add(menuComponent);
    }
 
    public void remove(MenuComponent menuComponent) {
        menuComponents.remove(menuComponent);
    }
 
    public MenuComponent getChild(int i) {
        return menuComponents.get(i);
    }
 
    public String getName() {
        return name;
    }
 
    public String getDescription() {
        return description;
    }

  
    public Iterator<MenuComponent> createIterator() {
        if (iterator == null) {
            iterator = new CompositeIterator(menuComponents.iterator());
        }
        return iterator;
    }
 
 
    public void print() {
        System.out.print("\n" + getName());
        System.out.println(", " + getDescription());
        System.out.println("---------------------");
    }
}

因為菜單是一個組合,包含了菜單項和其他的菜單,所以它的print()應該打印出它所包含的一切。如果它不這麼做,我們就必須遍歷整個組合的每個節點,然後將每一項打印出來。這麼一來,也就失去了使用組合結構的意義

所以,print還得進行優化,如下:

public void print() {
    System.out.print("\n" + getName());
    System.out.println(", " + getDescription());
    System.out.println("---------------------");
 
    Iterator<MenuComponent> iterator = menuComponents.iterator();
    while (iterator.hasNext()) {
        MenuComponent menuComponent = iterator.next();
        menuComponent.print();
    }
}

看到上面了沒,我們用了迭代器。用它遍歷所有菜單組件,遍歷過程中,可能遇到其他菜單,或者是遇到菜單項。由於菜單和菜單項都實現了print,那我們只要調用print即可。

開始測試數據之前,我們了解一下,在運行時菜單組合是什麼樣的:

開始運行我們的測試程序啦:

public class MenuTestDrive {
    public static void main(String args[]) {

        MenuComponent pancakeHouseMenu = 
            new Menu("PANCAKE HOUSE MENU", "Breakfast");
        MenuComponent dinerMenu = 
            new Menu("DINER MENU", "Lunch");
        MenuComponent cafeMenu = 
            new Menu("CAFE MENU", "Dinner");
        MenuComponent dessertMenu = 
            new Menu("DESSERT MENU", "Dessert of course!");
  
        MenuComponent allMenus = new Menu("ALL MENUS", "All menus combined");
  
        allMenus.add(pancakeHouseMenu);
        allMenus.add(dinerMenu);
        allMenus.add(cafeMenu);
  
        pancakeHouseMenu.add(new MenuItem(
            "K&B's Pancake Breakfast", 
            "Pancakes with scrambled eggs, and toast", 
            true,
            2.99));
        pancakeHouseMenu.add(new MenuItem(
            "Regular Pancake Breakfast", 
            "Pancakes with fried eggs, sausage", 
            false,
            2.99));
        pancakeHouseMenu.add(new MenuItem(
            "Blueberry Pancakes",
            "Pancakes made with fresh blueberries, and blueberry syrup",
            true,
            3.49));
        pancakeHouseMenu.add(new MenuItem(
            "Waffles",
            "Waffles, with your choice of blueberries or strawberries",
            true,
            3.59));

        dinerMenu.add(new MenuItem(
            "Vegetarian BLT",
            "(Fakin') Bacon with lettuce & tomato on whole wheat", 
            true, 
            2.99));
        dinerMenu.add(new MenuItem(
            "BLT",
            "Bacon with lettuce & tomato on whole wheat", 
            false, 
            2.99));
        dinerMenu.add(new MenuItem(
            "Soup of the day",
            "A bowl of the soup of the day, with a side of potato salad", 
            false, 
            3.29));
        dinerMenu.add(new MenuItem(
            "Hotdog",
            "A hot dog, with saurkraut, relish, onions, topped with cheese",
            false, 
            3.05));
        dinerMenu.add(new MenuItem(
            "Steamed Veggies and Brown Rice",
            "A medly of steamed vegetables over brown rice", 
            true, 
            3.99));
 
        dinerMenu.add(new MenuItem(
            "Pasta",
            "Spaghetti with Marinara Sauce, and a slice of sourdough bread",
            true, 
            3.89));
   
        dinerMenu.add(dessertMenu);
  
        dessertMenu.add(new MenuItem(
            "Apple Pie",
            "Apple pie with a flakey crust, topped with vanilla icecream",
            true,
            1.59));
        dessertMenu.add(new MenuItem(
            "Cheesecake",
            "Creamy New York cheesecake, with a chocolate graham crust",
            true,
            1.99));
        dessertMenu.add(new MenuItem(
            "Sorbet",
            "A scoop of raspberry and a scoop of lime",
            true,
            1.89));

        cafeMenu.add(new MenuItem(
            "Veggie Burger and Air Fries",
            "Veggie burger on a whole wheat bun, lettuce, tomato, and fries",
            true, 
            3.99));
        cafeMenu.add(new MenuItem(
            "Soup of the day",
            "A cup of the soup of the day, with a side salad",
            false, 
            3.69));
        cafeMenu.add(new MenuItem(
            "Burrito",
            "A large burrito, with whole pinto beans, salsa, guacamole",
            true, 
            4.29));
 
        Waitress waitress = new Waitress(allMenus);
   
        waitress.printVegetarianMenu();
 
    }
}

結果這裏就不附上了,請大家自行去跑代碼實現吧。相信你們又對組合模式也已經有了一個大概了吧。下一篇,還有更犀利的,組合迭代器等着我們。小編馬上回去搞起來,安排上。

愛生活,愛學習,愛感悟,愛挨踢

【精選推薦文章】

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

想要讓你的商品在網路上成為最夯、最多人討論的話題?

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

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

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

ASC19最新戰況:北航打破HPL基準測試賽會紀錄!

ASC19最新戰況:北航打破HPL基準測試賽會紀錄!

2019-04-23 23:32    原創  作者: 謝濤 編輯:
0購買

  【IT168現場報道】今天(4月23日)是全球矚目的ASC19全球總決賽第三天,經過前两天的系統搭建與調試工作后,20支隊伍進入了正式競賽階段,向總冠軍寶座發起最後衝刺。

  根據賽程,今天所有參賽隊伍需要完成的項目包括超級計算機性能基準測試HPL&HPCG、超級團隊對抗賽賽題Fluidity以及全球氣候變化模式CESM——其中,CESM是今年“e Prize計算挑戰獎”的指定賽題。

  上午十二時左右,組委會公布了第一項賽題HPL的成績,在3000瓦功耗約束下,北京航空航天大學代表隊以每秒50.21萬億次浮點運算的成績打破了賽會紀錄,在HPL賽題單項成績上排名第一。

  HPL是國際通用的超級計算機浮點性能基準測試程序,是全球超算TOP500榜單評比的重要依據,主要考察參賽隊伍對硬件平台的浮點計算性能優化能力。ASC競賽的HPL計算性能測試有嚴格的規定,各參賽隊伍需要在功耗不高於3000W的約束下,採用組委會統一提供的超算節點、高速網絡和自行配置加速卡等設備,完成超算系統搭建。

  HPL測試側重於系統的整體運行能力和峰值性能,這個項目考察參賽隊伍在搭建系統、性能優化和配置選擇上的綜合能力。為了取得更好的成績,參賽隊伍需要從超算系統體繫結構、多級存儲一致性、高速網絡、算法優化等不同角度,進行全方位的深入研究,在不同方案之間進行抉擇,通過反覆優化和測試獲得更高的運算性能。

  在這一項目上,歷屆ASC大賽總能給我們帶來驚喜,充分體現了“百尺竿頭,更進一步”的積極進取精神。ASC15,來自新加坡的南洋理工大學以11.92萬億次浮點運算/秒的成績打破上一年的紀錄;ASC16,該紀錄被浙江大學以12.03萬億次浮點運算/秒的成績刷新;ASC17,濰坊學院代表隊創下31.7萬億次浮點運算/秒的新紀錄;ASC18,也就是去年,台灣清華大學獲得42.99萬億次浮點運算/秒的成績,再次刷新紀錄。

  今年,北京航空航天大學則以50.21萬億次/秒的驚人成績又一次打破賽會紀錄,在現場引起一片呼聲。該代表隊設計了“3機12卡”的異構超算系統,共採用3台浪潮AI超算服務器NF5280M5配置12塊NVIDIA Tesla系列V100加速卡。值得一提的是,北京航空航天大學在預賽期間就曾獲得了第一名的好成績。

  根據ASC19競賽組委會的介紹,明天(4月24日)將公布正式競賽第一天其餘賽題的成績,包括HPCG、Fluidity、CESM。此外,參賽隊伍還將完成人工智能賽題人臉圖像超分辨率(Face SR)、中國科學家研發的第三代基因測序組裝軟件wtdbg以及一個神秘應用賽題。

  在這些賽題上,各位參賽隊伍又將給我們帶來哪些驚喜呢?大家一起期待明天的結果吧!

  4月24日下午,第21屆國際超算高峰論壇將在大連理工大學隆重舉行。全球超級計算機排行榜TOP500提出人、ASC競賽專家委員會主席、田納西大學傑出教授Jack Dongarra,憶阻器提出人加州大學伯克利分校教授Leon Chua(蔡少棠)等多位知名國際國內專家將出席並進行主題報告與分享,與參會嘉賓就超算話題展開思想碰撞。

  IT168將對本次大賽進行全程報道,了解大賽更多信息,請持續關注:http://zt.itpub.net/topic/ASC19/

, ,

網站內容來源http://server.it168.com/本站聲明:網站內容來源http://www.it168.com/,如有侵權,請聯繫我們,我們將及時處理

【精選推薦文章】

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

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

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

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

采埃孚coPILOT助力提升安全性與駕駛舒適性

采埃孚coPILOT助力提升安全性與駕駛舒適性

2019-04-24 11:46    原創  作者: 陶然 編輯:
0購買

  近日,采埃孚宣布推出采埃孚coPILOT智能高級駕駛輔助系統(ADAS),助力提升安全性和駕駛舒適性。藉助AI的強大功能同時配備全面的傳感器組,車輛能夠執行各類自動駕駛功能。在高速公路行駛時,該輔助系統的功能尤為突出。此外,采埃孚coPILOT可通過語音指令進行操作,識別交通狀況,感知車輛操控並監控駕駛員,並且能夠通過主動控制干預來幫助預防危險情況發生。采埃孚coPILOT基於采埃孚ProAI中央計算機和NVIDIA DRIVE平台,專為量產而設計,預計將於2021年開始供貨。

  距離采埃孚和NVIDIA宣布“采埃孚ProAI成為首個運行NVIDIA DRIVE軟件的系統”僅三個月後,采埃孚coPILOT就在上海國際汽車工業展覽會上首次亮相。兩家高科技公司共同推出這一極具吸引力的 “L2+級”自動駕駛輔助系統,可提高乘用車的安全性和駕駛舒適性。

  采埃孚先期開發工程部門負責人兼采埃孚風險投資公司(Zukunft Ventures GmbH)總經理TorstenGollewski表示:“采埃孚coPILOT配備了人工智能、360度全方位傳感器組、功能強大的采埃孚ProAI中央計算機以及NVIDIA DRIVE平台,可實現高於常規L2級系統的駕駛和安全功能。這使我們能夠實現更高性能的半自動駕駛。”

  采埃孚coPILOT演示車將在上海車展首次亮相,詳細展示其功能範圍以及其為駕駛員所提供的舒適性與安全性:車輛可自主執行特定的駕駛操作,例如在適當情況下進出高速公路。對於相對輕鬆的高速公路駕駛,采埃孚coPILOT將先進的巡航控制系統與主動轉向輔助功能和車道保持輔助功能相結合。此外,采埃孚coPILOT能夠主動變道、穿行和並道,還能持續分析車輛周圍環境,識別行人、對面車輛和交叉路口。

  采埃孚coPILOT配備了相應的傳感器和功能,能夠監控駕駛員並在發生潛在危險情況時觸發警告。例如,當發生駕駛員注意力不集中、幾乎完全未將注意力放在路面交通上或显示出瞌睡跡象等狀況時,警告將會被觸發。此外,采埃孚coPILOT還能夠進行智能路線引導,包括“MyRoute”這一能夠識別重複路線的地圖功能。該系統還配備了語音識別功能,駕駛員能夠通過語音指令便捷地啟用並操作駕駛員輔助功能;在駕駛員想要手動駕駛時,也可以通過語音指令對其禁用。

  在演示車輛中,搭載的采埃孚傳感器組包括一個前置雷達、四個角雷達以及八個攝像頭。其中,兩個攝像頭向前,一個向後,還有兩個分別集成在兩個側鏡中,一個負責監控駕駛員。

  為評估整套傳感器組實時收集的大量數據,高性能處理能力必不可少。這正是采埃孚coPILOT所採用的第二代采埃孚ProAI中央計算機的用武之地:以NVIDIA DRIVE Xavier處理器的高性能、高能效計算能力為核心,采埃孚ProAI可集成並完全控制預訓練算法,實現所有駕駛員輔助功能。該系統具有靈活性、可擴展性且能夠無縫更新。汽車製造商還可以根據需求添加自主開發或采埃孚開發的其他特性和功能。

  采埃孚ProAI產品系列包括從L0級到L5級的四種型號,覆蓋了整個自動駕駛運行範圍。高端型號采埃孚ProAIRoboThink每秒運行速度高達600萬億次(600 teraOPS),是目前移動出行領域功能最強大的AI超級計算機。

  高級駕駛員輔助 隨時隨地,隨您所需

  SAE L3級高度自動駕駛在許多國家和地區暫未被允許,因此采埃孚coPILOT提供SAE L2級半自動駕駛,要求駕駛員持續監控交通狀況。但采埃孚和NVIDIA所提供的L2+級技術更加強大,能夠起到可靠且便利的輔助駕駛作用,如同“私人駕駛助手”一般為駕駛員提供支持。

  “我們相信,像采埃孚coPILOT這樣的擴展型L2+級系統對製造商來說非常具有吸引力:鑒於其廣泛的功能,它在安全性和駕駛舒適性方面為消費者提供了明顯的附加值,且在價格方面也很具有競爭力,”TorstenGollewski如是說。

網站內容來源http://server.it168.com/本站聲明:網站內容來源http://www.it168.com/,如有侵權,請聯繫我們,我們將及時處理

【精選推薦文章】

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

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

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

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

​解讀浪潮“元腦”:不是AI大腦,欲引爆AI應用的工業化量產

​解讀浪潮“元腦”:不是AI大腦,欲引爆AI應用的工業化量產

2019-04-24 15:26    來源:廠商稿  作者: 廠商動態 編輯:
0購買

  文章來源:雲科技時代

  2016年以來,AI人工智能遍地開花。以神經元網絡為代表的深度學習成為了風靡大街小巷的熱詞,人工智能和深度學習技術創業公司如雨後春筍般湧現,各種深度學習開源框架、人工智能大腦和服務以及國際AI大賽跑分成為常態。進入2019年,全國共有35所高校獲首批“人工智能”新專業建設資格、96所高校獲批“智能科學與技術”專業、101所高校獲批“機器人工程”專業,人工智能也入選了《普通高中信息技術課程標準》新課標。

  儘管全民對於人工智能的熱情高漲,但人工智能的產業化以及在各產業和行業中推進人工智能應用,仍面臨着重重阻礙。“當前人工智能計算的業態還是相當分散的,需要買不同的機器、服務和加速卡等,還要自己配置人工智能應用環境、搭建人工智能框架,處理數據、模型和計算的管理、共享、調度等,這對客戶來說太複雜了,不知道怎麼做。”浪潮AI與HPC總經理劉軍在4月16日2019浪潮雲數據中心合作夥伴大會(IPF2019)上接受採訪時坦言,“合作夥伴更怕在幾十種選擇中組合,人工智能的生意很難做。”

  2018年Gartner與中國信通院合作的《2018世界人工智能產業發展藍皮書》也指出:人工智能仍處於早期採用階段,僅有4%的被調研企業已經投資並部署了AI技術,許多企業還處在正在考慮採用AI和規劃AI的階段。在Gartner的AI技術成熟度曲線中,仍有許多AI的相關技術都擁堵在期望膨脹期,要過渡到生產實施階段仍非常困難。此外,AI技術的碎片化十分嚴重,據藍皮書統計在中國市場就有上千家各類AI技術供應商。

  在IPF2019大會上,浪潮發布了“元腦”:打包了計算、算法、框架、PaaS以及服務的一站式人工智能解決方案交付。劉軍表示,“元腦”不是人工智能“大腦”,而是“大腦”的核心,浪潮希望與合作夥伴一起,基於“元腦”快速“量產”各行業的人工智能應用和“大腦”。劉軍表示,“元腦”的意義不亞於當年的福特T型車,福特並不是汽車的發明者,但T型車開創了汽車工業化時代,浪潮也希望“元腦”能開創人工智能應用的工業化時代。

  

  浪潮發布“元腦”

  1908年福特T型車的啟示

  1908年是人類歷史上一個重要的年份,這一年福特推出了歷史上著名的T型車。1903年成立的福特公司,並不是汽車的發明者。從1886年的世界上第一輛四輪汽車,到1893年發明了化油器以及1896年發明了石棉製動片和轉向盤等,汽車的結構越來越趨向現代汽車。但1908年的福特T型車,則首次讓汽車以低廉的價格走入了尋常百姓家,T型車不僅開創了現代汽車工業,更成就了“車輪上的國家”——美國。

  T型車的生產製造過程,開創了革命性的流水裝配線,代替了之前的個體手工製作方式。T型車是世界上第一種以大量通用零部件進行大規模流水線裝配作業而生產製造出來的汽車,1913年到1914年經過優化的流水裝配線可以在93分鐘內生產一輛汽車,超過同期其它所有汽車生產商生產能力的總合。最開始,T型車以競爭車型1/3的價格推動了汽車的普及,1920年後進一步降低到其它競爭車型1/10價格,讓普通生產線工人也能購買屬於自己的汽車。直到1927年停產,共生產了1500萬輛T型車,這一紀錄保持了近一個世紀。

  浪潮“元腦”就是福特T型車這樣的定位:不僅要開創人工智能應用的工業化量產,還要創造T型車這樣的爆款產品。此前,浪潮已經推出了一個AI爆款產品,這就是2017年推出的AGX-2 2U GPU服務器。2017年5月,浪潮推出了第一版的AGX-2 2U GPU服務器,當時是全球首款在2U空間內高速互聯集成8顆最高性能GPU加速器的服務器,2018年3月更新支持了最新的NVIDIA架構,成為全球性能最高的AI 2U服務器。儘管後來浪潮又發布了超級AI服務器AGX-5,但AGX-2仍然是受到廣大用戶喜歡的爆款產品。

  在運營商領域:浪潮AGX-2中標中國電信人工智能服務器集中採購,份額高達40%,大規模用於智能營業廳、智能推薦等場景人工智能訓練;中國移動子公司咪咕文化科技有限公司(簡稱:咪咕)2018年GPU服務器採購項目中,浪潮獲得億元採購訂單一半份額,為咪咕提供涵蓋創新AI服務器AGX-2在內的AI解決方案。在金融領域:AGX-2幫助招商銀行建設了先進的大數據智能平台以及多種人工智能應用場景。在視頻物聯等領域:海康威視的視頻人工智能訓練平台100%基於AGX-2,而大華以AGX-2為核心的人工智能解決方案,在智慧城市、雪亮工程、平安城市等多個領域落地。

  有了前面的這些市場基礎,在2019年,浪潮希望進一步高度集成AI技術、產品和服務於“元腦”,用“元腦”打開人工智能應用的工業化生產變革。

  浪潮“元腦”的構成

  什麼是浪潮“元腦”呢?具體來說包括以下組成部分:

  · 超強AI計算系統:通過浪潮人工智能計算平台、人工智能超高速計算加速卡、極低延遲RDMA網絡與超高帶寬并行存儲,共同提供極致人工智能計算性能;

  · 敏捷AI Paas平台:由極致優化的AI資源平台、極速流程化AI開發平台、開放兼容的AI生態平台和秒速構建AI軟件棧。最新開發的人工智能PaaS平台AIStation面向人工智能企業訓練場景,可實現容器化部署、可視化開發、集中化管理等,有效打通開發環境、計算資源與數據資源,提升開發效率;

  · 高效的Auto ML Suite:最新開發的AutoML Suite可實現非專業人員亦能通過極少操作構建網絡模型並獲得高精度,極大降低了人工智能開發、應用的門檻和成本。在2018年的NIPS 的自動機器學習挑戰賽中,浪潮與北京郵電大學、中南大學團隊合作,獲得自動機器學習領域的國際頂尖賽事的全球第三佳績。

  · 整合一體化交付:計算/存儲/網絡一體化、內置AI Paas平台、內置建模優化工具、預配置系統調優。

  

  中國工程院院士、浪潮集團執行總裁王恩東

  IPF 2019大會的主題為“智慧凝聚”,中國工程院院士、浪潮集團執行總裁王恩東的大會主題演講題目為《人工智能計算 未來核心動力》以及提出了人工智能三大趨勢——融合、開放、敏捷,這兩大主題和三大趨勢都透露了浪潮要“凝聚”過去幾年在人工智能方面的重大投資,並希望用融合、開放和敏捷的人工智能產品及解決方案拉升数字經濟大勢的想法和思路。而浪潮“元腦”就是基於融合、開放和敏捷的人工智能工業化生產線裝配出來的“T型車”。

  激進拉升千億市場到萬億

  “2018年,浪潮與合作夥伴一起創造了諸多令人振奮的成績,見證了服務器產業的快速發展,也體驗了人工智能產業的爆髮式增長。”王恩東在IPF 2019上如是表示。他認為,人工智能發展能為中國經濟帶來巨大增長機遇,據有關預測,到2035年人工智能領域的經濟總量將佔所有經濟的20%,所以“計算力就是生產力,而人工智能計算則是核心計算力”。

  在人工智能時代,浪潮認為有兩大市場:一個是千億的人工智能產業市場,另一個是萬億的產業人工智能市場。一方面,浪潮通過技術產品化、產品市場化,推動AI科技公司的技術成果轉化,也就是AI產業化的過程,創造和實現千億市場價值。另一方面就是產業AI化,即在傳統產業和行業的轉型和升級中,行業ISV和分銷渠道商鏈接着眾多客戶,浪潮通過生態協作方式,把AI計算平台、AI科技公司的技術能力和ISV的行業方案進行整合,通過分銷渠道交付到各行各業,從而撬動萬億級市場。

  那麼,如何普及人工智能計算這種先進的新型生產力?生產力有三大要素:生產力、生產工具和生產資料。其中,浪潮“元腦”就已經交付了先進了生產工具。浪潮集團副總裁彭震強調,浪潮“元腦”提供了一體化的解決方案,把浪潮的人工智能計算能力、存儲能力、網絡能力以及人工智能PaaS平台、AutoML Suite自動算法調優工具等集合在一起,通過浪潮專家的預配置、預調優、預集成,實現了完整平台級解決方案。

  

  浪潮集團副總裁彭震

  接下來就需要把浪潮“元腦”這樣的先進生產工具交付到更多的勞動者手中,讓他們在數據這種新型“生產資料”上,創造更多新型的人工智能應用。為了達成這一目標,光依靠浪潮自己遠遠不夠,還需要動員龐大渠道生態合作夥伴體系。截止至2018年底,浪潮共有9000多家合作夥伴,人工智能百強超過80家與浪潮建立了合作關係;合作夥伴業務增長116%,分銷夥伴增長124%;浪潮與合作夥伴開發聯合解決方案400多個,其中人工智能聯合方案20多個。

  為了把合作夥伴帶入人工智能時代,讓更多的合作夥伴儘早入場人工智能,劉軍表示浪潮將有可能採取激進的策略,包括激進的價格策略以激發整體的人工智能大市場。劉軍強調,人工智能產業和產業人工智能化都處於初期階段,浪潮在這個階段的策略不是自己實現更多的營收,而是要拉動合作夥伴都能獲益。儘管很多合作夥伴對於如何做人工智能生意還有很大的困惑,但劉軍認為“不要在岸上看,一起下來‘游泳’”。

  當然,浪潮也做好了充分的準備。浪潮集團渠道管理部總經理王峰在IPF 2019上提出了浪潮合作生態2.0,將要扮演的三個新角色:生態孵化器、AI試驗場和AI放大器。生態孵化器指的是浪潮將積極幫助AI技術公司、行業ISV以及分銷商,完成AI產品、應用和市場孵化,特別是針對區域行業客戶的AI場景,以及培養更多的AI人才;AI試驗場,指的是浪潮“元腦”與AI技術公司針對不同AI場景應用的聯合方案開發、預裝與轉售,通過浪潮方案創新平台InCloud Lab與行業ISV完成AI產品和方案的POC測試和驗證,以及通過浪潮分銷業務體系面向中小行業客戶的AI應用一體化產品;AI放大器,指的是浪潮將與合作夥伴、AI算法夥伴、AI場景應用+行業ISV夥伴一起,完成多行業的複製、推動多產業的AI化,其中包括面向全行業的行業標桿客戶AI應用以及面向區域市場客戶的一體化AI應用方案產品。

  浪潮在AI渠道總體上的2019目標是:發展 200家AI算法夥伴,每個夥伴要有面向行業場景的算法軟件,至少發布一個AI場景應用、培養AI場景應用認證工程師;發展400家AI方案集成夥伴 ,每個夥伴要有行業應用解決方案、行業AI應用整合和交付能力,要落地三個行業客戶AI應用方案、舉行一次行業客戶AI應用推薦、培養AI行業應用認證工程師;以及80家分銷商和2400經銷商組成的AI方案產品銷售夥伴,每個夥伴要有區域客戶AI應用產品交付和服務能力,每個分銷商要激活30家AI產品銷售經銷商以及通過AI應用產品銷售工程師認證。

  2019年,浪潮渠道還將特別聚焦計算機視覺、語音識別、自然語言識別、量化交易等四大基礎AI應用場景,集中發展100家以上算法合作夥伴,幫助400家以上的行業ISV建立AI能力,在金融、企業、通信、教育、零售、醫療、媒體和互聯網等8大行業落地客戶。

  總體來說,IPF 2019拉開了人工智能應用的工業化時代,是浪潮過去幾年在人工智能計算領域投資的大匯總和高度凝練,是對渠道生態合作夥伴的總動員,其意義不亞於浪潮在2015年所提出的“計算+”戰略及“硬件重構”和“軟件定義”核心。在智慧時代,AI與產業深度融合的大幕已經拉開,“融合、開放、敏捷”將要定義新的計算力——人工智能計算。

,

網站內容來源http://server.it168.com/本站聲明:網站內容來源http://www.it168.com/,如有侵權,請聯繫我們,我們將及時處理

【精選推薦文章】

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

想要讓你的商品在網路上成為最夯、最多人討論的話題?

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

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

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

冠軍倒計時:參賽隊員眼中的ASC19

冠軍倒計時:參賽隊員眼中的ASC19

2019-04-24 20:34    原創  作者: 謝濤 編輯:
0購買

  【IT168 現場報道】4月24日,ASC19全球總決賽第四天。經過緊張的两天系統搭建與調試后,來自全球各大高校的百位新生代“超算之星”們,將在明天迎來他們最後的答案。

  在這段時間里,這些熱愛超算技術的大學生們在七大賽題上同台競技、各展風采,也在超級團隊對抗賽中與其他隊伍積極交流、通力合作,共同完成超級賽題。既磨練了自己的專業技能,也與更多志同道合的同學建立了親密聯繫。無論成績好壞,他們都已經在ASC舞台上完成了對自我的挑戰,向更高的未來走去。

  

參賽學生接受採訪

  ASC世界大學生超級計算機競賽是由中國發起的世界最大規模的大學生超算競賽,從2012年至今,已為全球超過1400支參賽隊伍、超過7000 名年輕人才搭建了一個展現自我,相互交流的平台,推動了各國、各地區超算人才培養,以及行業應用與技術研發能力的提升。

  按照大賽規則,20支進入全球總決賽的參賽隊伍,在完成前期的競賽系統搭建與調試后,需要在两天時間內完成超級計算機性能基準測試HPL&HPCG、超級團隊對抗賽賽題Fluidity、全球氣候變化模式CESM、人工智能賽題人臉圖像超分辨率(Face SR)、中國科學家研發的第三代基因測序組裝軟件wtdbg以及一個神秘應用賽題。

  每支參賽隊伍的最終成績將根據HPL、HPCG、CESM、Face SR、wtdbg以及神秘賽題的單項成績進行綜合評定,而超級團隊對抗賽則單獨設置了獎項,不計入最終結果。雖然目前ASC19競賽組委會已公布了HPL、HPCG、CESM的成績,但冠軍最後將花落誰家仍然難以預測——如我們所見,單項賽題的成績並不能代表最終成績。

  今年首次設置的超級團隊對抗賽的結果也已經出爐,中山大學、太原理工大學、香港中文大學、德國埃爾朗根-紐倫堡大學組成的團隊最終獲得了“超級團隊獎”,這四支隊伍將平分總計2萬元的獎金。獎勵只是一方面,更重要的是參賽隊員們與來自其他國家、地區、高校的同學們在完成挑戰賽題的過程中,進行了積極踴躍的溝通,彼此學習、共同提高。

  作為世界最大規模的大學生超算競賽,ASC面向前沿技術領域,無論是近幾年加入的AI賽題,還是今年首次設置的超級團隊對抗賽,大賽每年在賽題設置上都會給人帶來新的驚喜。許多參賽學生都表示,有機會使用行業領先的計算硬件親自動手設計、搭建一台超級計算機,完成極具挑戰性的前沿應用賽題,對他們來說是一個非常寶貴的經驗。

  而同學們在競賽中展現出的進取精神也同樣讓人備受感染,他們在競賽中取得的優秀成績令人驚嘆,在他們身上,我們看到了超算行業的廣闊前景與光明未來。隨着超級計算機從科研、氣象等領域向互聯網、製造等更多行業普及應用,超算已成為驅動科技與產業創新的重要力量。在這之中,超算人才的培養是重中之重,ASC競賽以全球化的影響力,獲得了社會各界的認可。

  明天(4月25日)下午,ASC19總決賽閉幕式暨頒獎儀式將隆重舉行,這些辛苦了四天的參賽隊員們,將迎來屬於他們的高光時刻。

  點擊進入IT168的ASC19賽事報道專區,即可在線觀看閉幕式現場視頻直播。

,

網站內容來源http://server.it168.com/本站聲明:網站內容來源http://www.it168.com/,如有侵權,請聯繫我們,我們將及時處理

【精選推薦文章】

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

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

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

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

ASC19世界超算大賽:8分鐘全程亮點回顧

ASC19世界超算大賽:8分鐘全程亮點回顧

2019-04-25 16:45    來源:廠商稿  作者: 張靜 編輯:
0購買

ASC19世界超算大賽落幕,兩岸清華分獲冠亞軍。8分鐘全程亮點回顧,看超算青年決戰大連理工賽場。

本站聲明:網站內容來源http://www.it168.com/,如有侵權,請聯繫我們,我們將及時處理

【精選推薦文章】

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

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

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

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

ASC19完美落幕:台灣清華大學獲得全球總冠軍

ASC19完美落幕:台灣清華大學獲得全球總冠軍

2019-04-27 18:32    原創  作者: 謝濤 編輯:
0購買

  【IT168 現場報道】4月25日,2019 ASC世界大學生超級計算機競賽(ASC19)總決賽閉幕式暨頒獎儀式在海創大連科技交流中心隆重舉行。至此,ASC競賽正式走過了它的第八個年頭。

  根據大賽組委會評定,由台灣清華大學奪得總冠軍,清華大學獲得亞軍,中山大學獲得e Prize計算挑戰獎,北京航空航天大學獲得最高計算性能獎,哥倫比亞EAFIT大學、暨南大學、南方科技大學獲得應用創新獎,哥倫比亞EAFIT大學、南方科技大學獲得最佳人氣獎。

  “超級團隊獎”最終由中山大學、太原理工大學、香港中文大學、德國埃爾朗根-紐倫堡大學組成的團隊獲得。超級團隊對抗賽於今年首次設置,進入決賽的20強隊伍以現場抽籤的方式組成了5個超級團隊,以跨團隊合作的形式共同完成超級賽題“Fluidity”,此項賽題的成績不計入總決賽結果,僅用於評定“超級團隊獎”。

  作為由中國發起的世界最大規模的大學生超算競賽,ASC競賽旨在通過大賽平台推動各國及地區間超算青年人才交流和培養,提升超算應用水平和研發能力,發揮超算的科技驅動力,促進科技與產業創新。

  本屆ASC超算競賽由亞洲超算協會、浪潮集團和大連理工大學等單位聯合主辦,共有來自全球不同地區的300餘支高校隊伍報名,並在預賽期間決出20強戰隊,參加全球總決賽。

  賽題設置涵蓋多個前沿應用領域

  在賽題設置上,ASC超算競賽一直緊密關注信息技術的前沿應用領域。本屆賽題涵蓋了氣候、流體力學、生命科學、材料計算、人工智能等領域,包括超級計算機性能基準測試HPL&HPCG、全球氣候變化模式CESM、人工智能賽題人臉圖像超分辨率(Face SR)、中國科學家研發的第三代基因測序組裝軟件wtdbg2、神秘應用賽題ShengBTE,以及超級團隊對抗賽賽題Fluidity。

  關於神秘賽題與超級團隊賽題,ShengBTE軟件包由法國的Mingo和Carrete教授共同開發,是一個基於完整的迭代解決方案求解聲子的玻爾茲曼輸運方程軟件包。Fluidity 是計算流體力學的三維軟件包,基於有限元/控制體積法,能夠解決網格的任意移動和網格分辨率隨時間的變化而變化的問題。

ASC發起人、中國工程院院士、浪潮集團首席科學家王恩東

  閉幕式上,ASC發起人、中國工程院院士、浪潮集團首席科學家王恩東先生在致辭中表示:“今年的ASC賽題涵蓋了眾多前沿應用領域,意在幫助大學生們提高動手實踐能力、開拓創新思維,同時鼓勵創新、激勵學生們不斷向科學高峰攀登。未來,希望ASC大賽能夠持續推動超算人才的培養,推動超算與人工智能的融合發展,推動科技與社會的進步。”

  參賽隊伍表現優異,創造更多亮眼瞬間

  根據決賽規則,各隊需要採用組委會統一提供的硬件設備,完成超算系統搭建與調試,並在功耗不高於3000W的約束下完成以上賽題。

  成功奪得總冠軍獎盃的台灣清華大學代表隊,在HPL、HPCG、CESM以及ShengBTE等賽題上均取得了非常好的成績,整體表現優異,冠軍當之無愧。

  在基準測試HPL方面,預賽階段曾獲得第一名好成績的北京航空航天大學代表隊創下每秒50.21萬億次浮點運算性能的驚艷成績,獲得最高計算性能獎。成為繼ASC18台灣清華大學之後,刷新ASC大賽該項記錄又一支優秀隊伍。

  在超級團隊對抗賽中,中山大學代表隊的表現同樣讓人眼前一亮。中山大學隊員另闢蹊徑,使用了Docker技術製造鏡像,並分發給團隊中的兄弟隊伍使用,避免了複雜的安裝過程,最終幫助團隊獲得了“超級團隊獎”。

  ASC19完美落幕

  隨着計算力的提高,高性能計算(HPC)在科研以及互聯網、醫療、製造、金融等更多領域擁有廣泛應用,已成為科研與產業創新發展的重要支撐。如今,整個行業對HPC技術與應用人才的需求十分迫切。ASC大賽不僅激發了大學生對HPC的興趣與熱愛,培養了學生的動手實踐與創新思維能力,更為全球各個國家的年輕人才搭建了一個互相學習與交流的平台。隨着ASC影響力與規模的持續擴大,相信它將進一步驅動HPC行業的發展與進步。

, ,

本站聲明:網站內容來源http://www.it168.com/,如有侵權,請聯繫我們,我們將及時處理

【精選推薦文章】

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

想要讓你的商品在網路上成為最夯、最多人討論的話題?

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

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

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

全球最大AI服務器供應商,浪潮攜“元腦”再出擊

全球最大AI服務器供應商,浪潮攜“元腦”再出擊

2019-04-28 13:29    來源:廠商稿  作者: 廠商動態 編輯:
0購買

文章來源:半導體行業觀察  

      過去幾年5G和人工智能(英語:Artificial Intelligence,縮寫為AI)的火爆,不但帶動了應用端、算法和相關ASIC芯片的繁榮,在服務器端也在推動創新。

  這一方面是因為AI產生的海量數據需要服務器提供更多的運算能力支持,另一方面5G帶來的應用場景需要服務器做相應的轉變。而浪潮作為國內首屈一指的服務器供應商,正在引領並推動這場變革。

  在日前主題為“智慧凝聚”的浪潮雲數據中心合作夥伴大會(IPF)上,這家走在最前線的大廠給我們分享了他們對於AI和服務器現在和未來發展的一些看法。

  全球服務器市場第三,AI服務器頭號領頭羊

  在IPF 2018上,浪潮提出了做服務器全球第一的目標。雖然這是一個艱難的目標,但我們可以看到,浪潮服務器在2018年實現了84.4%的增長率,是全球服務器增長率的2.5倍。而在全球前三的服務器廠商中,排名第三的浪潮更是唯一一家2018年服務器出貨量同比2017年有增長的企業。在國內,浪潮則是毫無爭議的服務器領頭羊,其31%的份額遙遙領先於其他廠商。

  至於AI服務器方面,浪潮更是當之無愧的大贏家。資料显示,這個業務51.4%的國內市場都被浪潮承包了。公司也憑藉在AI服務器的提早布局,迅猛發展為全球領先的AI服務器供應商。

  

  中國工程院院士、浪潮集團執行總裁王恩東先生

  按照中國工程院院士、浪潮集團執行總裁王恩東的說法,這主要通過他們發布的領先產品和眾多夥伴合作實現的。王恩東指出,浪潮建立了人工智能全棧的生態、多樣化的人工智能加速卡、超過20款的人工智能服務器、成熟的人工智能開發PaaS平台以及強大的人工智能框架優化能力。

  同時,浪潮在人工智能生態上也進行了巨大投入,這就幫助他們在這個產業里建立起了廣泛的合作。

  

  據王恩東介紹,浪潮在2018年與合作夥伴推出了400多個聯合解決方案,銷售額達到了200多個億。而公司現在已經有了9000多家不同行業的合作夥伴,合作夥伴與他們的合作業績整體增長率也達到了驚人的116%。至於人工智能方面,浪潮2018年與合作夥伴一起針對人工智能的行業應用場景,整理出了20多個解決方案,積累了大量的經驗和行業案例。

  

  “當前在AI百強企業當中,80%的企業都是浪潮的夥伴,並且都是深度的合作夥伴,這裏面既包括BAT互聯網廠商,也包括第四範式等AI新興的獨角獸”,王恩東強調。

  發布“元腦”,打造最強AI服務器生態

  即使浪潮已經為AI服務器市場準備了不少“彈藥”,但正如浪潮集團副總裁彭震先生所說,AI正在加速向通信、金融、廣電、醫療和製造行業蔓延,這就需要更多的計算力。

  在他看來,智慧計算是我們每個人都必須深刻思考的轉型的方向。這也是為何浪潮會做出以硬件重構加軟件定義去支撐雲的發展;以大數據為認知方法為整個智慧計算提供轉型的支撐;同時藉助深度學習優化算法為其智慧計算提供業務變革的驅動力等決定的原因。

  

  浪潮集團副總裁彭震先生

  基於這樣的思考,浪潮在IPF 2019上發布了他們的“元腦”平台等多樣產品,助力人工智能產業騰飛。

  據介紹,浪潮“元腦”是浪潮人工智能全棧能力的載體與具象,既包含浪潮全球領先的場景化人工智能基礎設施,多樣化的深度學習框架與工具,以及最新研發的人工智能 PaaS平台和AutoML Suite等“有形”產品,同時也凝聚了浪潮多年積累的人工智能算法優化、系統優化服務等“無形”能力。所謂“元”,寓意着一切的初始,同時神經元也是腦神經網絡的基本要素。按照浪潮的規劃,“元腦”將為人工智能提供最基礎、最本源的創新支撐,賦能生態合作夥伴,加速產業人工智能化進程,促進人工智能產業百花齊放。

  

  我們來看一下浪潮元腦系統組成。

  超強AI計算系統:通過浪潮人工智能計算平台、人工智能超高速計算加速卡、極低延遲RDMA網絡與超高帶寬并行存儲,共同提供極致人工智能計算性能。

  敏捷AI PaaS平台:由極致優化的AI資源平台、極速流程化AI開發平台、開放兼容的AI生態平台和秒速構建AI軟件棧。

  最新開發的人工智能PaaS平台AIStation面向人工智能企業訓練場景,可實現容器化部署、可視化開發、集中化管理等,有效打通開發環境、計算資源與數據資源,提升開發效率。

  高效的AutoML Suite:最新開發的AutoML Suite可實現非專業人員亦能通過極少操作構建網絡模型並獲得高精度,極大降低了人工智能開發、應用的門檻和成本。在2018年的NeurIPS 的自動機器學習挑戰賽中,浪潮與北京郵電大學、中南大學團隊合作,獲得自動機器學習領域的國際頂尖賽事的全球第三佳績。

  整合一體化交付:計算/存儲/網絡一體化、內置AI PaaS平台、內置建模優化工具、預配置系統調優。

  其他如F10A、F37X和人工智能計算加速引擎TF2,這是他們AI加速卡硬件的代表作。這些軟硬件將為相關開發者提供強而有力的支持。

  

  攜手英特爾,推動傳統服務器升級

  除了AI服務器及其相關生態產品,傳統的服務器也是浪潮未來持續關注的一個領域。但浪潮集團副總裁彭震同樣指出,隨着數據中心規模的變大,他們會面臨構建和管理等一系列問題,這樣給服務器帶來了新挑戰。

  為了解決相關問題,浪潮與Intel共同發布了首款面向雲計算場景優化的高密度四路服務器全球參考設計Crane Mountain(NF8260M5),目前已貢獻給OCP社區,該參考標準將被更多服務器廠商借鑒。這款產品將單個2U平台核的數量增加至112個,48個內存插槽,提供了更高的部署密度、更低的整體成本,還可以承擔數據庫等傳統應用,讓公有雲更適合承載傳統企業應用和混合雲的環境。

  “這樣一個高密度的設計,能更好地實現高效管理並降低OPEX 。預計整套系統的CAPEX可以節省7%~12%,這就意味着OPEX可以節省5%~7%,這樣就能比較顯著地降低數據中心的總體成本”,彭震強調。

  

  這是一個為虛擬機優化的設計,可以支持很大的內存容量。同時為了提高系統的散熱能效比,降低OPEX,他們還特意把這個產品的CPU的位置設計得有一些錯位。這個系統的前面板可以支持可熱插拔的模塊,從而提供靈活的配置,可以方便售後的運維,也降低OPEX。

  對人工智能計算未來的一些看法

  王恩東在IPF 2019峰會上一再強調,計算力是現代社會的生產力,而人工智能則將是這種計算力的核心。但隨着終端和上游應用的變化,人工智能計算如何才能滿足客戶、滿足市場、能更好地為客戶提供計算力支撐就成為了產業界關注的重點問題。王恩東則表示:“基於浪潮在AI方面的技術、產品、模式上的探索和實踐,我們認為要達到這個目標,要做到開放、融合與敏捷這三點。”

  首先看開放。

  從浪潮集團副總裁胡雷鈞先生的介紹中我們得知,所謂開放就包括了架構開放和平台開放,通過架構開放和平台開放,就能為他們的最終客戶和合作夥伴提供一個良好的技術平台。“浪潮在過去的10年裡面一直踐行開放”, 胡雷鈞強調。按照他的說法,浪潮已經逐漸從軟件開放走向了硬件開放。

  

  浪潮集團副總裁胡雷鈞先生

  在軟件領域的開放方面,浪潮是OpenStack的全球黃金會員,他們在OpenStack社區貢獻的代碼可以幫助OpenStack實現1千個物理機以上的擴展,管理虛擬機的規模單一集群可以達到1萬個;在存儲領域,浪潮也和開源社區充分合作,能夠為Ceph的性能提升提供巨大支撐,在有些場景裏面可以實現I/O吞吐量的翻倍,實現了IOPS的十倍的提升;至於人工智能領域,浪潮的OpenCL FPGA第一次把多節點并行引入到了訓練領域,這個開創性的成果也獲得了整個社區的廣泛接受。

  來到硬件領域的開放,其整機櫃服務器開放的項目是過去幾年裡面硬件開源領域里最成功的實踐。胡雷鈞告訴記者,基於浪潮和國內互聯網公司合作的開放組織ODCC,他們搭建了整機櫃交付的服務器系統,能夠集中供電、集中管理、整機櫃交付,為客戶提供非常好的價值。又因為這裏包含了2倍部署密度提升、10倍交付速度,實現了更高的維護效率、更高的投資收益和增長速度。這就讓它能為多個不同的行業提供部署和應用。同時,浪潮也廣泛參与了OCP、ODCC、Open19等開放組織。

  其次看融合。

  胡雷鈞指出,融合主要體現在幾個方面,第一個就是產業鏈的融合。他指出,浪潮原來的IT系統建設模式往往是基於標準產品、基於標準服務、基於用戶和供應商之間比較清晰的界面,這個界面往往是以需求的方式表達的,但這個模式對於變化的適應就不是那麼容易。

  然而在融合的開發模式下,會讓浪潮的前台/後台、最終客戶和合作夥伴甚至廠商在一個開發平台上,在開源代碼上、硬件上做共同的聯合設計。

  融合的另外一個方面也非常重要,就是要把新技術、把顛覆性的新技術融合到浪潮的業務模式設計裏面,融合到整個的流程裏面,融合到IT系統的支撐裏面。通過這個融合,釋放浪潮自己的創新能力,讓創新為整個產業升級,改善整個產業的成本,為客戶的應用體驗的改善而提供支撐。

  再看敏捷。

  所謂敏捷包含兩個層面,一個業務的敏捷,另一個是開發上的敏捷。

  “我們現在在互聯網模式的驅動下做的很多生意,都要依靠我們對客戶服務的多樣性,要依靠我們產品的多樣性,要依靠對於市場的不斷適應。這就要求我們自己的業務不斷變化,不斷前進。尤其是在AI推動的環境之下,會創新出很多新的應用模式和商業模式,這是很難規劃的,就需要敏捷對待”。胡雷鈞如是說。

  在多維布局下,浪潮為走向服務器全球第一夯實了基礎。

 

本站聲明:網站內容來源http://www.it168.com/,如有侵權,請聯繫我們,我們將及時處理

【精選推薦文章】

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

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

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

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