lin-cms-dotnetcore功能模塊的設計

lin-cms-dotnetcore功能模塊的設計

先來回答以下問題。可拉到最下面查看預覽圖。

1.什麼是cms?

Content Management System,內容管理系統。

2.dotnetcore是什麼?

.NET Core,是由Microsoft開發,目前在.NET Foundation(一個非營利的開源組織)下進行管理,採用寬鬆的MIT協議,可構建各種軟件,包括Web應用程序、移動應用程序、桌面應用程序、雲服務、微服務、API、遊戲和物聯網應用程序。

3.lin-cms 是什麼?

Lin-CMS 是林間有風團隊經過大量項目實踐所提煉出的一套內容管理系統框架。Lin-CMS 可以有效的幫助開發者提高 CMS 的開發效率,

Lin的定位在於實現一套 CMS的解決方案,管理系統的基礎框架,提供了不同的後端,不同的前端實現,後端也支持不同的數據庫,是一套前後端完整的解決方案

目前官方團隊維護 lin-cms-vue,lin-cms-spring-boot,lin-cms-koa,lin-cms-flask 社區維護了 lin-cms-tp5,lin-cms-react,lin-cms-dotnetcore,即已支持vue,react二種前端框架,java,nodejs,python,php,c#等五種後端語言。

lin-cms-vue(官方)

  • https://github.com/TaleLin/lin-cms-vue
  • Vue+ElementUI構建的CMS開發框架,
  • 林間有風團隊經過大量項目實踐所提煉出的一套內容管理系統框架
  • 內置了 CMS 中最為常見的需求:用戶管理、權限管理、日誌系統等

lin-cms-koa(官方)

  • python
  • https://github.com/TaleLin/lin-cms-koa
  • 使用Node.JS KOA構建的CMS開發框架

lin-cms-flask(官方)

  • node.js
  • https://github.com/TaleLin/lin-cms-flask
  • A simple and practical CMS implememted by flask

lin-cms-spring-boot(官方)

  • java
  • https://github.com/TaleLin/lin-cms-spring-boot
  • 基於SpringBoot的CMS/DMS/管理系統開發框架

lin-cms-tp5(社區)

  • php 被官方fork。
  • https://github.com/TaleLin/lin-cms-tp5
  • A simple and practical CMS implememted by ThinkPHP 5.1

lin-cms-react(社區)

  • https://github.com/Bongkai/lin-cms-react
  • React+Antd構建的CMS開發框架

lin-cms-dotnetcore(社區)

  • C#
  • A simple and practical CMS implemented by .NET Core 3.1 一個簡單實用、基於.NET Core
  • https://github.com/luoyunchong/lin-cms-dotnetcore
  • .NET Core 3.1實現的CMS;前後端分離、Docker部署、OAtuh2授權登錄、自動化部署DevOps、GitHub Action同步至Gitee

4.lin-cms-dotnetcore有哪些特點?

基於.NET Core3.1實現的LIN-CMS-VUE後端API,並增加了博客模塊。目前實現簡約的權限管理系統、基礎字典項管理、隨筆專欄,評論點贊、關注用戶、技術頻道(標籤分類)、消息通知,標籤等仿掘金模塊。

功能模塊的設計

基礎權限模塊

  • 用戶信息:郵件、用戶名(唯一)、昵稱、頭像、分組、是否激活、手機號、是否是Admin、個性簽名
    • [x] 註冊/登錄
    • [x] 上傳頭像
    • [x] 修改個人密碼
    • [x] 用戶基本信息修改
    • [x] 用戶增刪改,配置分組
  • 綁定第三方賬號
    • [x] GitHub登錄
    • [x] QQ 登錄
    • [ ] Gitee登錄
  • 分組信息:是否靜態分組(無法刪除,無法修改分組編碼)、名稱可以修改
    • [x] 分組增刪改
    • [x] 分組配置權限
  • 文件管理
    • [x] 本地文件上傳
    • [x] 七牛雲存儲
    • [x] 文件去重,秒傳
  • 系統日誌:請求方法、路徑、http返回碼、時間、用戶昵稱、用戶id、訪問哪個權限、 日誌信息
    • [x] 記錄系統請求的日誌
    • [ ] 異常日誌
  • 設置管理:name(鍵),value(值),provider_name(提供名),provider_key(提供者值)
    • [x] 設置新增修改刪除
    • [x] 所有設置

比如存某用戶選擇的是markdown還是富文本。

name="Article.Editor",
value="markdown" 或 "富文本",
provider_name為"User",
provider_key為用戶Id

或存儲七牛雲的某一個配置

name="Qiniu.AK",
value="asfadsfadf23rft66S4XM2GIK7FxfqefauYkcAyNGDAc" ,
provider_name為"Qiniu"或自己定義的字符串
provider_key為空

cms 管理員維護模塊

  • [x] 標籤管理:名稱、圖片,是否啟用/禁用,排序、文章數量、用戶關注數量。
    • [x] 標籤增刪改
    • [x] 標籤列表,禁用
    • [x] 校正文章數量
  • [x] 技術頻道:封面圖、名稱、是否啟用/禁用、排序、編碼、備註描述、下屬標籤.一個技術頻道對應多個標籤
    • [x] 技術頻道增刪改
    • [x] 列表、禁用
  • [x] 隨筆管理:
    • [x] 審核隨筆/拉黑
    • [x] 管理員刪除隨筆
  • [x] 評論管理
    • [x] 後台審核通過/拉黑
    • [x] 管理員刪除評論
  • [x] 字典類別管理:編碼,名稱,排序
    • [x] 增刪改查
  • [x] 字典管理::編碼,名稱,排序,類別:如隨筆類型(原創、轉載、翻譯)
    • [x] 增刪改查

cms 用戶端模塊

  • 技術頻道
    • [x] 首頁展示技術頻道
    • [x] 選擇技術頻道后,可再根據標籤查詢文章
  • 分類專欄管理:發布隨筆時可選擇單個分類。
    • [x] 分類增刪改(隨筆數量、圖片、名稱、排序)
    • [x] 分類列表,僅查看、編輯自己創建的分類專欄
  • 標籤:統計每個標籤下多少個文章、多少人關注
    • [x] 標籤列表
    • [x] 無限加載
    • [x] 最新/最熱 根據標籤名稱模糊查詢
    • [x] 已關注的標籤
    • [x] 熱門標籤
  • 隨筆
    • [x] 支持markdown,增刪改(僅自己的隨筆),修正分類專欄中的隨筆數量
    • [x] 支持富文本編輯隨筆
    • [x] 列表無限加載,按標籤查詢隨筆
    • [x] 點贊隨筆
    • 隨筆詳情頁
      • [x] 支持目錄導航(滾動時,固定至頂部位置),展示字數統計、預計閱讀時長;
      • [x] 作者介紹:頭像,昵稱,簽名,隨筆數;
      • [x] 展示文章類型:原創、轉載、翻譯
      • [ ] 相關文章
      • [ ] 推薦文章
  • 評論
    • [ ] 用戶關閉評論時,無法對隨筆進行評論
    • [ ] 評論隨筆(內容支持超鏈接、emoji)
    • [x] 刪除自己的評論
    • [x] 點贊評論
    • [x] 回複評論
  • 關注
    • [x] 關注/取消關注用戶
    • [x] 關注/取消關註標簽
    • [x] 我關注的用戶發隨筆
  • 個人主頁
    • 隨筆
      • [x] 用戶專欄分類展示
      • [x] 最新發布的隨筆
    • 關注
      • [x] 關注的用戶
      • [x] 粉絲
      • [x] 關注的標籤
  • 設置
    • 個人主頁設置
      • [x] 個人資料更新
    • 安全設置
      • [x] 密碼修改:快速登錄的賬號,初次設置時可留空
    • 博客設置
      • [x] 編輯器設置,(可切換markdown/富文本)
      • [x] 代碼風格配置(tango、native、monokai、github、solarized-light、vs)
  • 消息
    • [x] 評論:點贊評論、評論隨筆、回複評論
    • [x] 喜歡和贊:點贊隨筆、點贊評論
    • [x] 關注,誰誰關注了你

腦圖分享

http://naotu.baidu.com/file/6532431a2e1f0c37c93c5ffd1dd5b49c?token=87690a9bc64fbae1

分組

分為三種

id  name        info
1	Admin	    系統管理員
2	CmsAdmin	內容管理員
3	User	    普通用戶

審計日誌

大多數表存在如下8個字段,用於記錄行的變化狀態,is_deleted為軟刪除,執行刪除操作時,將其狀態置為true,默認實體類繼承 FullAduitEntity 即可擁有以下8個字段。該設計參考ABP中的實現。FullAduitEntity為泛型,默認id為long類型,FullAduitEntity<Guid>,即可改變主鍵類型,默認LinUser表主鍵long,保持create_user_id,delete_user_id,update_user_id都與LinUser的主鍵相同


id	                bigint
create_user_id  	bigint
create_time	        datetime
is_deleted	        bit
delete_user_id  	bigint
delete_time	        datetime
update_user_id	    bigint
update_time	        datetime


