www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當前位置:首頁 > 公眾號精選 > 架構(gòu)師社區(qū)
[導(dǎo)讀]這篇文章醞釀了很久,一直想寫,卻一直覺得似乎要講的東西有點雜,又不是很容易講清楚,又怕爭議的地方很多,就一拖再拖。但是,每次看到不少遇到跟這個設(shè)計相關(guān)導(dǎo)致的問題,又忍不住跟人討論,但又很難一次說清楚,于是總后悔沒有及早把自己的觀點寫成文章。不管怎樣,觀點還是要表達的,無論對錯。故...


這篇文章醞釀了很久,一直想寫,卻一直覺得似乎要講的東西有點雜,又不是很容易講清楚,又怕爭議的地方很多,就一拖再拖。但是,每次看到不少遇到跟這個設(shè)計相關(guān)導(dǎo)致的問題,又忍不住跟人討論,但又很難一次說清楚,于是總后悔沒有及早把自己的觀點寫成文章。不管怎樣,觀點還是要表達的,無論對錯。



故障的推手——“Result"


先說結(jié)論:接口方法,尤其是對外HSF(開源版本即dubbo) api,接口異常建議不要使用Result,而應(yīng)該使用異常。阿里內(nèi)部的java編碼,已經(jīng)習慣性對外API一股腦兒使用“Result”設(shè)計——這是導(dǎo)致許多故障的重要原因!


???一個簡化的例子


