標籤: 收購3c

  • 傳蘋果電動汽車將採用韓國公司的電池技術

    傳蘋果電動汽車將採用韓國公司的電池技術

    根據行業消息,蘋果近期與一家韓國電池開發商簽署了保密協議,聯合為代號為“泰坦”的汽車專案開發電池。從今年初開始,他們一直在韓國做行政工作。一名蘋果員工一直在這家韓國公司進行參觀活動,他屬於與蘋果電動汽車電池開發相關的部門。  
      業界認為,這家韓國公司並不是唯一一家負責蘋果電池開發的公司。不過,有消息稱,儘管蘋果從一開始就從完全不同的設計、功能以及性能角度來開發電池,但是他們仍舊一直在挖掘創新技術。業界相信,蘋果專注于開發出只能存在於蘋果自動駕駛汽車的創新電池技術。   這家韓國電池開發商由大約20名電池專家組成,持有空芯電池的國際專利技術。這些電池是圓柱形鋰離子二次電池,有兩根手指那麼厚,不同於其它空芯電池。蘋果並未選擇當前電動汽車普遍使用的標準圓形或矩形電池,但計畫根據韓國公司的空芯電池技術為其電動汽車開發自主電池。   文章來源:鳳凰科技

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

    【其他文章推薦】

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

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

    ※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

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

  • 蘋果傳將攜手韓廠研發電動車用電池

    蘋果公司持續擴大業務範圍,除新成立的蘋果能源(Apple Energy)成功取得售電許可外,市場上關注度十足的蘋果電動車專案「泰坦計畫」(Project Titan)也時常傳出新消息。近期傳言蘋果將與南韓某企業合作,運用該南韓公司的電池專利,攜手開發電動車用電池。

    根據日本蘋果情報網站iPhone Mania、南韓媒體ET News 等報導,蘋果看上某家南韓廠商所取得的鋰電池專利,打算與該廠合作開發電動車用電池。被看上的鋰電池專利技術,電池中央部位採中空設計,可使空氣流通來冷卻電池,等同降低冷卻系統的需求,騰出更多空間來增加電池容量。

    日、韓媒體並未披露可能將與蘋果合作的韓廠名稱,但美國MacRumors 透剁歐洲專利局得知,這款「中央中空」的電池是由一家稱為Orange Power 的南韓廠商取得。該廠係一小廠,員工人數僅33人,其中多數為研發人員。

    蘋果電動車計畫自曝光以來即備受矚目,但至今仍然只聞樓梯響。據了解,目前共有約1,000人參與蘋果電動車企劃,且蘋果已在柏林設立秘密開發實驗室。MoneyDJ引述The Information網站的說法,表示蘋果電動車可能在2021年亮相;但也有分析師認為,蘋果電動車可能會步上蘋果電視的後塵,胎死腹中。

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

    【其他文章推薦】

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

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

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

  • 續航力600公里的特斯拉 即將問世?

    續航力600公里的特斯拉 即將問世?

    續航力是電動車最受關注的性能,而作為全球電動車龍頭廠商的特斯拉(Tesla),似乎也準備好要推出續航力更久的車款了。跟據了解,新的特斯拉電動車可能搭載100kW的電池,續航力最遠可達611公里。

    《癮科技》中文版指出,德國監管機關的資料中可查到Model S與Model X的100D與P100D型號的相關資訊;而根據特斯拉為車款型號命名的邏輯,這可能暗示特斯拉將推出搭載100kW電池的車款。

    100kW 的電池搭配Model S,預計最高續航里程可來到611公里,比90D的續航里程多了100公里以上。若搭配Model X,續航里程也可來到480 公里之多。這樣的續航力,將能有效減輕美國車主對駕駛特斯拉跨州旅行的疑慮。

    (照片來源:Tesla 臉書專頁)

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

    【其他文章推薦】

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

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

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

  • 從零開始搭建前後端分離的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的項目框架之十一Swagger使用一

    從零開始搭建前後端分離的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的項目框架之十一Swagger使用一

     一.未使用Swagger狀況

      相信無論是前端開發人員還是後端開發人員,都或多或少都被接口文檔折磨過,前端經常抱怨後端給的接口文檔或與實際情況不一致。後端又覺得編寫及維護接口文檔會耗費不少精力,經常來不及更新。 其實無論是前端調用後端,還是後端調用後端,都期望有一個好的接口文檔。但是這個接口文檔對於程序員來說,就跟註釋一樣,經常會抱怨別人寫的代碼沒有寫註釋,然而自己寫起代碼起來,最討厭的,也是寫註釋。 所以僅僅只通過強制來規範大家是不夠的,隨着時間推移,版本迭代,接口文檔往往很容易就跟不上代碼了

     二.使用Swagger狀況

      Swagger 提供了一個可視化的UI頁面展示描述文件,其中包括接口的調用,接口所需參數(header,body,url.params),接口說明,參數說明等。接口的調用方、測試、項目經理等都可以在該頁面中對相關接口進行查閱和做一些簡單的接口請求。只要在項目框架搭建時,對Swagger 進行了配置,後面持續迭代的時候,只會花很小代價去維護代碼、接口文檔以及Swagger描述文件。因為一旦接口發生改變,程序重新部署,接口文檔會重新生成對應新的文檔。

     三.如何使用?

      在NetCore項目中怎麼去使用Swagger來生成接口文檔呢?

      首先在 webApi 啟動項目 上 右鍵 點擊管理Nuget程序包, 安裝  Swashbuckle.AspNetCore ,然後到  Startup 中添加引用  using Swashbuckle.AspNetCore.Swagger; 

      在ConfigureServices方法中添加以下代碼

                #region Swagger
    
                services.AddSwaggerGen(options =>
                {
                    options.SwaggerDoc("v1", new Info
                    {
                        Version = "v1",
                        Title = "API Doc",
                        Description = "作者:Levy_w_Wang",
                        //服務條款
                        TermsOfService = "None",
                        //作者信息
                        Contact = new Contact
                        {
                            Name = "levy",
                            Email = "levy_w_wang@qq.com",
                            Url = "https://www.cnblogs.com/levywang"
                        },
                        //許可證
                        License = new License
                        {
                            Name = "tim",
                            Url = "https://www.cnblogs.com/levywang"
                        }
                    });
    
                    #region XmlComments
    
                    var basePath1 = Path.GetDirectoryName(typeof(Program).Assembly.Location);//獲取應用程序所在目錄(絕對,不受工作目錄(平台)影響,建議採用此方法獲取路徑)
                    //獲取目錄下的XML文件 显示註釋等信息
                    var xmlComments = Directory.GetFiles(basePath1, "*.xml", SearchOption.AllDirectories).ToList();
    
                    foreach (var xmlComment in xmlComments)
                    {
                        options.IncludeXmlComments(xmlComment);
                    }
                    #endregion
    
                    options.DocInclusionPredicate((docName, description) => true);
    
                    options.IgnoreObsoleteProperties();//忽略 有Obsolete 屬性的方法
                    options.IgnoreObsoleteActions();
                    options.DescribeAllEnumsAsStrings();
                });
                #endregion

    上面寫的循環是因為項目中可能有多個控制器類庫,為的是排除這種情況

    接下來,再到 Configure 方法中添加:

                #region Swagger
    
                app.UseSwagger(c => { c.RouteTemplate = "apidoc/{documentName}/swagger.json"; });
                app.UseSwaggerUI(c =>
                {
                    c.RoutePrefix = "apidoc";
                    c.SwaggerEndpoint("v1/swagger.json", "ContentCenter API V1");
                    c.DocExpansion(DocExpansion.Full);//默認文檔展開方式
                });
    
                #endregion

    這裏使用了 RoutePrefix  屬性,為的是改變原始打開接口文檔目錄,原始路徑為 swagger/index.html ,現在為 /apidoc/index.html 

    這個時候在需要輸出註釋的控制器類庫屬性 中設置如下信息,並添加上相關註釋

    然後運行起來,打開本地地址加上  /apidoc/index.html  就可以看到效果,

    特別提醒:如果打開下面這個界面能正常显示,但是提示  Fetch errorInternal Server Error v1/swagger.json  錯誤,說明有方法未指明請求方式,如 HttpGet HttpPost HttpPut 等,找到並指明,重新運行就正常了

     

      點擊方法右上角的 Try it out ,試下調用接口,然後點擊Exectue,執行查看結果,能得到後端方法返回結果就說明成功。

    特別說明:有接口不需要展示出去的時候,可以在方法上添加屬性 Obsolete ,這樣就不會显示出來。 前提:有前面ConfigureServices中 後面的 忽略 有Obsolete 屬性的方法 設置才行!!!

     

     最後可以看到接口返回數據正常,並且也能看到接口響應請求嘛等等信息,一個接口應該返回的信息也都有显示。

     

    總結:

    本文從為開發人員手寫api文檔的痛楚,從而引申出Swagger根據代碼自動生成出文檔和註釋,

    並且還可以將不需要的方法不显示等設置。然後進行了簡單的測試使用 。

    但是!!一般後端方法都有token等驗證,需要在header中添加token、sid等字段來驗證用戶,保障安全性,

    該設置將在下一章節中寫!

     下一章

    以上若有什麼不對或可以改進的地方,望各位指出或提出意見,一起探討學習~

    有需要源碼的可通過此 鏈接拉取 覺得還可以的給個 start 和點個 下方的推薦哦~~謝謝!

     

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理【其他文章推薦】

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

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

    ※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

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

  • PostgreSQL空間數據庫創建備份恢復(PostGIS vs ArcGIS)

    梯子

    PostGIS

    創建

    安裝就不必介紹了,windows下使用安裝工具Application Stack Builder,選擇空間擴展PostGIS即可自動安裝

    然後新建庫后,在庫中執行以下語句創建控件擴展

    CREATE EXTENSION postgis

    也可以創建數據庫時選擇postgis的模板庫創建

    create database postgisdb template postgis_template;

    新建數據庫后添加postgis擴展後會發現庫內public模式下函數序列觸發器等都會增加一些postgis相關功能
    然後就可以通過PostGIS Shapefile and DBF Loader工具導入shp數據

    備份

    postgersql的備份恢復主要有

    1. 增量備份和基於時間點恢復(RITR)
    2. pg_dump和pg_dumpall進行轉儲,從SQL轉儲文件恢復
    3. 文件系統級別備份

    這裏我們使用簡單,容易掌握的pg_dump命令,一般在安裝目錄bin下
    pg_dump備份單庫,不導出角色和表空間相關信息

    pg_dump -h localhost -U postgres postgisdb > D:\backup\postgisdb.bak

    有一些參數選項可以參考(很多,具體不列了,執行help可以查看到)

    pg_dump --help
    恢復

    恢復可以使用psql

    psql -h localhost -U postgres -d postgisdb2 < D:\backup\postgisdb.bak

    恢復時可以指定不同的數據庫,如果pg_dump時-C創建數據庫,那也可以不用先新建數據庫

    postgis庫的恢復備份還是挺簡單的,所有的東西都在public下

    ArcGIS

    創建

    ArcGIS要連接到postgresql,需要將postgresql安裝目錄lib下的libeay32.dll、libiconv-2.dll、libintl-8.dll、libpq.dll 和 ssleay32.dll拷貝到ArcGIS Desktop的安裝目錄bin下
    將ArcGIS Desktop目錄DatabaseSupport\PostgreSQL下的st_geometry.dll拷貝到postgresql的lib下

    使用ArcGIS工具箱中Create Enterprise Geodatabase工具創建SDE,完事後會在創建一個sde登陸角色並在庫中創建一個sde模式,包含諸多函數序列管理表等。(注意:ArcGIS雖然可以在系統庫postgres中創建SDE擴展,然並連不上,ArcGIS不允許連接訪問系統數據庫

    然後ArcGIS可以連接該數據庫,並且進行空間數據管理操作。(注意:默認ArcGIS創建空間數據,只能創建在和登陸用戶同名的模式下

    備份

    我們可以向上面PostGIS備份恢復一樣,直接備份整個庫

    恢復

    如果恢復至同名數據庫,像上面恢復是沒有問題的
    但如果數據庫改名了,則會有驚喜發生,ArcGIS管理空間報底層gdb_release之類的錯誤,同樣的問題不止恢復庫時,修改數據庫名稱也不像其他庫那麼隨心所欲,以含SDE擴展的庫為模板創建新庫也會有問題

    ArcGIS SDE未見文檔介紹內部結構邏輯,只能猜測大概,或不準確,願聞其詳

    ArcSDE空間數據創建時會在SDE管理表裡註冊相關信息,比如空間參考,列啊,表的唯一標識等,便於它做數據管理、版本控制

    修改庫名后,ArcSDE管理就出問題,主要是一些註冊項,安裝SDE時也會把該庫的信息註冊到SDE管理表中去,所以新庫名,它就不認識了

    如果修改了庫名,我們找到以下錶

    select * from sde.gdb_items
    you need modify : name physicalname path etc...

    update sde.sde_table_registry set database_name='testdb';
    update sde.sde_column_registry set database_name='testdb';
    update sde.sde_geometry_columns set f_table_catalog='testdb';
    update sde.sde_raster_columns set database_name='testdb';
    update sde.sde_layers set database_name='testdb';

    然後就一切正常

    當然我們建議不輕易改庫名

    這就是商業軟件,足夠強大不夠靈活,封裝和靈活總會互相博弈

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理【其他文章推薦】

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

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

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

  • 高質量App的架構設計與思考!

    高質量App的架構設計與思考!

    最近在做一功能不大、業務也不複雜的小眾App,以往做App是發現自己從來沒有考慮過一些架構方面的問題,只是按照自己以往的習慣去寫代碼,忽略了App的設計。本次分享主要包含一些開發App的小經驗和技巧,來一次App開發與設計的分享。

    先和分享下一下實體類的設計與組織形式

    實體類的組織

    在做App開發的時候有很多的實體類,項目越複雜實體類就會越多,經過我的一番思考大致這可以將實體分為以下幾大數:

    • 面向數據庫的
    • 服務端返回的數據實體
    • 用於渲染View的實體(使用Databinding)

    一般情況下實體類的操作會經過以下步驟:

    1. App請求服務器獲取數據
    2. 將數據存入數據庫(可選)
    3. 渲染頁面展示數據

    現在的實體的產生只用在請求服務器數據的時候才需要新建,後續的數據庫、頁面渲染其實是可以使用一套實體:

    先不說這樣做的行不行,首先三個地方使用同一實體就會引起字段歧義比如服務器數據有Id、本地數據也有Id,那兩個id字段就有衝突了不得不改字段名。

    另一種情況渲染和數據本身並不會一一對應,有時候後端數據給的是一個純数字而前端頁面显示的是字符串兩個都對應不上,強行放在一起會起來更多的問題。

    所為實體類的的正確組織形式應該是:相互隔離、互不干擾

    數據實體的在渲染之前都需要準備好,比如在ViewModel中將int型的數據轉換成文本型的數據然後再使用Databinding+頁面渲染實體來渲染頁面。

    優雅的處理網絡數據

    現在Android開發使用的網絡庫大部分都是Okhttp + Retrofit,使用Retrofit網絡交互變的非常簡單一個Service接口就能搞定一切,美茲茲~~,現在大部分後端返回的數據都會是以下形式:

    {
        "code":0,
        "data": {},
        "msg": ""
    }

    雖然不能涵蓋所有,但還是可以非常贊的數據、消息、成功與否啥都有!對於前面主要是關注data字段,其他msgcode等都屬於輔助字段。前端對應的實體對象應該是這樣的(假代碼):

    public class ApiResponse<T> {
        private int code;
        private T data;
        private String msg;
    }

    對應的Service那就得定義成這樣(使用了RxJava):

    public intface UserService {
        @GET("/xx/{id}")
        Single<ApiResponse<UserInfo> getUserInfoById(@Path("id") Long userId);
    }

    從接口中可以看出來,方法的返回值就包了幾層,如果要拿data字段需要經過:ApiResponse -> UserInfo,而且在拿之前還要判斷code字段:

    
    ...
    
    if(ApiResponse.code == 0){
        UserInfo info = ApiResponse.getData();
    }
    
    ...
    

    為了消除這些冗餘的代碼可以使用CallAdapter來使Service方法返回的數據直接就是實體類:

    public intface UserService {
        @GET("/xx/{id}")
        Single<UserInfo> getUserInfoById(@Path("id") Long userId);
    }

    CallAdapter的代碼就不貼了,可以自行查找。這樣做帶來的另外一個問題就是業務代碼如何判斷接口是否成功或失敗,前端必需友好的把錯誤提示給用戶而不是一直搞個Loading在那裡瞎轉~~。現階段最方便的的錯誤傳遞方式是使用Java異常,前端可以定義業務異常網絡異常

    public class BizException extends RuntimeException {
        ...
    }

    CallAdapter中檢查ApiResponse的返回值是否成功:

    
    if(!ApiResponse != 0){
        throw new BizExcepiton(ApiResponse);
    }
    

    如果後端返回業務異常那前端就對應拋出一個BizExcepiton,如果是http錯誤如:404、400那可以拋出HttpException。除了BizExcepitonHttpException外還可使用特定的異常比如後端返回密碼錯誤異常:

    public class InvalidPasswordException extends BizException {
        ...
    }

    如需特殊處理,也可以滿足要求。

    健壯的數據層

    現在很多應用都開發使用MVVM開發模式數據層都使用Repository來表示,面向數據驅動的開發模式,頁面變化都需要隨着數據變更而更新,數據發生變化然後頁面再做出響應。Repository的拆分要細一點,不建議簡單的弄個UserRepository包含登陸、註冊、更新密碼等等操作,設計Repository的一些想法:

    1. 面向接口編程
    2. 保持單一原則
    3. 功能邊界要清晰(如:登陸、註冊可以分開)
    4. 業務邏輯盡可能的少(複雜的業務考慮Presenter)

    一個判斷是否是好的設計的辦法可以這樣:一個登陸頁面從Activive/Fragment到ViewModel再到Repository,有沒有多餘的代碼。比如上面說的UserRepository包含登陸、註冊但是在一個登陸頁面就不需要有註冊功能,從登陸頁面上來看註冊的代碼就是多餘的(有些App登陸/註冊在一個頁面的~~)。

    一個包含登陸、註冊的UserRepository簡單圖:

    另外一點是盡量將repository使用到的一些東西集中管理,可引入一個基礎的repository:

    public class SimpleRepository {
        
        protected final  <T> T getService(Class<T> clz){
            return Services.getService(clz);
        }
    }
    

    做為SimpleRepository的子類,就不需要考慮從哪裡獲取service的問題。

    簡潔的UI層

    UI層面可以分為ViewModel和View(Activity/Fragment), View的職責應當只有二點:

    1. 展示業務數據
    2. 收集業務數據

    例如一些數據的組織、判斷都不應該出現在View中比如:

     if (Strings.isNullOrEmpty(phone)) {
           ...
            return;
     }
    
     if (Strings.isNullOrEmpty(pwd)) {
            ...
            return;
      }

    像上面這類的代碼都不應該出現在View中,而在放置在ViewModel裏面,View只收集用戶數據傳遞給ViewModel由它來進行數據校驗。再比如像這樣的if/else代碼也應該放置在ViewModel中:

     int age = 10;
     String desc = "";
     if(age < 18){
        desc = "青年";
     }else if(age < 29){
        desc = "中年";
     }

    如果數據的显示和數據的收集過多,建議使用Databinding來進行雙向綁定數據。再搭配LiveData使View作為觀察者實時監聽數據變化:

    registerViewModel.getRegistryResult().observe(this, new SimpleObserver<RegistryInfo>(this));

    一旦數據發生變化LiveData就會通知Observer更新,通過DataBinding更新各個頁面數據。

    再說ViewModel應該只包含一些簡單的判斷、檢查、打通數據的代碼,如果業務過於複雜可以考慮加Presetner,如果真的超級複雜那可以反思下這個複雜的邏輯應不應該放在前端,能不能放在後端呢?

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理【其他文章推薦】

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

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

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

  • paper sharing :學習特徵演化的數據流

    paper sharing :學習特徵演化的數據流

    特徵演化的數據流

        數據流學習是近年來機器學習與數據挖掘領域的一個熱門的研究方向,數據流的場景和靜態數據集的場景最大的一個特點就是數據會發生演化,關於演化數據流的研究大多集中於概念漂移檢測(有監督學習),概念/聚類演化分析(無監督學習),然而,人們往往忽略了一個經常出現的演化場景:特徵演化。大多數研究都考慮數據流的特徵空間是固定的,然而,在很多場景下這一假設並不成立:例如,當有限壽命傳感器收集的數據被新的傳感器替代時,這些傳感器對應的特徵將發生變化。

        今天要分享的文章出自周志華的實驗室《Learning with Feature Evolvable Streams》(NIPS 2017),它提出了一個新的場景,即在數據流中會有特徵消亡也會有新特徵出現。當出現新的特徵空間時,我們並不直接拋棄之前學到的模型並在新的數據上重新創建模型,而是嘗試恢復消失的特徵來提升模型的表現。具體來說,通過從恢復的特徵和新的特徵空間中分別學習兩個模型。為了從恢復的特徵中獲得提升,論文中提出了兩種集成策略:第一種方法是合併兩個模型的預測結果;第二種是選擇最佳的預測模型。下面我們具體來理解特徵演化數據流以及論文中提出的一些有趣的方法吧~

    paper link:

     

    什麼是特徵演化數據流?

        在很多現實的任務中,數據都是源源不斷收集的,關於數據流學習的研究近年來受到越來越多的關注,雖然已經有很多有效的算法針對特定的場景對數據流進行挖掘,但是它們都基於一個假設就是數據流中數據的特徵空間是穩定的。不幸的是,這一假設在很多場景下都不滿足。針對特徵演化的場景,最直接的想法就是利用新的特徵空間的數據學習一個新的模型,但是這一方法有很多問題:首先,當新的特徵剛出現的時候,只有很少的數據樣本來描述這些信息,訓練樣本並不足夠去學習一個新的模型;其次,包含消失特徵的舊模型被直接丟棄了,其中可能包含對當前數據有用的信息。論文中定義了一種特徵演化數據流的場景:一般情況下,特徵不會任意改變,而在一些重疊時期,新特徵和舊特徵都存在,如下圖所示:

        其中,T1階段,原始特徵集都是有效的,B1階段出現了新的特徵集,T2階段原始特徵集消失,只有新的特徵集。

        論文提出的方法是通過使用重疊(B1)階段來發現新舊特徵之間的關係,嘗試學習新特徵到舊特徵的一個映射,這樣就可以通過重構舊特徵並使用舊模型對新數據進行預測

    問題描述

        論文中着重解決的是分類和回歸任務,在每一輪學習過程中,對每一個實例進行預測,結合它的真實標籤會得到一個loss(反映預測和真實標籤的差異),我們將上面提到的T1+B1+T的過程稱為一個周期,每個周期中只包含兩個特徵空間,所以,之後的研究主要關注一個周期內的模型的學習,而且,我們假設一個周期內的舊特徵會同時消失。定義Ω1和Ω2分別表示兩個特徵空間S1和S2上的線性模型,並定義映射,定義第i維特徵在第t輪的預測函數為線性模型,。損失函數是凸的,最直接的方式是使用在線梯度下降來求解w,但是在數據流上不適用。

     

    方法介紹

        上文提到的基本算法的主要限制是在第1,…T1輪學習的模型在T1+1,…T1+T2時候被忽略了,這是因為T1之後數據的特徵空間改變了,我們無法直接應用原來的模型。為了解決這一問題,我們假設新舊特徵空間之間有一種特定的關係:,我們嘗試通過重疊階段B1來學習這種關係。學習兩組特徵之間的關係的方法很多,如多元回歸,數據流多標籤學習等。但是在當前的場景下,由於重疊階段特別短,學習一個複雜的關係模型是不現實的。所以我們採用線性映射來近似。定義線性映射的係數矩陣為M,那麼在B1階段,M的估計可以基於如下的目標方程:

    M的最優解可以解得:

        然後,當我觀測到S2空間得數據,就可以通過M將其轉化到S1空間,並應用舊模型對其進行預測。

    除了學習這個關係映射之外,我們得算法主要包括兩個部分:

    1. 在T1-B1+1,…T1階段,我們學習兩個特徵空間之間得關係;

    2. 在T1之後,我們使用新特徵空間的數據轉化后的原特徵空間數據,持續更新舊模型以提升它的預測效果,然後集成兩個模型進行預測。

     

    預測結果集成

        論文中提出兩種集成方法,第一種是加權組合,即將兩個模型的預測結果求加權平均,權重是基於exponential of the cumulative loss。

    其中

        這種權重的更新規則表明,如果上一輪模型的損失較大,下一輪模型的權值將以指數速度下降,這是合理的,可以得到很好的理論結果。

        第二種集成方法是動態選擇。

        上面提到的組合的方法結合了幾個模型來提升整體性能,通常來說,組合多個分類器的表現會比單分類器的效果要好,但是,這基於一個重要的假設就是每個基分類器的表現不能太差(如,在Adaboost中,基分類器的預測精度不應低於0.5)。然而在這個問題中,由於新特徵空間剛出現的時候訓練集較小,訓練的模型不好,因此可能並不適合用組合的方法來預測,相反,用動態選擇最優模型的方法反而能獲得好的效果。

    有趣的靈魂在等你長按二維碼識別

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理【其他文章推薦】

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

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

    ※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

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

  • Go 多變量賦值時注意事項

    說到多變量賦值時,先計算所有相關值,然後再從左到右依次賦值,但是這個規則不適用於python
    我們來看一例:

    package main
    
    import "fmt"
    
    func main() {
        data, i := [3]string{"喬幫主","慕容復","鳩摩智"}, 0
        i, data[i] = 2, "枯榮大師"
        fmt.Println(i, data)
    }

    輸出結果:

    2 [枯榮大師 慕容復 鳩摩智]  

    有的朋友會認為,結果不應該是這樣么?(但是python下輸出的結果卻是下面的)?

    2 [喬幫主 慕容復 枯榮大師]

    事實並如此,我們來看賦值順序這段的理解:

    1     data, i := [3]string{"喬幫主","慕容復","鳩摩智"}, 0
    2     i, data[i] = 2, "枯榮大師" //注意原則:先計算所有相關值,然後再從左到右依次賦值
    3     // 這裏變量i 的順序其實是(i = 0,因為上一行的變量i是0) -> (然後 i = 2), (data[i] 此時取的值是data[0],而不是data[2],也就是data[0] = 枯榮大師)
    4     fmt.Println(i, data) //所以這裏最終 輸出 i=2,[枯榮大師 慕容復 鳩摩智]

    同樣的多變量賦值卻不適用於python.

    data,i=["喬幫主", "慕容復", "鳩摩智"],0
    i, data[i] = 2, "枯榮大師" # 注意這裏data[i] 已經是 data[2]了,即data[2]="枯榮大師"
    print(i,data) # 輸出 2 ['喬幫主', '慕容復', '枯榮大師']

    另外:我們要注意重新賦值與定義新同名變量的區別:再看一例:

    package main
    
    func main() {
        name := "喬幫主"
        println(&name)
        name, age := "鳩摩智", 30 // 重新賦值: 與前 name 在同層次的代碼塊中,且有新的變量被定義。
        println(&name, age)    // 通常函數多返回值 err 會被重複使用。
        {
            name, weight := "清風揚", 50 // 定義新同名變量: 不在同層次代碼塊。
            println(&name, weight)
        }
    }

    輸出:

    0xc00002bf78
    0xc00002bf78 30
    0xc00002bf68 50

    注意:因個人機器不同,大家返回的內存引用地址可能和我的不一樣,但是 這步是重點。重點在這裏:
    同層級相同變量的賦值,內存地址並不會改變。不同層級相同變量的賦值,其實是定義了一個新同名變量,也就是大家看到的第三行內存地址變了。
    接着我們再看有點意思的一段代碼(大家來找茬):

    package main
    
    func main() {
        name := "喬幫主"
        println(&name)
        name, age := "鳩摩智", 30 // 重新賦值: 與前 name 在同 層次的代碼塊中,且有新的變量被定義。
        println(&name, age)    // 通常函數多返回值 err 會被重複使用。
    
        name, weight := 100, 50 // 定義新同名變量: 不在同 層次代碼塊。
        println(&name, weight, age)
    
    }

    輸出:

    cannot use 100 (type int) as type string in assignment

    原因很明顯,因為上面:name := “喬幫主” 已經隱試滴申明了name 是字符串,等同於 var name string. 同層級再次賦值100為整形。這是不允許滴,

    但是:重點來了,我們稍改下:

    package main
    
    func main() {
        name := "喬幫主"
        println(&name)
        name, age := "鳩摩智", 30 // 重新賦值: 與前 name 在同 層次的代碼塊中,且有新的變量被定義。
        println(&name, age)    // 通常函數多返回值 err 會被重複使用。
        {
            name, weight := 100, 50 // 定義新同名變量: 不在同層次代碼塊。
            println(&name, weight, age)
        }
    }

    區別就是層級發生了變化,因為{}裏面的name已經是新的變量了。
    好啦,到此介紹結束了。博友們有關golang變量使用中遇到的各種奇怪的“坑”,請留下寶貴滴足跡,歡迎拍磚留言.

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理【其他文章推薦】

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

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

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

  • 【併發編程】Java中的原子操作

    【併發編程】Java中的原子操作

    什麼是原子操作

    原子操作是指一個或者多個不可再分割的操作。這些操作的執行順序不能被打亂,這些步驟也不可以被切割而只執行其中的一部分(不可中斷性)。舉個列子:

    //就是一個原子操作
    int i = 1;
    
    //非原子操作,i++是一個多步操作,而且是可以被中斷的。
    //i++可以被分割成3步,第一步讀取i的值,第二步計算i+1;第三部將最終值賦值給i
    i++;

    Java中的原子操作

    在Java中,我們可以通過同步鎖或者CAS操作來實現原子操作。

    CAS操作

    CAS是Compare and swap的簡稱,這個操作是硬件級別的操作,在硬件層面保證了操作的原子性。CAS有3個操作數,內存值V,舊的預期值A,要修改的新值B。當且僅當預期值A和內存值V相同時,將內存值V修改為B,否則什麼都不做。Java中的sun.misc.Unsafe類提供了compareAndSwapIntcompareAndSwapLong等幾個方法實現CAS。

    另外,在jdk的atomic包下面提供了很多基於CAS實現的原子操作類,見下圖:

    下面我們就使用其中的AtomicInteger來看看怎麼使用這些原子操作類。

    package com.csx.demo.spring.boot.concurrent.atomic;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.atomic.AtomicInteger;
    
    public class AtomicIntegerDemo {
    
        private static int THREAD_COUNT = 100;
    
        public static void main(String[] args) throws InterruptedException {
    
    
            NormalCounter normalCounter = new NormalCounter("normalCounter",0);
            SafeCounter safeCounter = new SafeCounter("safeCounter",0);
            List<Thread> threadList = new ArrayList<>();
    
            for (int i = 0; i < THREAD_COUNT ; i++) {
                Thread thread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        for (int j = 0; j < 10000; j++) {
                            normalCounter.add(1);
                            safeCounter.add(1);
                        }
                    }
                });
                threadList.add(thread);
            }
    
            for (Thread thread : threadList) {
                thread.start();
            }
            for (Thread thread : threadList) {
                thread.join();
            }
            System.out.println("normalCounter:"+normalCounter.getCount());
            System.out.println("safeCounter:"+safeCounter.getCount());
        }
    
    
        public static class NormalCounter{
            private String name;
            private Integer count;
    
            public NormalCounter(String name, Integer count) {
                this.name = name;
                this.count = count;
            }
    
            public void add(int delta){
                this.count = count+delta;
            }
    
            public String getName() {
                return name;
            }
    
            public void setName(String name) {
                this.name = name;
            }
    
            public Integer getCount() {
                return count;
            }
    
            public void setCount(Integer count) {
                this.count = count;
            }
        }
    
        public static class SafeCounter{
            private String name;
            private AtomicInteger count;
    
            public SafeCounter(String name, Integer count) {
                this.name = name;
                this.count = new AtomicInteger(count);
            }
    
            public void add(int delta){
                count.addAndGet(delta);
            }
    
            public String getName() {
                return name;
            }
    
            public void setName(String name) {
                this.name = name;
            }
    
            public int getCount() {
                return count.get();
            }
    
            public void setCount(Integer count) {
                this.count.set(count);
            }
        }
    
    }

    上面的代碼中,我們分別創建了一個普通的計數器和一個原子操作的計數器(使用AtomicInteger進行計數)。然後創建了100個線程,每個線程進行10000次計數。理論上線程執行完之後,計數器的值都是1000000,但是結果如下:

    normalCounter:496527
    safeCounter:1000000

    每次執行,普通計數器的值都是不一樣的,而使用AtomicInteger進行計數的計數器都是1000000。

    CAS操作存在的問題

    • ABA問題:因為CAS需要在操作值的時候檢查下值有沒有發生變化,如果沒有發生變化則更新,但是如果一個值原來是A,變成了B,又變成了A,那麼使用CAS進行檢查時會發現它的值沒有發生變化,但是實際上卻變化了。ABA問題的解決思路就是使用版本號。在變量前面追加上版本號,每次變量更新的時候把版本號加一,那麼A-B-A 就會變成1A-2B-3A。

    從Java1.5開始JDK的atomic包里提供了一個類AtomicStampedReference來解決ABA問題。這個類的compareAndSet方法作用是首先檢查當前引用是否等於預期引用,並且當前標誌是否等於預期標誌,如果全部相等,則以原子方式將該引用和該標誌的值設置為給定的更新值。

    • 循環時間長開銷大:自旋CAS如果長時間不成功,會給CPU帶來非常大的執行開銷。如果JVM能支持處理器提供的pause指令那麼效率會有一定的提升,pause指令有兩個作用,第一它可以延遲流水線執行指令(de-pipeline),使CPU不會消耗過多的執行資源,延遲的時間取決於具體實現的版本,在一些處理器上延遲時間是零。第二它可以避免在退出循環的時候因內存順序衝突(memory order violation)而引起CPU流水線被清空(CPU pipeline flush),從而提高CPU的執行效率。

    • 只能保證一個共享變量的原子操作:當對一個共享變量執行操作時,我們可以使用循環CAS的方式來保證原子操作,但是對多個共享變量操作時,循環CAS就無法保證操作的原子性,這個時候就可以用鎖,或者有一個取巧的辦法,就是把多個共享變量合併成一個共享變量來操作。比如有兩個共享變量i=2,j=a,合併一下ij=2a,然後用CAS來操作ij。從Java1.5開始JDK提供了AtomicReference類來保證引用對象之間的原子性,你可以把多個變量放在一個對象里來進行CAS操作。

    使用鎖來保證原子操作

    還是以上面的列子為列,普通的計數器我們只需要在計數方法上加鎖就行了:

    public synchronized void  add(int delta){
      this.count = count+delta;
    }

    執行結果如下:

    normalCounter:1000000
    safeCounter:1000000

    兩個計數器都能拿到正確的結果

    CPU是怎麼實現原子操作的

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理【其他文章推薦】

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

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

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

  • 三個月(敏捷)項目收穫

    三個月(敏捷)項目收穫

     

     

    項目背景

    客戶已有運行多年的官網老站(PC端),想在今年對老站進行一次UI全面更新、功能全部平移的升級,對接新的運營後端,然後建立官網小程序端且與官網PC端進行聯動,使得品牌自有渠道能夠更加全面化。

     

    挑戰

    • 時間緊。五月份進行Inception Workshop,確定項目交付範圍與架構方案。官網六月初開始開發,小程序八月份開始開發,整個項目九月中旬必須上線。
    • 系統集成和數據遷移。系統需要對接客戶的CRM,對接3個服務商,需要對老官網歷史數據(訂單、會員等)進行遷移。
    • 多團隊溝通。小程序設計稿由第三方提供,因此多出了溝通、確認的時間,以及把控第三方交付的時間,以避免交付進度的影響。

     

    迭代計劃

    Inception Workshop一結束,差不多就開始整理整個項目涉及的故事和技術卡,按照兩周一迭代進行迭代計劃安排並與客戶確認,每個迭代第一周周三安排跟客戶showcase上一周的預定的交付結果,得到反饋並安排進行改進。官網項目比較順利,改造自定義了一下SSR框架就能開始進行開發,並且因為歷史原因,還能享受到上一個項目遺留的一些福利,當然也少不了一些坑。

    小程序的時間比較緊,相當於整個複製了一遍官網的功能,主要是前端任務,後端可以復用官網後端,因此一開始就給團隊同學同步到整個項目的情況,讓大家有一個大概的心理準備。然後就是與官網類似的處理,整個交付內容進行迭代排期並與客戶確認,前期盡量能多做一些,避免後期怎麼努力都無法完成的囧鏡。

     

    項目進行時

    整個項目的過程中,PM會根據迭代完成情況靈活的找外援加入項目進行支援,以免交付延期。每日的站會(Standup Meeting)更新,讓團隊能對當前進度有一個大概的了解以及同步一些突發信息。定期的回顧會議(Retrospective Meeting)能暴露團隊內部問題,將風險扼殺於苗頭,鼓勵能為團隊帶來正向幫助的行為,及時停止不好的做法。

    迭代會議(IPM)能讓團隊對下一個迭代具體要做的事情有一個詳細的了解,進行大致的估點,以便check開發進度情況。技術人員定期的CodeReview成為一個大家交流的時段,發現風險,指出問題,互相提高,還可以幫助新人快速的融入團隊。

    根據團隊內部人員情況,可以定期進行一對一溝通,了解個人訴求或是給與近況反饋都是一個不錯的渠道。TL應考慮團隊內部人員提升自己的訴求,在一些安排上給與傾斜和鼓勵,發現問題也需要提前制止。

     

    不足之處

    • 後期對卡牆(Jira)的管理鬆懈。導致有些問題反覆修改,且丟失context
    • 項目對運營後台有一些的定製化配置,沒有提前準備運營需要了解的後台操作資料和培訓,導致後期花費大量精力幫助運營進行後台配置與更新
    • 人員(QA)變動頻繁。公司處於高速發展階段,項目經歷了4個QA,因此有些context可能丟失,測試不到位,導致項目上線出了一些低級問題。比如上線后發現部分瀏覽器有支付兼容問題
    • 甲乙方定位太角色化,不能站在專業角度評估客戶需求(項目做完感覺都一樣,客戶是爸爸)
    • 與第三方合作交付產物管控不到位,導致第三方設計稿的延遲影響到我們的交付計劃
    • 與客戶溝通的需求,後面有一些沒有進行郵件確認,導致交付驗收階段因一些需求上的問題產生不愉快(這個完全沒必要的)
    • 對第三方系統的了解不充分和集成系統的需求整理不清晰導致後續一系列的開發、測試都不到位,以致上線出了不可控的問題

     

    項目總結

    • 提前評估項目的風險點,且在項目進行過程中持續維護,後期安排足夠的時間進行調研與分析
    • 與第三方合作一定要有自己的規劃,並且將定好的規劃提前與第三方確認時間,然後派人提前專門細緻的了解第三方需求詳細點,確定好具體的業務場景,再來規劃己方與第三方的具體集成的點。此外,在進行的過程中,還應注意定時檢查合作進度,管控風險
    • 與客戶溝通的所有需求都要進行郵件的二次確認,一個是能夠對所有需求來源有所記錄,另一個是能避免後面的不必要的消耗
    • 開發管理不能鬆懈,盡量做到所有的改動都能有卡,能夠進行追溯
    • 對後期交付時所需要的資料提前準備,對需要進行培訓的人員提前約好時間進行溝通培訓

    在前端這塊的管理上,做的還不夠。前期經常codereview,然後效果都還不錯,讓我有了一些錯覺就是當前團隊趨於穩定,中後期即便是加班比較多,大家氣氛這塊我覺得都還好。不過在項目後期的時候,有些疏於管理,然後大家有些人也被分配到了其他項目,和同事們的交流不夠,沒有及時的顧及到一些個人情緒,這塊是可以加強的。

    作為一個Lead,不論同事是否還在一個項目都應該及時的去了解近況,給與自己力所能及的幫助,這樣才能產生向心力,以幫助一些比較迷茫的同學找到方向,看見燈塔。

    整個項目時間不長,得失還是挺多的,不論是管理還是技術上,都會有一些心得。然後項目的ROI還不錯,得到公司領導的肯定,最後客戶那邊的反饋也還不錯,算是對大家努力的一種認可。

    ps: 及時總結,靜心沉澱;如風少年,砥礪前行。

    如想了解更多,請移步

    歡迎關注我的公眾號 “和F君一起xx”

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理【其他文章推薦】

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

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

    ※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

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