相關技術

  • 數據庫相關:ORM:FreeSql+DataBase:MySQL5.6
  • ASP.NET Core3.1+WebAPI+RESTful
  • 簡化對象映射:AutoMapper
  • 身份認證框架:IdentityServer4
  • Json Web令牌:JWT
  • 文檔API:Swagger(Swashbuckle.AspNetCore)
  • 序列化:Newtonsoft.Json
  • 測試框架:Xunit
  • 日誌 Serilog
  • 依賴注入服務AutoFac
  • 通用擴展方法 Z.ExtensionMethods
  • 雲存儲:七牛雲 MQiniu.Core
  • 分佈式事務、EventBus:DotNeteCore.CAP
  • GitHub第三方授權登錄AspNet.Security.OAuth.GitHub
  • QQ第三方授權登錄AspNet.Security.OAuth.QQ
  • Docker
  • Azure DevOps
  • 健康檢查AspNetCore.HealthChecks.UI.Client
  • GitHub Action同步至Gitee

分層結構(Layers)

  • framework
    • IGeekfan.CAP.MySql:為CAP實現了配合FreeSql的事務一致性擴展
  • identityserver4
    • LinCms.IdentityServer4:使用id4授權登錄
  • src
    • LinCms.Web:接口API(ASP.NET Core)
    • LinCms.Application:應用服務
    • LinCms.Application.Contracts:DTO,數據傳輸對象,應用服務接口
    • LinCms.Infrastructure:基礎設施,數據庫持久性的操作
    • LinCms.Core:該應用的核心,實體類,通用操作類,AOP擴展,分頁對象,基礎依賴對象接口,時間擴展方法,當前用戶信息,異常類,值對象
    • LinCms.Plugins 使用單項目實現某個業務的擴展,不需要主要項目結構,可暫時忽略。
  • test
    • LinCms.Test:對倉儲,應用服務或工具類進行測試

功能特性

  • [x] Azure Devops CI/CD構建
  • [x] GitHub Action實現 GitHub Gitee代碼同步
  • [x] .Net Core結合AspNetCoreRateLimit實現限流
  • [x] 方法級別權限控制
  • 社交賬號管理:支持多種第三社交賬號登錄,不干涉原用戶數據,實現第三方賬號管理
  • 多語言
  • [x] 全局敏感詞處理
  • 日誌記錄,方便線上排查錯誤
  • [ ] 支持多種數據庫,並測試,
    • [x] Mysql
    • [ ] Postgresql
    • [ ] Sql Server
    • [ ] SQlite

產品設計-評論模塊的設計

下面我們來設計一個評論模塊,需要注意的是,一個評論模塊也有不同的方式。從展示形式,排序規則,按鈕功能設計,操作等方式都有詳細的分析設計,大家可以參考who shi pm 中的文章http://www.woshipm.com/pd/3548139.html,這裏主要講解下展式方式中的主題式的應用。

1.主題式

相信很多人都刷過抖音,他的評論主題式的強化版。

特點為前三個是熱門評論(喜歡最多的評論),將評論分為二級,第一級採用時間倒序,第二級按照時間正序,有助於理解上下文關係。

可以總結為如下功能點

用戶操作:

  • [x] 評論隨筆(內容支持超鏈接、emoji)
  • [x] 點贊評論/取消點贊
  • [x] 回複評論
  • [x] 刪除自己的評論

運營操作:

  • [x] 審核通過/拉黑評論
  • [x] 刪除任何評論
  • [x] 拉黑后的显示邏輯。(保留當前區塊、显示內容為:該評論因違規被拉黑)
  • 刪除:(如果是二級評論,直接軟刪除,如果是一級評論,軟刪除子評論和當前評論-需要提前提醒用戶)

交互設計

  • 評論的字數長度(500)、emoji。
  • 點贊交互-動畫、消息通知/推送
  • 評論區域元素,需要有明確可點擊的區域,會跳轉到哪個地方。

優化

  • 精選或者叫置頂評論
  • 該文章是否開放評論功能。
  • 熱門評論(點贊最多的評論)
  • 標註哪些評論是作者,標準哪些評論被用戶點贊。
  • @邏輯,emoji,舉報等

2 平鋪式

特點是不區分子父節點關係,比如現在博客園(大多數的主題),微信朋友圈,github。
不過博客園,github,回復時,可選擇引用回復,方便用戶理解上下文關係。

3.蓋樓式

這種方式有點這種感覺 》>-,即.net core中間件請求方式。當回復越來越多時,显示的效果就越誇張。一層套一層的显示上下文的關係。下圖是網易新聞的評論效果。

排行榜見解

排行榜從心理學上分析,主要從四個方面影響着您:尋找權威 、參与比較 、關注主流 、自我確認。

如何設計一個簡單的排行榜呢。。

在一個博客隨筆中,我們設計一個3天、七天(周榜)、30天(月榜)、全部的榜單。以瀏覽量(權重1)、點贊量(20)、評論量(30)。權重可自己定義。

1.默認取最新的隨筆

前台傳create_time時,使用如下sql

select * from `blog_article` order by create_time desc;

2.傳排序方式為最近n天的熱榜時。

參數:THREE_DAYS_HOTTEST(三天)、WEEKLY_HOTTEST(七天)、MONTHLY_HOTTEST(一個月)、HOTTEST(全部)

mysql 查詢當前日期時間前三天數據

select date_sub(now() ,interval 3 day);

根據權重查詢

select * from `blog_article` a 
where a.`create_time`>(select date_sub(now() ,interval 3 day))
order by (a.`view_hits` + a.`likes_quantity` * 20 + a.`comment_quantity` * 30) DESC, a.`create_time` DESC

更多參考

  • 評論區如何設計?
  • 萬字長文深度分析:產品排行榜的設計和玩法
  • 想知道誰是你的最佳用戶?基於Redis實現排行榜周期榜與最近N期榜

lin-cms 開源地址分享

  • 後端接口 https://github.com/luoyunchong/lin-cms-dotnetcore
  • 管理後台UI https://github.com/luoyunchong/lin-cms-vue
  • 前端UIhttps://github.com/luoyunchong/lin-cms-vvlog

Demo

  • 用戶端 lin-cms-vvlog https://vvlog.baimocore.cn

    • 普通用戶:710277267@qq.com
    • 密碼:123qwe
  • 管理員 lin-cms-vue https://cms.baimocore.cn/

    • 管理員: admin
    • 密碼:123qwe

預覽圖

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

【其他文章推薦】

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

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

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

※幫你省時又省力,新北清潔一流服務好口碑

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

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

邊緣計算告訴你們公司空調怎麼開最省錢

據統計,現代城市人的生活與工作同樓宇息息相關,超過80%的時間都是在城市樓宇中度過,樓宇智能毋庸置疑是影響深遠的關鍵研究課題。

近年來,隨着邊緣計算技術的崛起,邊緣智能相關的場景應用拓展也成為科技公司爭相展現技術創新和商業價值的路徑,各種邊緣AI的解決方案亦應運而生,如華為雲智能邊緣平台IEF,一站式端雲協同多模態AI開發平台HiLens。據統計,現代城市人的生活與工作同樓宇息息相關,超過80%的時間都是在城市樓宇中度過,樓宇智能毋庸置疑是影響深遠的關鍵研究課題。本文將圍繞樓宇智能其中最重要的課題之一中央空調能效預測與管理來展開,目前,該課題面臨最大的瓶頸是:現有的大多數能效預測與管理方法僅限於雲端單任務,無法支撐中央空調能效模型在邊緣隱含的大量複雜場景上的能力。

眾所周知,暖通空調系統(包括供暖,通風和空調)主導着商業建築的用電量。對暖通空調系統的現有研究表明,準確量化冷水機組的能效比(數值越大越節能)非常重要,近期提出的數據驅動的能效比預測可以被應用到雲上。但是,由於不同園區擁有不同型號的空調或不同種類的傳感器,導致不同邊緣各個項目在特徵、模型等方面區別很大,在小樣本情況下很難用一個通用模型適應所有的項目。

近年來,華為雲邊緣雲創新lab與來自香港理工大學、IBM研究院、華中科技大學、同濟大學、深圳大學等知名校企研究團隊密切合作並持續開展技術研究,以邊緣樓宇智能領域場景為依託,希望逐步解決現實中隱含大量複雜場景的邊緣智能問題。有興趣的讀者歡迎關注2018到2020間年發表的多任務學習、多任務調度和多任務應用等歷史工作:

通用算法:多任務遷移與邊緣調度

基於元數據的多任務遷移關係發現

Zheng, Z., Wang Y., Dai Q., Zheng H., Wang, D. “Metadata-driven task relation discovery for multi-task learning.” In Proceedings of IJCAI (CCF-A), 2019.

在這篇論文中有一個多任務的實際應用案例,不同邊緣智能項目採用不同設備使得邊緣側模型不同,從而可以應用於多任務設定。這篇論文的亮點是引入元數據,元數據是數據集的描述信息,在複雜系統中用於日常系統運作,蘊含專家信息。基於元數據提取任務屬性,本論文設計了元數據任務屬性與樣本任務屬性層次結合的多任務通用AI算法(圖1)。相關論文專家評審也認為該技術在應用實踐中显示了實用價值,對機器學習項目真正落地具備重要意義,將成為當今大型組織感興趣的技術。