// 用戶查詢的HSF服務(wù)API,使用了Result做為返回結(jié)果public interface UserService { Result getUserById(Long userId);}
// 一段客戶端應(yīng)用facade的調(diào)用示例。讀寫緩存邏輯部分省略,僅做示意public User testGetUser(Long userId) { String userKey = "userId-" userId; // 先查緩存,如果命中則返回緩存中的user // cacheManager.get(123, userKey); // ...
try{ Result result = userService.getUserById(userId); if (result.isSuccess()) { cacheManager.put(123, userKey, result.getData()); return result.getData(); } // 否則緩存空對象,代表用戶不存在 cacheManager.put(123, userKey, NullCacheObject.getInstance(), 3600); return null; } catch (Exception e) { // TODO log throw new DemoException("getUserById error. userId=" userId, e); }}
上面的代碼很簡單,客戶端應(yīng)用對User查詢服務(wù)做了個緩存。有些同學可能一眼就看出來,這里隱藏的bug:第10行的“result.isSuccess()”為false的實際含義是什么?是服務(wù)端系統(tǒng)異常嗎?還是用戶不存在?光看API是很難確定的。不得不去找服務(wù)提供方或文檔確認其邏輯,根據(jù)錯誤碼進行區(qū)分。如果是服務(wù)端系統(tǒng)異常,那么第15行將導(dǎo)致線上bug,因為后續(xù)1小時對該用戶的請求都認為用戶不存在了。


???嚴謹點的寫法
如果要寫正確邏輯,那么代碼可能會變成這樣:


public User testGetUser(Long userId) { String userKey = "userId-" userId; // 先查緩存,如果命中則返回緩存中的user // cacheManager.get(123, userKey); // ...
try{ Result result = userService.getUserById(userId); if (result.isSuccess()) { cacheManager.put(123, userKey, result.getData()); return result.getData(); } if ("USER_NOT_FOUND".equals(result.getCode())) { // 否則緩存空對象,代表用戶不存在 cacheManager.put(123, userKey, NullCacheObject.getInstance(), 3600); } else { // 可能是SYSTEM_ERROR、DB_ERROR等一些系統(tǒng)性的異常,TODO log throw new DemoException("getUserById error. userId=" userId ", result=" result); } } catch (DemoException e) { throw e; } catch (Exception e) { // TODO log throw new DemoException("getUserById error. userId=" userId, e); } return null;}

很顯然,代碼變得復(fù)雜起來了,加上對外部調(diào)用的try catch異常處理,實際代碼變相當復(fù)雜繁瑣。
???不使用Result的例子
public interface UserService { User getUserById(Long userId) throws DemoAppException;}
public User testGetUser(Long userId) { String userKey = "userId-" userId; // 先查緩存,如果命中則返回緩存中的user // cacheManager.get(123, userKey); // ...
try { User user = userService.getUserById(userId); if (user != null) { cacheManager.put(123, userKey, user); return user; } else { // 否則緩存空對象,代表用戶不存在 cacheManager.put(123, userKey, NullCacheObject.getInstance(), 3600); return null; } } catch (Exception e) { // TODO log throw new DemoException("getUserById error. userId=" userId, e); }}
這樣一看,代碼簡潔清晰很多,也更符合對普通API的調(diào)用習慣。


???使用Result的幾個問題

  1. 調(diào)用成本高:雖然通過對依賴的API深入了解異常設(shè)計,可以寫出嚴謹?shù)拇a以避免出現(xiàn)bug,但是簡單的邏輯,代碼卻變得復(fù)雜。換言之,調(diào)用的成本變高。但是很可惜,我們忘記判斷而寫成“一個簡化的例子”這樣是往往常事。

  2. 無意義錯誤碼:SYSTEM_ERROR、DB_ERROR等系統(tǒng)異常的錯誤碼,雖然放在Result中了,但是調(diào)用方除了日志和監(jiān)控作用外,業(yè)務(wù)邏輯永遠不會關(guān)心,也永遠處理不了。而些錯誤碼的處理分支,實際與拋異常的處理邏輯一樣。既然如此,為何要將這些錯誤碼放在返回值里?


關(guān)于阿里巴巴開發(fā)規(guī)約


我們看《阿里巴巴Java開發(fā)手冊》的“異常處理”小節(jié)第13條:


【推薦】對于公司外的http/api開放接口必須使用“錯誤碼”;跨應(yīng)用間HSF調(diào)用優(yōu)先考慮使用Result方式,封裝isSuccess()方法、“錯誤碼”、“錯誤簡短信息”;而應(yīng)用內(nèi)部推薦異常拋出。


這條推薦非常具有誤導(dǎo)性,在2016年孤盡對于這條規(guī)范進行調(diào)研時的帖子:《【開發(fā)規(guī)約熱議投票02】HSF服務(wù)接口定義時,是Result isSuccess方式返回,還是是拋異常的方式?》有部分同學不建議使用Result,但大部分同學推薦了Result的做法。


???為什么說這條規(guī)約具有誤導(dǎo)性?


因為這個問題本身沒有講清楚“對什么東西的處理”要用Result還是異常的方式,即這里沒有講清楚我們要解決的問題是什么。事實上我們常說的“失敗”,往往混淆了2種含義:


  1. 系統(tǒng)異常:比如網(wǎng)絡(luò)超時、DB異常、緩存超時等,調(diào)用方一般不太可能基于這些錯誤類型做不同的業(yè)務(wù)邏輯,常用用于日志和監(jiān)控,方便定位排查。

  2. 業(yè)務(wù)狀態(tài):比如業(yè)務(wù)規(guī)則攔截導(dǎo)致的失敗,比如發(fā)權(quán)益時庫存不足、用戶限領(lǐng)等,為方便后文敘述和理解,暫時稱為“業(yè)務(wù)失敗”。這類“失敗”,從機器層面來看,嚴格來說不能算做是失敗,這只是一種正常的業(yè)務(wù)結(jié)果,這和“調(diào)用成功”這個業(yè)務(wù)結(jié)果對系統(tǒng)來說沒有任何區(qū)別,只是一個業(yè)務(wù)狀態(tài)而已。調(diào)用方往往可能關(guān)心對應(yīng)的錯誤碼,以完成不同的業(yè)務(wù)邏輯。


有經(jīng)驗的開發(fā),都會意識到這2種含義的區(qū)別,這對于幫助我們理解接口的異常設(shè)計非常重要!對這條開發(fā)規(guī)約而言,如果是第2種,并沒有什么大的問題,但如果是第1種,我則持相反的意見,因為這違背了java語言的基本設(shè)計,不符合java編碼直覺,會潛移默化造成前面案例所示的理解和使用成本的問題。


談?wù)凧ava接口Result設(shè)計


???為什么針對HSF?


當我們討論要用Result代替Exception時,經(jīng)常會以這是HSF接口為由,因為性能開銷等等。我們常說HSF這種RPC框架,設(shè)計的目的就是為了看起來像本地調(diào)用。那么,這個“看起來像本地調(diào)用”到底指的是哪方面像呢?顯然,編碼時像,運行時不像。所以我們寫調(diào)用HSF接口的代碼時,感覺像在調(diào)用本地方法,那么我們的編碼直覺和習慣也都應(yīng)該是符合java的規(guī)范的。因此,至少有幾點理由,對于系統(tǒng)異常,我們的HSF接口更應(yīng)該使用Exception,而非Result的方式:


  1. 只有同樣遵循本地方法調(diào)用的設(shè)計,來設(shè)計HSF的api,才能更好做到“像本地調(diào)用一樣”,更符合HSF設(shè)計的初衷。

  2. HSF接口是往往用于對外部團隊提供服務(wù),更應(yīng)該遵循java語法的設(shè)計,提供清晰的接口語義,降低調(diào)用方的使用成本,減少出bug的概率。

  3. Result并無統(tǒng)一規(guī)范,而Exception則是語言標準,有利于中間件、框架代碼的監(jiān)控發(fā)現(xiàn)和異常重試等邏輯生效。


當然,由于“運行時不像”,對于HSF封裝帶來的抽象泄露,我們在使用異常時,需要關(guān)注幾點問題


  1. 異常要在接口顯式聲明,否則客戶端可能會反序列化失敗。

  2. 盡可能不帶原始堆棧,否則客戶端也可能反序列化失敗,或者堆棧過大導(dǎo)致性能問題。可以考慮異常中定義錯誤碼以方便定位問題。


???結(jié)論


無論是HSF接口,還是內(nèi)部的API,都應(yīng)該遵循java語言的編碼直覺和習慣,業(yè)務(wù)結(jié)果(無論成功還是失敗)都應(yīng)該通過返回值返回,而系統(tǒng)異常,則應(yīng)該使用拋出Exception的方式來實現(xiàn)。


關(guān)于Checked?Exception


講到這里,我們發(fā)現(xiàn),java的Checked Exception的設(shè)計,作用上和反映業(yè)務(wù)失敗的Result很像。Result是強制調(diào)用方進行判斷和識別,并根據(jù)不同的錯誤碼進行判斷和處理。而Checked Exception也是強制調(diào)用方進行處理,并且可能要對不同的異常做不同的處理。但是,基于前面的結(jié)論,業(yè)務(wù)失敗應(yīng)該通過返回值來表達,而不是異常;而異常是不應(yīng)該用于做業(yè)務(wù)邏輯判斷的,那么java的Checked Exception就變成奇怪的存在了。這里我明確我的觀點,我們應(yīng)該盡可能不使用Checked?Exception。另外,《Thinking in Java》的作者 Bruce Eckel就曾經(jīng)公開表示,Java語言中的Checked Exception是一個錯誤的決定,Java應(yīng)該移除它。C#之父Anders Hejlsberg也認同這個觀點,因此C#中是沒有Checked Exception的。


Reselt 的實質(zhì)是什么?


談?wù)凧ava接口Result設(shè)計


我們看看一個java方法的簽名(省略修飾符部分):


  1. 方法名:用于表達這個方法的功能

  2. 參數(shù):方法的輸入

  3. 返回值類型:方法的輸出

  4. 異常:方法中意外出現(xiàn)的錯誤


所以,返回值和方法功能必須是配套的,返回值類型,就是這個方法的功能執(zhí)行結(jié)果的準確表達,即返回值必須正好就是當前這個方法要做的事情的結(jié)果,必須滿足這個方法語義,而不應(yīng)該有超出這個語義外的東西存在。而異常,所說的“意外”,則是指超出這個方法語義之外的部分。這幾句話有點拗口,舉個例子來說,上面這個用戶接口,語義就是要通過用戶id查詢用戶,那么當服務(wù)端發(fā)生DB超時錯誤時,對于“通過用戶id查詢用戶”這個語義來說,DB超時錯誤”沒有任何意義,使用異常是恰好合適的,如果我們把這個錯誤做為錯誤碼放在返回值的Result里,那么就是增加了這個方法的使用成本。


???Result的由來


到底為什么會有“Result”這樣的東西誕生呢?如果設(shè)計的方法返回值是Result類型,那么它必須能準確反應(yīng)這個方法調(diào)用的結(jié)果。實際上,以上面的例子為例,這個時候的Result就是User類本身,User.status相當于Result.code。這聽起來可能有點和直覺不符,這是為什么?


public class UserRegisterResult { private String errorCode; private String errorMsg; private Long userId; // ...
public boolean isSuccess() { return errorCode == null; } // ...}
UserRegisterResult registerUser(User user) throws DemoAppException;

我們再來看看上面這個“注冊用戶”的方法聲明,會發(fā)現(xiàn),這個方法定義一個Result顯得很合適。這是因為前一個例子,我們的方法是一個查詢方法,返回值剛好可以用領(lǐng)域?qū)ο箢愋捅旧恚@個“注冊用戶”的方法,顯然沒有現(xiàn)成合適的類型可以使用,所以就需要定義一個新的類型來表達方法的執(zhí)行結(jié)果??吹竭@里,我們會以為,對于“寫”與“讀”類型的方法有所差異,但實際上,對于java語言或者機器來說,并無二致,第二個方法UserRegisterResult的和第一個方法的User是同等地位。所以,最重要的還是一點:需要有一個合適的類型,做為返回值,用于準確表達方法執(zhí)行的功能結(jié)果。而偏“寫”類型,或者帶業(yè)務(wù)校驗的讀接口,往往因為沒有現(xiàn)成的類型可用,為了方便,常常會使用Result來代替。


???是否有必要統(tǒng)一Result?


講到這里,想想,當我們這種“需要Result”的方法有多個時,我們會說“我需要一個統(tǒng)一的Result類”時,實際上說的什么呢?


  1. 我希望各種接口方法都統(tǒng)一同樣的Result,方便使用

  2. 我希望有個類復(fù)用errorCode、errorMsg以及相關(guān)的getter/setter等代碼


顯然,第1點理由經(jīng)不起推敲,為何“統(tǒng)一就方便使用”了?如果各種方法返回類型都一樣,那就違背了“返回值要和方法功能配套”的結(jié)論,也不符合高內(nèi)聚的設(shè)計原則。恰相反,返回值越是設(shè)計得專用,對調(diào)用方來說理解和使用成本越低。所以,我們實際想要的,僅僅是如何“偷懶”,也就是第2點理由。所以我們真正要做的是,只是在當前領(lǐng)域范圍內(nèi),如何既滿足讓每個方法返回值專用以便使用,同時又可以偷懶復(fù)用部分代碼即可。因此,絕不必要求大家都統(tǒng)一使用同一個Result類型。

接口返回設(shè)計建議


根據(jù)前文的結(jié)論,我們知道,對于接口方法的返回值和異常處理,最重要的是需要遵循方法的語義進行設(shè)計。以下是我梳理的一些設(shè)計上的原則和建議。


???對響應(yīng)合理分類


接口響應(yīng)按有業(yè)務(wù)結(jié)果和未知業(yè)務(wù)結(jié)果分類,業(yè)務(wù)結(jié)果不管是業(yè)務(wù)成功還是業(yè)務(wù)規(guī)則導(dǎo)致的失敗,都通過返回值返回;未知結(jié)果一般是系統(tǒng)性的異常導(dǎo)致,不要通過返回值錯誤碼表達,而是通過拋出異常來表達。這里最關(guān)鍵一點,就是如何理解和區(qū)分某個“失敗”是屬于業(yè)務(wù)失敗,還是屬于系統(tǒng)異常。由于有時候這個區(qū)分并不是很容易,我們可以有一個比較簡單的判斷標準來確定:


  1. 如果一個錯誤,調(diào)用方只能通過人工介入的方式才能恢復(fù),比如修改代碼、改配置,或數(shù)據(jù)訂正等處理,則必然屬于異常

  2. 如果調(diào)用方無法使用代碼邏輯處理消化使得自動恢復(fù),而是只能通過重試的方式,依賴下游的恢復(fù)才能恢復(fù),則屬于異常


???找到合適的場景


普通查詢接口,如無必要,不要使用Result包裝返回值??梢院唵畏譃?類做為參考:
  • 普通讀接口


查詢結(jié)果即是領(lǐng)域?qū)ο螅瑹o其他業(yè)務(wù)規(guī)則導(dǎo)致的失?。航ㄗh直接用領(lǐng)域?qū)ο箢愋妥鰹榉祷刂?。如?/span>
User getUserById(Long userId) throws DemoAppException;
  • 寫接口


或者帶業(yè)務(wù)規(guī)則的讀接口:
  1. 理想情況是專門封裝一個返回值類,以降低調(diào)用方的使用成本。

  2. 可考慮將返回值類繼承Result,以復(fù)用errorCode和errorMsg等代碼,減輕開發(fā)工作量。但注意這不是必要的。

  3. 將本方法的錯誤碼,直接定義到這個返回值類上(高內(nèi)聚原則)。

  4. 若有多個方法有共同的錯誤碼,可以考慮通過將這部分錯誤碼定義到一個Interface中,然后實現(xiàn)該接口。

// UserRegisterResult、UserUpdateResult可以繼承Result類,減少工作量,但調(diào)用方不需要感知Result類的存在UserRegisterResult registerUser(User user) throws DemoAppException;
UserUpdateResult updateUser(User user) throws DemoAppException;談?wù)凧ava接口Result設(shè)計
  • 帶業(yè)務(wù)規(guī)則的的領(lǐng)域?qū)ο笞x接口