圖1 顏色代表不同聚類簇,数字代表不同設備型號。基於樣本屬性的方法容易導致負遷移(同一簇中混淆不同型號設備模型,左圖),而基於元數據的方法可以避免負遷移(右圖)。

多任務遷移學習的邊緣任務分配系統與實現

Zheng, Z., Chen, Q., Hu, C., Wang, D., & Liu, F. “On-edge Multi-task Transfer Learning: Model and Practice with Data-driven Task Allocation.” In Proceedings of IEEE TPDS (CCF-A), 2019.

Chen, Q., Zheng, Z., Hu, C., Wang, D., & Liu, F. “Data-driven task allocation for multi-task transfer learning on the edge. ” In Proceedings of IEEE ICDCS (CCF-B), 2019.

多任務遷移學習是解決邊緣上樣本不足的典型做法。而目前邊緣上的任務分配調度工作通常假設不同的多個任務是同等重要的,導致資源分配在任務層面不夠高效。為了提升系統性能與服務質量,我們發現不同任務對決策的重要性是一個亟需衡量的重要指標。我們證明了基於重要性的任務分配是NP-complete的背包問題變種,並且在多變的邊緣場景下該複雜問題的解需要被頻繁地重新計算。因此我們提出一個用於解決該邊緣計算問題的AI驅動算法,並且在實際多變的邊緣場景中進行算法測試(圖2),與SOTA算法相比該算法能減少3倍以上的處理時間和近50%的能源消耗。

圖2 根據邊緣場景動態進行任務分配調度

邊緣應用:樓宇智能

基於多任務的冷機負荷控制

Zheng, Z., Chen, Q., Fan, C., Guan, N., Vishwanath, A., Wang, D., & Liu, F. “Data Driven Chiller Sequencing for Reducing HVAC Electricity Consumption in Commercial Buildings.” In Proceedings of ACM e-Energy, 2018. Best Paper Award.

Zheng, Z., Chen, Q., Fan, C., Guan, N., Vishwanath, A., Wang, D., & Liu, F. “An Edge Based Data-Driven Chiller Sequencing Framework for HVAC Electricity Consumption Reduction in Commercial Buildings.” IEEE Transactions on Sustainable Computing, 2019.

多任務可以應用於樓宇節能中。冷機是樓宇中的耗能大戶。冷機能效預測與管理,預測冷機負荷決策的能效比並優化冷機負荷決策,一直是樓宇智能最重要的研究問題之一。本研究觀測到,在冷機決策能效預測中,不同邊緣項目的設備型號和工況不同會導致最終需求的模型不同。這種情況下僅採用雲端單一模型的做法容易導致精度下降和決策失誤。本工作研發了一種邊雲協同的多任務冷機負荷決策框架(圖3),在利用現有端邊節點且不部署額外硬件的情況下,較當前工業界方法節能30%以上。

圖3 邊雲協同的冷機負荷決策框架

基於多任務的空調舒適度預測

Zheng, Z., Dai Y., Wang D., “DUET: Towards a Portable Thermal Comfort Model.” In Proceedings of ACM BuildSys (Core rank A), 2019.

Yang, L., Zheng, Z., Sun, J., Wang, D., & Li, X. A domain-assisted data driven model for thermal comfort prediction in buildings. In Proceedings of ACM e-Energy. 2018.

空調舒適度預測是樓宇智能歷史長河中重要的研究課題之一。目前的舒適度預估方法通常要求額外的傳感器或者用戶反饋等人工干預,這使得規模化本身成為難題。基於機器學習方法的空調舒適度預測已被證明可以減少額外的人工干預。但在不同邊緣場景下,樓宇製冷類型、安裝傳感器類別等因素會使得雲上單一通用模型出現嚴重錯誤。本研究提出了一種多任務的方法進行空調舒適度的預測,在精度上較機理模型和單任務模型分別提升39%和31%。

邊緣自適應任務定義

基於以上項目,讀者可以了解到基於多任務的邊緣智能算法、系統與應用。值得注意的是,在使用多任務之前,首先需要回答任務如何定義和劃分的問題,如確定在一個應用內不同項目所需機器學習模型的數量以及各個模型的應用範圍。該方法目前通常只能由數據科學家和領域專家人工進行干預,自動化程度低,難以規模化複製。因此,邊緣自動定義機器學習任務是一個懸而未決但又重要的難題。

為了在邊緣各種場景自適應地定義機器學習預測任務,華為雲邊緣雲創新Lab近日發表了研究論文《MELODY: Adaptive Task Definition of COP Prediction with Metadata for HVAC Control and Electricity Saving》。該研究提出了一種包含任務定義的多任務預測框架(MELODY),其中任務定義能夠自適應地定義並學習複數能效比預測任務。

MELODY是第一個根據各種邊緣場景自適應定義能效比預測任務的方法。本研究工作為尋求自動有效的邊緣機器學習方法的研究人員和應用開發人員提供了一種有吸引力的機制,特別適用於對於元數據多樣化但數據樣本不足的複雜系統。MELODY的關鍵思想是使用元數據動態劃分多個任務,論文提出了元數據的數學定義以及提取元數據的2種來源和方法。

該團隊在實際應用中評估該方案的性能:基於2個大型工業園區中的8座建築物中9台冷機進行4個月實驗。實驗結果表明,MELODY解決方案優於最新的能效比預測方法,並且能夠為兩個園區每月節省252 MWh的電量,較當前建築中冷水機的運行方式節省了35%以上的能源。

MELODY論文已獲ACM e-Energy 2020接收:

Zimu Zheng,Daqi Xie,Jie Pu,Feng Wang. MELODY: Adaptive Task Definition of COP Prediction with Metadata for HVAC Control and Electricity Saving. ACM e-Energy 2020. Australia.

ACM e-Energy 屬於ACM EIG-Energy Interest Group、計算機與能源交叉的旗艦會議。

1、論文接受率23.2%,歷年接受率在20%左右;

2、與CCF-A的Ubicomp; CCF-B的ECAI、TKDD H5-index相同;

3、55位評審程序委員會成員中包括Andrew A. Chien、Klara Nahrstedt、Prashant Shenoy等8位ACM/IEEE Fellow(約15%);

4、評審程序委員會成員來自IBM研究院、伊利諾伊大學香檳分校、劍橋大學、華盛頓大學、普渡大學、馬薩諸塞大學阿默斯特分校、西蒙菲沙大學、南洋理工大學、清華大學、香港理工大學等國際知名校企;

5、與CCF-A的STOC、ISCA、PLDI;CCF-B的IWQos、SIG Metric、COLT、HPDC、ICS、LCTES、SPAA等同屬ACM Federated Computing Research Conference (FCRC)系列的13個會議中,ACM FCRC頂會系列由Google、微軟、IBM、華為、arm、Xilinx等國際知名企業贊助。

能效比預測

基於冷機的暖通空調系統通常用於商業建築中,消耗的電力占建築物總用電量的40%至70%,這種消耗量主要由暖通空調系統的消耗量決定。商業建築物支付的電費(其中大部分歸於暖通空調系統)通常位於組織運營支出的前三名。這種趨勢給設施管理者帶來了巨大的壓力,他們需要通過減少與暖通空調系統相關的電力消耗來提高建築的能源利用效率。

暖通空調的主要消耗來自冷機(見圖4)。典型的冷機負荷控制的有效性在很大程度上取決於冷機運行時的性能,即在不同的冷負荷條件下的能效比。能效比是衡量冷機能效的指標,指的是在單位輸入功率消耗下的輸出冷量。能效比通常大於1,值越大,意味着效率越高。在實踐中,設施管理人員通常在冷機部署到建築物期間,在首次測試和調試冷水機組時衡量能效比的初始信息,並用該初始信息來執行冷機負荷控制。初始信息測試時通常將冷量負荷視為唯一參數。然而,這些初始信息無法捕獲實際參數的影響,並且已被近期研究證明是不精確的。

圖4 冷機示意圖

本研究以能效比預測問題作為個例研究。能效比高度依賴於多種因素,例如工況、冷量需求、設備老化、天氣等。為了在冷水機組中捕獲這些因素,現有工作已經提出採用數據驅動方法。能效比預測問題可以看做是在訓練階段學習一種被稱為模型的“公式”,該公式在推理階段能夠輸出具有給定特徵的能效比。

自適應任務定義

現有方法通常假定預測任務的配置,比如同一應用下的預測模型的數量和預測模型的應用範圍,是由數據科學家或領域專家定義和固定的。下文比較三種被廣泛接受的設定:單任務設定、多任務設定和專家輔助的多任務設定。

單任務設定

一個最典型的、被廣泛接受的預測任務配置方法是基於固定的單任務設定:這意味着將所有數據集作為一個整體合併在一起,並訓練單個預測模型。研究人員可以使用任何機器學習算法(例如SVM、神經網絡、Boosting等)來學習這種模型,並在任何場景下的推理階段都應用訓練出的這單個模型。

單任務設定假設對於同一應用下不同項目內不同的數據集,單個模型應足以描述所選特徵和能效比之間的關係。但是,這種假設可能並不總是成立。

比方說有兩個園區採用了兩種類型的冷水機:園區H使用了特靈CVHG1100冷水機和園區J使用了開利W3C100冷水機,那麼應根據冷水機的型號調整在特徵和能效比之間的熱力學模型。邊緣用戶往往也期待看到應用到兩個邊緣項目的模型有所不同:即使兩種冷水機輸入相同的水溫等特徵值,輸出的能效比也應不同。但如果將兩個數據集合併在一起並訓練同一個能效比模型,通常很難在沒有人工干預的情況下確保這一點。

論文作者過去的研究還表明,除了不同邊緣項目採用冷機型號不同可能導致模型不同外,可能導致模型不同的例子還包括:不同項目採用的工況和參數配置不同、不同項目採用的傳感器種類不同、不同季節採用特徵不同等(篇幅原因不再贅述,感興趣的讀者可以參考文章開頭提及的研究團隊歷史工作)。不同邊緣場景訓練出的模型應用範圍可能是迥乎不同的。所以對於不同的場景都採用單任務設定並非總是最佳選擇,這可能在實踐中引發重大錯誤,尤其是某些邊緣智能項目中訓練樣本的大小不足以在大量特徵中自動將場景彼此區分的情況。

多任務設定

但目前預測任務的配置,例如所需模型的數量以及模型的應用範圍,仍然是一個開放性問題。為了深入研究此問題,該團隊進一步驗證多任務設定而非單任務設定,也即觀察多個模型在多個測試集上的性能。在一個實際建築物中,使用了從冷機1到冷機5的訓練數據集訓練了5個模型(以下稱為M1 – M5)。然後在另外5個測試數據集(T1 – T5)的不同場景中測試了5個模型的性能。實驗及其結果分別如圖5-1、5-2所示。

圖5-1 複數冷機訓練模型在不同冷機測試集下的實驗示意圖

圖5-2 複數冷機訓練模型在不同冷機測試集下的預測準確率和樣本採集時間對比結果

觀察結果显示,

1)精度

儘管是基於不同的數據集進行訓練,但是冷機1的模型在冷機2和冷機3的測試集上效果很好,而在冷機4和冷機5的測試集上卻導致嚴重錯誤。對於冷機2到冷機5的模型可以看到類似的觀察結果。這是因為冷機1到冷機3來自同一種冷機型號,而冷機4和冷機5是另一種型號。

2)樣本採集時間

如果按冷機來劃分任務,每個冷機任務至少需要81天的樣本。但如果按照型號劃分為2個任務,每個型號任務僅需30天的樣本。這是因為每個型號任務包含多台冷機採集的數據。

根據上述精度和樣本採集時間的結果,與其考慮5個冷機從而定義5個冷機任務,在這個數據集下不如考慮2個型號(冷機1-3和冷機4-5)從而定義2個型號任務,在上述例子中可以降低63%左右的樣本採集時間,同時提升近10%的精度。

專家輔助的多任務設定

實際上,不僅冷機型號,隨時間變化的環境(例如,天氣條件)和工況(例如,供水溫度)也可以導致能效比模型的變化。藉助領域專家的知識,可以在構建的環境中定義固定的任務,並將這些固定的任務應用於不同的建築中。

例如,基於建築環境研究中的領域專業知識,該團隊最近一項工作在三座建築物中根據工況給出了固定的50個任務,用於多任務冷機能效比預測;該團隊最近另外一項工作根據季節和製冷類型在160座建築物中給出了固定的4個任務,以進行多任務熱舒適性預測。

但是,所需模型的數量及其應用範圍可以根據不同的邊緣項目場景而變化,而領域專家的配置很難跟隨不同邊緣項目動態擴展。例如,在一個建築物的少量數據集中,最好有3個任務,即訓練3種不同的模型進行能效比預測。但是在另一個包含1000座建築物的大型數據集中,最好有75個任務。在邊緣場景手動定義要預測的機器學習任務通常會導致成本過高或準確性降低,尤其是當任務隨項目和時間而動態變化時。因此,有必要針對不同場景自適應地定義任務。

MELODY

本研究工作旨在解決自適應任務定義問題,也即不同場景下自動化定義不同的任務,例如,在不同場景中確定需要使用的模型數量以及模型的應用範圍等。該團隊遇到三個主要挑戰,並提出了使用自適應任務定義方法的多任務預測框架(MELODY)。

挑戰1:當前項目的目標未知,而且通常更糟糕的是,可能的任務候選集也未知。

MELODY通過提出任務挖掘解決了第一個挑戰。它基於諸如任務森林等新穎結構和算法來自適應地定義任務,參見圖6。這使得MELODY可規模化到眾多建築和環境的能效比預測。

圖6 任務森林的例子:數據表示模型訓練樣本,屬性表示模型應用範圍;節點表示子任務,包括數據、屬性和模型(若有);森林的每個根節點,也即每棵樹的頂點,表示各個子任務合併成的一個任務。對任務森林初始化和維護等具體實現和算法複雜度等證明,有興趣的讀者可以閱讀論文附錄。

挑戰2:標誌能效比模型應用範圍的屬性未知,同時此類屬性的來源也在研究中。

MELODY通過使用元數據作為任務屬性的來源來解決第二個挑戰。

元數據由領域專家定義,用於建築管理系統的日常控制。例如,傳感器的名稱和建築物的類型是元數據。在MELODY框架中,該團隊提出了從數據庫的兩個來源中提取兩種元數據的方法。

元數據包含潛在領域信息,藉助這些信息,能夠自適應地提取具有領域知識的任務,併為自動和強大的任務定義打開了方便之門,如圖7所示。

圖7 基於元數據提取的任務定義(具體實現請參見論文)

挑戰3:任務組合數量隨屬性數量指數增長;因此,冷機樣本不足以為所有組合訓練模型。

MELODY通過利用多任務遷移學習克服了第三個挑戰。在多任務優化中,學習任務可以使用來自其他不同任務的知識,從而減少數據量的需求。

多任務評估

本研究工作通過將其應用於實際數據來評估方案的性能,在2個大型工業園區中的8座建築物中9台冷機進行4個月時間的實驗。園區情況可參見圖8。

圖8 2個大型工業園區中的8座建築物及其冷機信息

表1 任務定義輸出結果

表1显示了通過任務定義算法挖掘出的任務的總體信息,在Park J和Park H中發現了兩組不同的任務集合。觀察显示不同項目模型的數量和使用模型時的場景都不同。藉助五分鐘的間隔數據,可以在Park J中挖掘出33個任務,這些任務模型的應用範圍主要根據冷機額定功率和平均濕度的來判斷。藉助一小時的時間間隔數據,Park H中僅有2個任務,應用範圍需要通過額定功率和額定製冷量來判斷。可以發現每個任務中的樣本量很小。 對於總共35個任務,有13個任務的樣本數少於100,其餘22個任務的樣本數少於1000。

研究比較了幾種應用於冷機能效預測的典型方法:

(1)工業界當前方法:初始配置文件(IP)利用安裝時測量的初始配置文件來估算未來的能效比,是目前工業界正在使用的方法。

(2)學術界常用方法:單任務學習(STL)通過將來自每個數據集的所有任務的數據匯總在一起來學習一個模型;

(3)近期研究工作:關於數據源的獨立多任務學習(IMTL),它獨立於數據源學習每個任務。例如,針對9個冷機固定9個任務,而無需在任務之間共享任何樣本或知識;

(4)近期研究工作:具有領域知識的多任務學習(MTL),它學習具有由領域知識定義的任務聚類。例如,固定的50個任務,其中10個負載比和5個冷機。

表2 各方法錯誤率提升

表2結果显示,MELODY的任務定義可以比STL(單任務方法)有所提升。 但是,不正確的任務定義(即IMTL和MTL)對比單任務方法未能有所提升。這主要是因為與在不同數據集中(如MELODY)使用自適應任務的方法相比,IMTL和MTL在劃分任務後會生成較小的數據集,這導致部分任務內缺乏訓練樣本。當任務數量隨着屬性數目和時間推移而增加時,效果變得更差,因為任務遷移關係變得越來越複雜。在這種情況下,任務之間共享知識變得更具挑戰性,並容易導致一種被稱為負遷移的影響,也即從不相關的源域到目標域共享知識而導致的錯誤。可以看到,MELODY能解決相關問題,從而使得結果優於最新的能效比預測方法,將能效比預測誤差率降低了18.18-61.70%,最終能夠在兩個園區上每月節省252 MWh的電量,與當前建築中冷水機的運行方式相比節省了36.75%以上的能源。

本文作者:鄭博士,華為雲邊緣雲創新Lab高級研究工程師,畢業於香港理工大學,主要研究方向是邊緣智能及AIoT。發表國際相關領域頂級會議及期刊 (TPDS、 IJCAI、 ICDCS、CIKM、TOSN、TIST等) 論文十餘篇,多次獲得最佳會議論文獎項,多次獲得關鍵技術突破、高價值專利和新服務孵化等華為傑出貢獻獎項。