完全遵循上面第2點,會給方法提供者帶來一定的開發(fā)成本,權(quán)衡情況下可以考慮,套Result包裝領(lǐng)域?qū)ο笞鰹榉祷刂?。注意,對外不建議,可考慮用于內(nèi)部方法。如下接口,“沒有權(quán)限”是一個正常的業(yè)務(wù)失敗,調(diào)用方可能會判斷并做一定的業(yè)務(wù)邏輯處理:


// 查詢有效用戶,如果用戶存在但狀態(tài)非有效狀態(tài)則返回“用戶狀態(tài)錯誤”的錯誤碼,如果不存在則返回nullResult getEffectiveUserWithStatusCheck(Long userId) throws DemoAppException;

???內(nèi)外部區(qū)分


對外接口,尤其是HSF,由于變更成本高,更要遵循前面的原則;內(nèi)部方法,方法眾多,如果完全遵循需要編碼成本,這里需要做權(quán)衡,根據(jù)代碼規(guī)模和發(fā)展階段不斷重構(gòu)和調(diào)整即可。


???避免直接包裝原生類型


我們對外的接口,返回值要避免出現(xiàn)直接使用Result包裝一個原生類型。比如:


Result registerUser(User user) throws DemoAppException;

這樣設(shè)計導(dǎo)致的結(jié)果是,擴展性很差。如果registerUser方法需要增加返回除了userId以外的其他字段時,就面臨幾個選擇:


  1. 讓Result支持擴展參數(shù),通過map來傳遞額外字段:可讀性和使用成本很高

  2. 開發(fā)一個新的registerUser方法:顯然,成本很高