華為雲邊緣雲創新Lab:願景是探索端邊雲協同關鍵技術,構建無所不在的、極致體驗的智能邊緣雲。聯合工業夥伴和學術機構,共同致力於研究邊緣雲創新技術、孵化邊緣雲創新應用、構建邊緣雲繁榮生態。研究方向包括大規模智能邊緣雲平台、邊雲協同AI、端邊雲協同渲染與視頻加速。目前已孵化上線華為邊緣計算平台IEF,並貢獻首個基於Kubernetes的雲原生邊緣計算平台KubeEdge,獲尖峰開源技術創新獎、最佳智能邊緣計算技術創新平台等多項獎項;孵化的業內首個邊雲協同增量學習工作流即將上線華為雲HiLens服務、IEF服務;學術上近2年已發表7篇邊雲協同AI、雲原生邊緣計算相關頂會論文,獲多項最佳論文和優秀論文獎項。

 

點擊關注,第一時間了解華為雲新鮮技術~

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

【其他文章推薦】

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

新北清潔公司,居家、辦公、裝潢細清專業服務

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

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

※超省錢租車方案

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

Jmeter系列(26)- 詳解 JSON 提取器

如果你想從頭學習Jmeter,可以看看這個系列的文章哦

https://www.cnblogs.com/poloyy/category/1746599.html

 

為什麼要用 JSON 提取器

  • JSON 是目前大多數接口響應內容的數據格式
  • 在接口測試中,不同接口之間可能會有數據依賴,在 Jmeter 中可以通過後置處理器來提取接口的響應內容
  • JSON 提取器是其中一個可以用來提取響應內容的元件

 

JSON 提取器的應用場景

  1. 提取某個特定的值
  2. 提取多個值
  3. 按條件取值
  4. 提取值組成的列表

 

JSON 提取器

我們通過實際栗子去講述理論知識點

 

JSON 提取器界面介紹

 

字段含義

 

字段 結果
Apply to 應用範圍,選默認的 main sample only 就行了
Names of created variables
  • 接收提取值的變量名
  • 多個變量用 ; 分隔
  • 必傳
JSON Path expression
  • json path 表達式,用來提取某個值
  • 多個表達式用 ; 分隔
  • 必傳
Match No.(0 for Random)
  • 取第幾個值,多個值用 ; 分隔
  • 0:隨機,默認
  • -1:所有
  • 1:第一個值
  • 非必傳
Compute concatenation var(suffix_ALL)
  • 如果匹配到多個值,則將它們都連接起來,不同值之間用 , 分隔
  • 變量會自動命名為 <variable name>_ALL 
Default Values
  • 缺省值,匹配不到值的時候取該值,可寫error
  • 多個值用 ; 分隔
  • 非必傳

 

入門栗子 

栗子的前提

這個栗子,我都會以這個地址的接口來完成 JSON 提取器的實戰慄子,大家可以註冊個賬號玩一玩哦

http://api.yesapi.cn/docs.php?keyword=%E4%BC%9A%E5%91%98&channel=api

 

測試計劃樹結構

下面多個栗子都以這個測試計劃為基礎哦

 

提取某個特定的值的栗子

登錄接口響應

登錄是執行其他接口的前置接口,所以要獲取用戶登錄后的 token、uuid

 

提取 token

相對路徑的方式

 

提取 uuid

絕對路徑的方式

 

其他接口調用 token、uuid

 

知識點

  • 提取某個特定值的方式有兩種:絕對路徑、相對路徑
  • 提其他接口可以通過 ${var} 這種格式,來獲取提取到的值

 

綜合栗子

  • 上面講的是使用 JSON 提取器時的一個流程
  • 在實際項目中,接口的響應內容肯定是非常複雜的,而我們需要提取的值也是多樣化的,需要通過各種實戰慄子來講述清晰

 

JSON 字符串

這也是某個接口返回的響應內容,後面的栗子也是以這個 JSON 字符串為基礎來提取各種值

感興趣也可以自己玩一玩:http://api.yesapi.cn/docs-api-App.User.GetList.html

{
    "ret": 200,
    "msg": "V2.5.1 YesApi App.User.GetList",
    "data": {
        "total": 3,
        "err_msg": "",
        "err_code": 0,
        "users": [
            {
                "role": "user",
                "status_desc": "正常",
                "reg_time": "2020-06-22 15:19:51",
                "role_desc": "普通會員",
                "ext_info": {
                    "yesapi_nickname": "",
                    "yesapi_points": 0
                },
                "uuid": "6D5EDCB459F0917A98106E07D5438C58",
                "username": "fangjieyaossb",
                "status": 0
            },
            {
                "role": "user",
                "status_desc": "正常",
                "reg_time": "2020-06-22 14:27:17",
                "role_desc": "普通會員",
                "ext_info": {
                    "yesapi_nickname": "",
                    "yesapi_points": 0
                },
                "uuid": "0164DC0680F84DCE40D3DD4A36640ECA",
                "username": "fangjieyaossa",
                "status": 0
            },
            {
                "role": "admin",
                "status_desc": "正常",
                "reg_time": "2020-03-23 22:48:32",
                "role_desc": "管理員",
                "ext_info": {
                    "yesapi_nickname": "",
                    "yesapi_points": 0
                },
                "uuid": "079BF6BB82AFCFC7084F96AECAF0519F",
                "username": "fangjieyaoss",
                "status": 0
            }
        ]
    }
}

 

提取單個值

Jsonpath 結果
$.data.total 2
$..total 2
$..users[0].role user
$..uuid 079BF6BB82AFCFC7084F96AECAF0519F
$.data.users[0].ext_info.yesapi_points 0

 

重點

  • 如果匹配到多個值(像 $..uuid ),也只能提取到一個值
  • 如果想提取匹配到的所有 uuid,可以設置為 -1,結果如下圖

還會告訴你匹配了多少個值 ${uuid_matchNr} ,記住,調用變量時,不再是 ${uuid} 而是 ${uuid_1} 、 ${uuid_2} 

 

利用切片提取單個值

和 Python  切片一樣的原理

Jsonpath 結果
$..users[2] 第三個 users
$..users[-2] 倒數第二個users
$..users[0,1] 前面兩個users
$..users[:2] 第一、二個users
$..users[1:2] 第二個users
$..users[-2:] 倒數兩個users
$..users[1:] 第二個開始的所有users

 

提取多個值

  • 四種寫法類似,選一種方法自己熟記即可
  • 重點:提取多個值,提取器的 Match No. 必須填 -1

 

$.data.users[*].role

提取所有 role 字段值

[*] 表示取數組的所有元素

 

$..users..role_desc

提取所有 role_desc 字段值

 

$..reg_time

提取所有 reg_time 字段值

 

$..[*].username

提取所有 username 字段值

 

按條件提取值

有時候只需要提取某個特定條件下的參數值

 

語法格式

[?(expression)]

 

栗子

Jsonpath 結果
$..users[?(@.uuid)] 提取 users 裡面包含 uuid 字段的記錄
$..users[?(@.reg_time > ‘2020-06-01’)] 提取 reg_time 字段大於 2020-06-01 的記錄
$..users[?(@.role_desc =~ /.*會員.*?/i)] 提取 role_desc 字段包含會員的記錄
$..users[?(@.status == 0)] 提取 status 字段等於 0 的記錄

 

@

代表當前節點,像上面的四個栗子,@代表 users 這個列表字段

 

=~

  • 後面跟正則表達式,如果想提取包含指定字符的值,可以使用此正則: /.*指定字符串.*?/i 
  •  i  代表大小寫不敏感

 

提取數據指定字段的值的栗子

提取 users 第一條記錄的 uuid、username 字段的值

$..users[0].['uuid','username']

 

測試結果

new_1={"uuid":"6D5EDCB459F0917A98106E07D5438C58","username":"luojunjiessb"}

 

勾選 Compute concatenation var 的栗子

JSON 提取器

 

測試結果

uuid_1=6D5EDCB459F0917A98106E07D5438C58
uuid_2=0164DC0680F84DCE40D3DD4A36640ECA
uuid_3=079BF6BB82AFCFC7084F96AECAF0519F
uuid_ALL=6D5EDCB459F0917A98106E07D5438C58,0164DC0680F84DCE40D3DD4A36640ECA,079BF6BB82AFCFC7084F96AECAF0519F
uuid_matchNr=3

 

一個 JSON 提取器有多個 Jsonpath 的栗子

JSON 提取器

 

測試結果

uuid1_1=6D5EDCB459F0917A98106E07D5438C58
uuid1_2=0164DC0680F84DCE40D3DD4A36640ECA
uuid1_3=079BF6BB82AFCFC7084F96AECAF0519F
uuid1_matchNr=3
uuid2_1=6D5EDCB459F0917A98106E07D5438C58
uuid2_2=0164DC0680F84DCE40D3DD4A36640ECA
uuid2_3=079BF6BB82AFCFC7084F96AECAF0519F
uuid2_matchNr=3

 