???避免所有錯誤碼定義在一個類中


有人建議,做一個全局的錯誤碼定義,以做統(tǒng)一,方便排查和定位。但這樣做真的方便嗎?這樣做實際上有幾個問題:


  1. 完全違背了高內(nèi)聚、低耦合的設(shè)計原則。這個“統(tǒng)一的定義”將與各個域都有耦合,同時對于某單個接口而言,則不夠內(nèi)聚。

  2. 這個統(tǒng)一定義的錯誤碼,一定會爆炸式增長,即便我們對其進行分類(非常依賴人的經(jīng)驗),遲早也會變得難以維護和理解。

  3. 不要將系統(tǒng)異常類的錯誤碼和業(yè)務(wù)失敗錯誤碼放在一起,這點其實和方法響應(yīng)分類設(shè)計是一回事。


我們在設(shè)計拉菲2權(quán)益平臺的錯誤碼時,就犯了這樣的錯誤?,F(xiàn)在這個“統(tǒng)一的”錯誤碼已經(jīng)超過400個,揉合了管理域、投發(fā)放域、離線域等各種不同域的業(yè)務(wù)失敗、系統(tǒng)異常的錯誤碼,不要說調(diào)用方,即便我們自己,也梳理不清楚了。而實際上,每個域、每個方法自己的業(yè)務(wù)失敗是非常有限的,它的增長一定是隨著業(yè)務(wù)需求本身的變化而增長的?,F(xiàn)在如果有個業(yè)務(wù)方來問我,拉菲2的發(fā)放接口,有哪些錯誤碼(這問的實際是業(yè)務(wù)失敗,他也只關(guān)心業(yè)務(wù)失敗),我?guī)缀蹼y以回答。很可惜,這塊目前即便重構(gòu),難度也很大。