知識點

  • 如果有多個 Jsonpath 的時候,每個字段都必填值,且字段值的數量要一致(像上圖,每個字段都填了兩個值)
  • 勾不勾 Compute concatenation var 都行
  • 字段值數量不一致則無法提取值

 

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

【其他文章推薦】

新北清潔公司,居家、辦公、裝潢細清專業服務

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

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

※超省錢租車方案

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

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

Flutter學習筆記(36)–常用內置動畫,Flutter學習筆記(36)–常用內置動畫

如需轉載,請註明出處:Flutter學習筆記(36)–常用內置動畫

Flutter給我們提供了很多而且很好用的內置動畫,這些動畫僅僅需要簡單的幾行代碼就可以實現一些不錯的效果,Flutter的動畫分為補間動畫和基於物理的動畫,基於物理的動畫我們先不說。

補間動畫很簡單,Android裏面也有補間動畫,就是給UI設置初始的狀態和結束狀態,經過我們定義的一段時間,系統去幫助我們實現開始到結束的過渡變化,這就是補間動畫。

今天我們要看的Flutter的內置動畫就是補間動畫,根據Flutter提供的動畫組件,我們去設置初始、結尾的狀態,並且定義一下這個變化過程所需要的時間,再經過系統的處理(其實就是setState())來達到動畫的效果。

接下來我們會寫一下常用的內置動畫組件,並且提供一下動畫效果的gif,方便大家更直觀的去理解。

  • AnimatedContainer

看到Container我們就會知道這是一個帶有動畫屬性的容器組件,這個組件可以定義大小、顏色等屬性,那麼我們是不是就可以給這個組件設置初始和結束的大小及顏色的屬性值,然後通過系統來幫助我們來補足中間過程的動畫呢?

答案是可以的,下面看一下demo和動畫效果:

class _MyHomePageState extends State<MyHomePage> {
  double _width = 100.0;
  double _height = 100.0;
  Color _color = Colors.red;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: AnimatedContainer(
        width: _width,
        height: _height,
        duration: Duration(seconds: 2),
        color: _color,
        curve: Curves.bounceInOut,
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            _width = 300.0;
            _height = 300.0;
            _color = Colors.green;
          });
        },
        tooltip: 'Increment',
        child: Icon(Icons.adjust),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

 

demo很簡單,就是先定義好組件初始的大小和顏色,點擊按鈕,在按鈕事件裏面去更改大小和顏色的屬性值。這裏唯一需要特別說一下就是curve這個屬性。

curve指的是動畫曲線?我開始的時候不理解這個動畫曲線是什麼意思,後來看了一組圖之後,豁然開朗。demo裏面curve我們用的是Curves.bounceInOut。如下:

 

它其實就是一個非線性的動畫的變化形式(變化過程)也可以理解為就是一種函數,也不知道這麼說大家能不能理解。

/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_bounce_in.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_bounce_in_out.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_bounce_out.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_decelerate.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_sine.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_quad.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_cubic.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_quart.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_quint.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_expo.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_circ.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_back.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_sine.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_quad.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_cubic.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_quart.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_quint.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_expo.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_circ.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_back.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_sine.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_quad.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_cubic.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_quart.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_quint.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_expo.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_circ.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_back.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_elastic_in.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_elastic_in_out.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_elastic_out.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_fast_out_slow_in.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_slow_middle.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_linear.mp4}

 

這裡是每一種curve曲線的表現形式,大家可以看看,也可以在demo裏面多嘗試,或者可以看另一篇博客,有動畫曲線Curves 效果。

  • AnimatedCrossFade

Flutter中文網:一個widget,在兩個孩子之間交叉淡入,並同時調整他們的尺寸。

個人說明:CrossFade,故名思意,淡入淡出,AnimatedCrossFade組件包含兩個子widget,一個firstChild一個secondChild,這兩個組件根據狀態(我們自己定義的一個標識)改變狀態,

一個淡入,一個淡出,同時改變大小或顏色等屬性。

class _MyHomePageState extends State<MyHomePage> {
  bool _showFirst = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: AnimatedCrossFade(
        firstChild: Container(
          width: 100,
          height: 100,
          color: Colors.red,
          alignment: Alignment.center,
          child: Text('firstChild'),
        ),
        secondChild: Container(
          width: 200,
          height: 200,
          color: Colors.green,
          alignment: Alignment.center,
          child: Text('secondChild'),
        ),
        duration: Duration(seconds: 3),
        crossFadeState:
            _showFirst ? CrossFadeState.showFirst : CrossFadeState.showSecond,
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            _showFirst = false;
          });
        },
        tooltip: 'Increment',
        child: Icon(Icons.adjust),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

 

  • Hero

Hero常用於頁面跳轉的過長動畫,比如電商App有一個商品列表,列表的每個item都有一張縮略圖,點擊會跳轉到詳情頁面,在Flutter中將圖片從一個路由飛到另一個路由稱為hero動畫,儘管相同的動作有時也稱為 共享元素轉換

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Hero(
        tag: 'heroTag',
        child: ClipOval(
          child: Image.asset(
            'images/banner.png',
            width: 60,
            height: 60,
            fit: BoxFit.cover,
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            Navigator.push(context, MaterialPageRoute(builder: (_) {
              return new HeroPage();
            }));
          });
        },
        tooltip: 'Increment',
        child: Icon(Icons.adjust),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

 

詳情頁面:

import 'package:flutter/material.dart';

class HeroPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'HeroPage',
      home: Scaffold(
        appBar: AppBar(
          title: Text('HeroPage'),
        ),
        body: Center(
          child: GestureDetector(
            child: Hero(
              tag: 'heroTag',
              child: ClipOval(
                child: Image.asset(
                  'images/banner.png',
                  width: 300,
                  height: 300,
                  fit: BoxFit.cover,
                ),
              ),
            ),
            onTap: () {
              Navigator.pop(context);
            },
          ),
        ),
      ),
    );
  }
}

 

注:特彆強調一下,為了將兩個頁面的元素關聯起來,hero有個tag標識,前後兩個頁面的tag標識必須一樣,不然的話元素是關聯不起來的,也就意味着不會產生hero動畫。

1.同級tag不允許相同。

2.前後頁面想要有hero動畫,tag必須相同。

3.前後關聯起來的hero組件,其各自內部的child組件不是必須一樣的,就是說前面的hero的子組件可以是image,後面的hero的子組件可以是image以外的其他組件。

  • AnimatedBuilder

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  Animation<double> _animation;
  AnimationController _animationController;

  @override
  void initState() {
    _animationController =
        AnimationController(duration: Duration(seconds: 3), vsync: this);
    _animation =
        new Tween(begin: 0.0, end: 200.0).animate(_animationController);
    _animationController.forward();
    super.initState();
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: AnimatedBuilder(
          animation: _animation,
          builder: (BuildContext context, Widget child) {
            return Center(
              child: Container(
                color: Colors.red,
                width: _animation.value,
                height: _animation.value,
                child: child,
              ),
            );
          },
        ));
  }
}

AnimationController:動畫控制器(定義動畫過程時長)。

Animation:動畫變化區間值(也可以說是開始和結束的關鍵幀值),demo里定義的值為初始0,結束200。

_animation.value:關鍵幀值是0和200,_animation.value的值為0–200之間連續變化的值(0-1-2-3-…-198-199-200)。

  • DecoratedBoxTransition

Decortated可以給容器添加各種外觀裝飾,比如增加圓角、陰影等裝飾。DecoratedBox的動畫版本,可以給它的Decoration不同屬性使用動畫

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  Animation<Decoration> _animation;
  AnimationController _animationController;

  @override
  void initState() {
    _animationController =
        AnimationController(duration: Duration(seconds: 3), vsync: this);
    _animation = DecorationTween(
            begin: BoxDecoration(
                borderRadius: BorderRadius.all(Radius.circular(0.0)),
                color: Colors.red),
            end: BoxDecoration(
                borderRadius: BorderRadius.all(Radius.circular(30.0)),
                color: Colors.green))
        .animate(_animationController);
    _animationController.forward();
    super.initState();
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(widget.title)),
      body: Center(
        child: DecoratedBoxTransition(
          decoration: _animation,
          child: Container(
            width: 100,
            height: 100,
          ),
        ),
      ),
    );
  }
}

  • FadeTransition

透明度變化動畫,因為透明度也是在0-1之間變化的,所以animation就還繼續用double類型的就可以了。

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  Animation<double> _animation;
  AnimationController _animationController;

  @override
  void initState() {
    _animationController =
        AnimationController(duration: Duration(seconds: 2), vsync: this);
    _animation = Tween(begin: 1.0, end: 0.0).animate(_animationController);
    _animationController.forward();
    super.initState();
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(widget.title)),
      body: Center(
        child: FadeTransition(
          opacity: _animation,
          child: Container(
            width: 100,
            height: 100,
            decoration: BoxDecoration(
              color: Colors.red,
            ),
          ),
        ),
      ),
    );
  }
}

  • RotationTransition