???異常處理機制


  • 異常錯誤碼


前面我們講到,即便是拋異常的形式,我們也可以為我們的異常類設(shè)計錯誤碼,異常錯誤碼的增加會很快,往往也和當前業(yè)務(wù)語義無關(guān),因此千萬不要和業(yè)務(wù)失敗的錯誤碼定義在一起。異常內(nèi)的錯誤碼主要用于日志、監(jiān)控等,核心原則就是,要方便定位問題。


  • 避免層層try?catch

到處充滿異常處理的代碼,會導(dǎo)致整個程序可讀性變差,寫起來也非常繁瑣,可以遵循一定的原則:


  1. 在原始發(fā)生錯誤的地方try?catch,比如調(diào)用HSF接口的Facade層代碼,主要目的是為了記錄原始的錯誤以及出入?yún)ⅲ奖愣ㄎ粏栴},一般會打日志,并轉(zhuǎn)換成本應(yīng)用的異常類上拋

  2. 在應(yīng)用的最頂層catch異常,打印統(tǒng)一日志,并根據(jù)“為什么針對HSF?”小節(jié)中的建議,處理成合適的異常后再拋出。對于HSF接口,可以直接實現(xiàn)HSF的“ServerFilter”來統(tǒng)一在框架層面處理。

  3. 中間層的代碼,不必再層層catch,比如domain層,可以讓代碼邏輯更加清晰。


  • 參數(shù)錯誤