旋轉動畫,對widget使用旋轉動畫 1~360°(Tween(begin: 0.0, end: 1.0))這裏的0-1指的是0°-360°

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  Animation<double> _animation;
  AnimationController _animationController;

  @override
  void initState() {
    _animationController =
        AnimationController(duration: Duration(seconds: 2), vsync: this);
    _animation = Tween(begin: 0.0, end: 1.0).animate(_animationController);
    _animationController.forward();
    super.initState();
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(widget.title)),
      body: Center(
        child: RotationTransition(
          turns: _animation,
          child: Container(
            width: 100,
            height: 100,
            decoration: BoxDecoration(
              color: Colors.red,
            ),
            child: Center(child: Text('data')),
          ),
        ),
      ),
    );
  }
}

  • ScaleTransition

縮放動畫,Tween(begin: 1.0, end: 0.2)指的是原大小的倍數,demo里是由原大小縮小到原來的0.2倍。

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  Animation<double> _animation;
  AnimationController _animationController;

  @override
  void initState() {
    _animationController =
        AnimationController(duration: Duration(seconds: 2), vsync: this);
    _animation = Tween(begin: 1.0, end: 0.2).animate(_animationController);
    _animationController.forward();
    super.initState();
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(widget.title)),
      body: Center(
        child: ScaleTransition(
          scale: _animation,
          child: Container(
            width: 200,
            height: 200,
            decoration: BoxDecoration(
              color: Colors.red,
            ),
            child: Center(child: Text('data')),
          ),
        ),
      ),
    );
  }
}

  • SizeTransition

僅一個方向進行縮放

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  Animation<double> _animation;
  AnimationController _animationController;

  @override
  void initState() {
    _animationController =
        AnimationController(duration: Duration(seconds: 2), vsync: this);
    _animation = Tween(begin: 1.0, end: 0.2).animate(_animationController);
    _animationController.forward();
    super.initState();
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(widget.title)),
      body: Center(
        child: SizeTransition(
          axis: Axis.horizontal,
          sizeFactor: _animation,
          child: Center(
            child: Container(
              width: 200,
              height: 200,
              decoration: BoxDecoration(
                color: Colors.red,
              ),
              child: Center(child: Text('data')),
            ),
          ),
        ),
      ),
    );
  }
}

 

以上!有任何疑問歡迎留言!

 

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

【其他文章推薦】

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

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

※回頭車貨運收費標準

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

※超省錢租車方案

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

JVM 總結

JVM GC 總結。

周志明大大的《深入理解Java虛擬機》出第三版了,早早的買了這本書,卻一直沒有花時間看。近來抽空溫習了一下,感覺又有了新的收穫。這裏簡單總結下。

GC的由來

由於的動態性,操作系統將堆交由給了開發者自己管理,手動申請,手動釋放。對於C++,則是將這個權限繼續交給了開發者,而對於Java,則是將這個過程自動化了。為什麼要釋放內存呢?最簡單的原因就是操作系統一共給你了4G的內存空間,你需要的時候,就去借用。有借有還,再借不難,只借不還,最後4G內存空間被用完了,你就無法再申請新的內存了。內存泄漏,就是只借不還。

JVM在操作系統與開發者之間又封裝了一層,間接的接管了內存的劃分。同時也將堆統一管理起來,使得開發者只管借用內存,由JVM負責回收,了解JVM的回收機制,明白它的原理,能讓開發者在不同的場景下,定製不同的回收規則,提高回收效率。

關於GC的思考

如果讓我設計一個能自動回收垃圾的虛擬機,我會怎麼設計呢?

  • 什麼時候開始回收?
  • 怎麼判斷這部分內存可以回收?
  • 怎麼回收這部分的垃圾?

這3個問題,也是JVM開發者一直在思考的問題。之前簡單了解過JVM,就知道JVM會有Stop The World的問題,這對於用戶體驗來說非常不好,其根本原因便是因為在回收垃圾的時候,用戶線程可能會修改這部分內存,如果不暫停用戶線程,則可能會導致嚴重的問題,而如何減少Stop The World的時候,甚至讓其消失,是各個垃圾回收器一直追求的目標。

哪些內存可以回收?

對於一個對象來說,當不存在任何一個引用能夠訪問到這個對象的時候,則說明這個對象可以進行回收。因為沒有任何引用指向這個對象,那麼這個對象就不能被讀或寫。

  • 引用計數法

    前面說判斷一個對象可以被回收的標準就是是否還有引用指向這個對象,所以最容易想到的便是引用計數法,通過判斷一個對象的引用數量即可,可是這樣無法判斷兩個循環引用的對象。

  • 可達性分析

    可達性分析指的是從目前程序中正在使用的所有引用的對象出發,循環遍歷所有能找到的對象。

    作為出發的點的這些對象,被稱為GC Roots

    GC Roots主要包括以下幾種:

    • 在虛擬機棧(比如棧幀中的本地遍歷表)中引用的對象
    • 靜態屬性引用的對象
    • 常量池引用對象(比如
      String Table
    • 本地方法棧引用的對象
    • Java虛擬機內部的引用對應的對象
    • 所有被同步鎖持有的對象

    總體來說,就是當前程序中正在被使用的引用所指向的對象會被作為GC Roots

GC Roots出發,依次查找,就能標記出當前存活的對象。但是標記這個過程,細節上依然存在問題:

  • STW : 標記是通過引用查找對象的,如果在標記過程中,用戶修改了引用的對象,那麼會導致不可預估的後果,因此一般標記過程中,是會STW

  • 跨代標記 : 現在的垃圾回收器,大多數都是分代,或者分區域回收的,也就是說,可能進行垃圾回收的時候,不是標記所有的垃圾,而是標記一部分,比如老年代或者新生代。此時就存在一個問題,跨代引用。比如一個新生代的對象,僅僅被一個老年代對象引用的話,對於Yong GC來說,是不會掃描老年代對象的,這個時候就會造成誤判。解決這個誤判的方法便是記憶集(Remembered Set),記憶集通過AOP技術生成寫屏障來維護。

    前面說了從GC Roots開始掃面,那分代收集的,怎麼知道哪些對象是新生代的,哪些對象是老年代的呢?因為GC Roots是包含了所有引用的。後面想想,其實對象的分代信息是存放在對象頭裡面的。在掃描GC Roots的時候,只保留新生代的對象即可。這樣基本能保證掃描到的是新生代對象,然後老年代對新生代引用交給記憶集實現就行(自己的猜測,沒有證據)

    JVM書中說道通過AOP生成的寫屏障會使得只要有更新操作,無論更新的是不是老年代對新生代對象的引用,都會使卡表變髒,不過這樣的代價相對來說是能接受的。

  • GC Roots 需要掃描的引用過多 :隨着現在Java應用越做越大,Java堆也越來越大,GC Roots的掃描是需要STW的,如果每次GC都逐個掃描,會非常的浪費時間。解決這個問題的辦法就是OopMap,使用OopMap記錄應用程序所存放的引用,每次需要GC的時候掃描這個OopMap即可生成對應的GC RootsOopMap通過安全點和安全區域來維護,只有在安全點或安全區域的時候,才更新OopMap和進行垃圾回收。

  • 併發標記過程可能丟失存活的對象 :從CMSG1,都將從GC Roots出發標記存活對象的過程修改成併發的,這樣會需要解決的問題就是標記過程中如果用戶修改了對象的引用,可能會導致本應該存活的對象”丟失“(可以通過三色標記分析),相應的解決方案便是破壞存活對象消失的必要條件,分別是增量更新(Incremental Upate)和原始快照(Snapshot At The Begin,SATB),增量更新破壞的是第一個條件,每插入一個引用,就都記錄下來,而原始快照破壞的是第二個條件,每刪除一個,都將其記錄下來。

    增量更新和併發快照也是通過前面所說的AOP技術生成寫屏障來維護

通過以上分析以及解決方案,基本明白了怎麼標記那些內存可以回收,接下來需要分析的就是什麼時候開始回收

什麼時候開始內存回收?

對於內存回收來說,開始也需要有一定的講究,理論上來說,隨時隨地都可以開始內存回收,但是如果回收時使用的內存過多,會導致GC時間過程,進而STW時間也會很長,如果回收過於頻繁,又會導致吞吐量下降,畢竟每次掃描GC Roots都回STW的。

同時,前面還說過,對於用戶線程來說,需要將用戶線程運行到安全點,更新對應的OopMap,才能開始垃圾回收。

因此,對應何時GC,有以下幾點分析:

  • 對於新生代來說,一般新生代滿了(Eden + Survivor1)就會開始進行(Yong/Minor GC

  • 對於老年代來說,一般是老年代滿了了會開始Full/Major GC

    注意:這裏的滿了,需要根據具體的回收器不同,來衡量真正的滿,對於沒有併發過程的GC,老年代滿一般指的是真正到達100%,已經無法分配內存了,對於有併發過程的GC,則需要預留出來空間給用戶線程在併發過程中同時申請內存,如果預留內存過小,則會使用非併發垃圾回收器進行Full GC

    CMS: -XX:CMSInitiatingOccupancyFraction 設置,默認92% (JDK 8),表示當老年代垃圾佔用到92%就開始老年代回收, JDK 9后便無法使用CMS

    G1: -XX:G1ReservePercent設置,默認為10,表示當整個Java堆使用到達90%,就開始回收。同時配合的參數還有-XX:InitiatingHeapOccupancyPercent=n,默認值為45,表示使用率到達45%就啟動標記周期。這裏的GCMixed GC

    一般來說,只有CMS才有Major GC,其他老年代GC都會回收整個Java堆,也稱為Full GC

  • 統計得到的Minor GC晉陞到老年代的平均大小大於老年代剩餘的空間。(JDK 6 之後已經刪除了擔保規則)

  • GC併發失敗(concurrent mode failure): 情況如前面說的,併發標記過程中,又出現了新生代晉陞的情況,但是此時老年代剩下的內存不足夠放下晉陞的對象的時候,會生導致Full GC

    這裏的Full GC和情況1中說到達預留空間的GC不一樣,情況1是正常進行的GC,而這個併發失敗卻是GC過程中出現了異常,一般需要切換到非併發GC,此時性能會大大下降

  • 方法區區域被使用完畢:JDK 8之後將方法區從Perm Gen替換成了元空間,一般來說元空間大小理論上等於本地內存大小,不過元空間有一個默認初始值,到達默認初始值后,會通過Full GC擴大

    注意:G1只有Yong GCMixed GC。沒有Full GC的概念,也就是說如果需要回收方法區的話,只能退化為Serial GC進行Full GC

    CMS可以通過-XX:+CMSClassUnloadingEnabled設置併發回收方法區

  • 最大連續空間裝不下大對象:對於CMS,基於標記-清除算法來說,即使空間足夠,但是由於內存碎片,裝不下分配的大對象時,會進行一次Full GC,對於G1來說,當分配巨型對象的時候,如果在老年代無法找到連續的Humongous的時候,會進行Full GC

  • 用戶執行System.gc(),可以通過-XX:+DisableExplicitGC屏蔽

怎麼回收這些內存

最後一步便是怎麼回收這些內存。怎麼回收,書中介紹不多,總體來說有以下三種:

  • 標記-清除(
    Mark-Sweep):最原始的方法,實現簡單,不用移動對象,很容易做到不用
    Stop The Word,但是缺點也很致命,容易產生內存碎片。標記清除的速度一般,
    Mark階段與活對象的數量成正比,
    Sweep階段與整堆大小成正比。目前只有
    CMS使用這種回收方案
  • 標記-複製(
    Mark-Copying):基於標記-清除修改的垃圾回收算法,需要移動對象。 前期標記,然後複製活下來的對象到另一個區域,再總體回收整塊區域。標記複製算法對於新生代這種專門放朝生夕死的對象效率非常高,因為存活下來的對象少,所以
    Mark階段和
    Copying階段花費的時間都會比較少,幾乎所有的分代
    GC新生代都是使用的這種算法
  • 標記-整理(
    Mark-Compact): 基於標記-清除算法修改的垃圾回收器,需要移動對象。前期標記,然後將所有對象移動到一起,再對剩餘的區域進行回收,速度最慢,但是不會產生內存碎片。

對於新生代使用標記-複製算法,是毋庸置疑的。但是對於老年代,使用標記清除還是標記整理,需要有一定的考量。因為使用標記-清除,不用移動對象,速度會相對來說比較快,但是由於存在內存碎片,無法使用指針碰撞的方式分配內存,而不得不使用“分區空閑分配鏈表”來解決內存分配的問題,這樣會對在內存分配帶來一定的效率影響,而標記-整理算法需要移動對象,特別是對於老年代這種大對象來說,移動這些對象將是一種極為負重的操作,但是標記-整理不會產生內存碎片。

因此,基於以上考慮,對於CMS這種側重響應速度,致力於減少STW時間的回收器來說,選擇了標記-清除算法,但是由於內存分配是一個非常頻繁的操作,使用”分區空閑分配鏈表”會降低整個垃圾回收器的吞吐量,因此,對於Parllel Scavenge這種注重回收吞吐的垃圾回收器來說,選擇了標記-整理算法。當然,對於G1則是吞吐和響應速度都比較注重,權衡之下,選擇了標記-整理(全局)算法。

GC的概念,到這裏基本總結完畢,但是,如果僅僅是理論,只是讓我們記着一些概念性的東西,接下來,我會結合CMSG1GC日誌以及《深入理解JVM》第四章的內容,聊一聊如何分析以及查看GC過程,簡單介紹如果進行GC調優。

個人公眾號:

不定期更新一些經典Java書籍總結。

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

【其他文章推薦】

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

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

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

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

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

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

保護復活島生態文化 智利限遊客停留最多30日

摘錄自2018年7月30日自由時報報導

智利國會今年3月立法,強化旅客登復活島規範,並限制外來人口數量,限令於8月1日正式生效。

法新社報導,根據新法令,外籍人士或非當地原住民的智利人,在島上停留的期限從原本的90天降至30天,僅原住民拉帕努伊人(Rapa Nui)的直系血親,才可在島上長期居住。此外,公務員、政府相關組織人士,以及在當地從事獨立經濟活動者和家人,也獲准在島上居住。觀光客則須在抵達時,出示飯店預約證明或當地人的邀請函,日後也將訂定島上最高人數限制。

去年的人口普查資料顯示,島上居民已增至7750人,比數十年前多出一倍以上。

此外,人潮除了破壞文化樣貌和生態平衡,也使當地的基礎服務瀕臨極限。當地政府的環境顧問古特雷茲(Ana Maria Gutierrez)舉例說明,復活島居民10年前每年約產生1.5噸廢棄物,但如今一天就高達2.5噸,因為居民的環保意識相當薄弱。

市長艾德蒙茲一方面認同新法是「好的開始」,但另一方面卻直指新法「規模太小」,不足以保護島上文化、遺產和特色,甚至指稱許多拉帕努伊人企盼的是,全面禁止新住民到來。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

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

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

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

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

卡爾大火極具破壞性 加州史上第9大

摘錄自2018年7月31日中央社加州報導

美國加州北部野火「卡爾大火」(Carr Fire)已奪走至少六條人命,在今夏極度乾燥的美西地區數十起火災中災情最嚴重,森林防火廳官員表示,據信這是加州史上第九大破壞性大火。

美聯社報導,加州森林防火廳(CalFire)發言人麥克林(Scott Mclean)表示,這場大火目前據信是加州史上第九大破壞性大火,燒毀至少818棟房屋和311棟附屬建築物,並造成165棟房屋受損。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

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

※幫你省時又省力,新北清潔一流服務好口碑

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

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

G20部長會議 矢言永續農業 消除饑餓

摘錄自2018年7月30日青年日報報導

G20農業部長會議28日於阿根廷布宜諾斯艾利斯落幕,會後各國農業部長發表聯合聲明,矢言「共同努力消除饑餓、促進永續農業,以實現未來糧食的不虞匱乏」。這將成為此屆G20的三大優先目標。

聲明且強調創新的重要性,並對「愈來愈常採取保護主義的非關稅貿易措施感到擔憂」;因為「農業發展、投資與貿易及引進改良技術,近數十年成為人類進步的驅動力,並改善全球數百萬人的生活條件」。G20農業部長因此鼓勵創新農業技術,提升農業生產力與永續性。

另重申土壤健康的重要性,認為其能強化農業在人類發展與資訊通訊技術(ICTs)中的角色,進而加強生產力、糧食安全與農業永續。同時呼籲減少食物損失與浪費,以增進糧食安全,減輕對氣候、水與土地資源造成壓力,並改善農夫、經銷商與家庭經濟的收入。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

新北清潔公司,居家、辦公、裝潢細清專業服務

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

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

※超省錢租車方案

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

電動車、太陽能福音 科學家找到可極速充電的材料

環境資訊中心綜合外電;姜唯 編譯;林大利 審校

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

新北清潔公司,居家、辦公、裝潢細清專業服務

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

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

※超省錢租車方案

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

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

地球2017年體檢報告出爐 溫室氣體突破80萬年記錄

摘錄自2018年8月5日東森新聞報導

美國國家海洋暨大氣總署(NOAA)1日發布了2017年的氣候狀況報告,顯示地球的溫室氣體突破80萬年來的紀錄,這份報告由超過500名全球科學家共同研究,測量2017年的溫度、降水和天氣現象。美國氣象學會公報主編羅森菲爾德(Jeff Rosenfeld)說,這個報告就像地球的身體檢查一樣。

「每年都會檢查同樣的項目,這些數據可以讓我們了解長時間來看,什麼是正常狀況,什麼是異常」,羅森菲爾德說。根據這份長達300頁的報告,2017年地球表面的全球平均二氧化碳濃度是405ppm,比2016年高出2.2ppm,是近代大氣測量記錄和80萬年的冰芯紀錄中最高的。

報告指出,自1960年代以來,二氧化碳濃度已經成長近4倍,海平面高度也創下新高,平均每年上升1.2英吋(3.05公分),現在的海平面高度已經比1993年高約3英吋(7.62公分)。此外,2017年是有記錄以來最熱的非聖嬰年,巴基斯坦甚至在5月份時達到目前世界記錄的5月最高溫攝氏53.5度。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

※回頭車貨運收費標準

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

※超省錢租車方案

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