拋異常的場景,除了前面說的系統(tǒng)性異常外,參數(shù)錯誤也推薦使用異常。原因如下:


  1. 參數(shù)正確一般是我們當前上下文執(zhí)行的前提條件,我們一般可以使用assert來保證其正確。即我們的后續(xù)邏輯是認為,當前的參數(shù)是不可能錯誤的,我們沒必要為此寫過多繁瑣的防御性代碼。

  2. 一旦發(fā)生參數(shù)錯誤,則一定是調(diào)用方有代碼bug,或者配置bug,應(yīng)該通過拋出異常的方式,充分提前在開發(fā)或測試階段暴露。

  3. 參數(shù)錯誤對調(diào)用方來說,是無法處理的,程序不可能自動恢復(fù),一定是會需要人工介入才可能恢復(fù),調(diào)用方不可能會“判斷如果是xx參數(shù)錯誤,我就做某個業(yè)務(wù)邏輯”這樣的代碼,因此通過返回值定義參數(shù)錯誤碼沒有意義。


  • 系統(tǒng)異常和業(yè)務(wù)結(jié)果轉(zhuǎn)換


系統(tǒng)性異常并非一定是異常,因為有些層可能有能力處理某些異常,比如對于弱依賴的接口,異常是可以吞掉,轉(zhuǎn)換成一個業(yè)務(wù)結(jié)果;相反,有些接口返回的一些業(yè)務(wù)失敗,但調(diào)用方認為該業(yè)務(wù)失敗不可能出現(xiàn),出現(xiàn)也無法處理,那么這一層可以將其轉(zhuǎn)換成異常。


結(jié)尾


前面講了接口的響應(yīng),包括返回值Result和異常拋出的設(shè)計,有很多結(jié)論是與現(xiàn)在公司內(nèi)部大家常見做法是不同的,這也是我為什么特別想要表達的,有可能正是日常我們的這些習以為常做法,才導(dǎo)致了團隊間接口依賴調(diào)用的成本提高,也是導(dǎo)致故障的一個很重要原因。當然,我相信,我的觀點也不一定都是對的,很多同學并不一定同意上面所有的結(jié)論,所以,歡迎大家在文章下面討論!

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