谷歌上網氣球公司組建機構 推進技術全面商用

  騰訊科技訊,谷歌公司的一家兄弟企業,正在研發利用高空氣球幫助偏僻地區的民眾上網。據外媒最新消息,這家公司最近成立了一個由電信內部人士組成的新的諮詢委員會,以幫助將其價格低廉的“互聯網氣球”變成一種商業服務。

  據國外媒體報道,谷歌母公司 Alphabet 在 2013 年推出了高空氣球上網計劃(Loon 計劃),該項目將創建一個將互聯網傳輸到偏遠地區的氣球網絡。經過幾年的發展,Loon 公司於去年夏天宣布,它相信這項技術已經證明了自己的能力,並表示將開始把這項技術轉變為一項對外推出的業務。

  要做到這一點,這家公司需要與世界各地的移動運營商合作,因此該公司已經聘請了三名有電信運營商經驗的人擔任顧問。

  Loon 首席執行官阿拉斯泰爾·韋斯特加斯(Alastair Westgarth)在發表於社交媒體 Medium 上的一篇文章中指出:“隨着 Loon 向商業企業過渡,公司希望與世界各地的移動運營商合作,我們正在通過一個新的諮詢委員會為我們的隊伍增添一些專業知識,該委員會彙集了在該行業擁有數十年經驗的頂級移動通信創新者。”

  事實上,這三位專家在電信領域帶來了相當多的經驗。克雷格·麥考因創辦麥克考蜂窩公司而聞名,該公司是一家開拓性的無線公司,最終被 AT??T收購。伊恩·斯莫爾目前是 Evernote 的首席執行官,曾擔任西班牙電信公司 Telefonica 的首席數據官。瑪妮·瓦爾登(MarniWalden)是 Verizon 的前執行副總裁兼全球媒體和新業務(Global Media and New Business)總裁。

  這三位專家只是 Loon 公司新機構的“創始成員”,所以如果有更多的人加入這個行列,外界無需感到震驚。鑒於 Loon 的重點是為偏遠或服務不足的地區提供互聯網接入,該公司可能需要擴大規模。目前的董事會成員包括來自美國和歐洲供應商的人員。該公司可能需要特別熟悉發展中國家和其他寬帶稀缺或不存在地區的顧問。

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

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

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

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

美國司法部:黑客侵入SEC數據庫 利用內幕信息獲利數百萬美元

美國證券交易委員會(SEC)主席傑伊·克萊頓(Jay Clayton)在華盛頓特區的公開會議上發表講話

  1 月 16 日消息,據外媒報道,美國聯邦檢察官周二公布了一項與國際股票內幕交易有關的指控,該案嫌疑人涉嫌侵入美國證券交易委員會(SEC)的 EDGAR 公司備案系統。

  據稱,在這起案件中,來自美國的詐騙犯在美國、俄羅斯和烏克蘭凈賺了 410 萬美元。通過利用 157 家公司的財報文件,這些嫌疑人得以在重大非公開信息公布前進行內幕交易獲利。這些文件大多是“測試文件”,由企業將其上傳到 SEC 網站上。

  周二,美國新澤西州聯邦檢察官克雷格·卡貝托(Craig Carpenito)與 SEC、聯邦調查局(FBI)和負責調查金融犯罪的美國特勤局(U.S. Secret Service)共同宣布了上述指控。

  這起國際股票內幕交易案涉及 9 人,作案時間從 2016 年 5 月持續到當年 10 月份。卡貝托在周二的新聞發布會上說,此案涉及數以千計有價值的私人商業文件。他說:“在侵入 EDGAR 系統后,黑客竊取了這些報告的草稿,隨後這些信息才向公眾公開。”

  這些文件包括季度財報、併購計劃等敏感新聞,犯罪分子可以在文件公開前查看,從而影響到個別公司的股價。被指控的黑客利用這些報告執行內幕交易,並將其出售給其他非法交易商。據卡貝托稱,一名內部交易員一天賺了 27 萬美元。

  卡貝托說,黑客使用通過电子郵件發送給 SEC 員工的惡意軟件。在 SEC 的電腦上安裝了該軟件后,他們將能夠從 EDGAR 系統收集到的信息發送到立陶宛的服務器上。在那裡,他們要麼利用這些信息,要麼將數據分發給其他罪犯。

  SEC 執法部門聯席負責人斯蒂芬妮·阿瓦基安(Stephanie Avakian)說,這些罪犯還竊取了發給三家通訊社的事先新聞稿,不過她沒有透露這些通訊社的名字。她還說,黑客利用多個經紀人賬戶來獲取非法收益。

  美國司法部指控兩名烏克蘭人入侵數據庫,他們是奧列克桑德爾·恭弘=恭弘=恭弘=恭弘=恭弘=叶 恭弘 恭弘 恭弘 恭弘 恭弘雷門科(Oleksandr Ieremenko)和阿提姆·拉琴科(Artem Radchenko)。另外 7 個個人和實體也因非法信息交易在民事訴訟中被 SEC 起訴。

  與此同時,這一事件也引發了人們對 SEC 合併審計跟蹤數據庫 CAT 的擔憂。CAT 被用來記錄在美國的每筆交易和訂單,無論是股票還是期權,其目標是提供足夠的數據進行分析,以發現市場操縱和其他惡意行為。

  紐約證券交易所已要求 SEC 考慮限制 CAT 收集的數據數量,這些數據包括每日 580 億筆交易的數據,以及進行交易的個人詳細信息,包括他們的社會保障號碼和出生日期。

  2017 年 9 月,SEC 主席傑伊·克萊頓(Jay Clayton)在長篇聲明中宣布,EDGAR 數據庫遭到黑客攻擊。歐盟委員會表示,該數據庫在 2016 年被入侵,但直到 2017 年 8 月才被發現。

  克萊頓當時稱:“網絡安全對我們的市場運作至關重要,風險巨大,而且在很多情況下都是系統性的入侵。我們還必須認識到,包括 SEC 在內的公共和私營部門將會受到入侵。”

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

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

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

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

我坐了坐王欣的馬桶,覺得太味兒了

  文/Philex

  來源:科技唆麻(ID:techsuoma)

  不少人自認為欠兩個人電影票,一個是周星馳,另一個是王欣。

  前一位的,大概率在《美人魚》的時候已經還清了,即將沖春節檔的《新喜劇之王》的已經開始显示出頹勢:

  “衝著 XX 也要看”的邏輯已經開始失效了。前兩年屢試不爽的“大 IP+ 流量明星”在全年幾乎全線票房撲街,一度喜劇影響力不遜於周星馳的開心麻花,也在《李茶的姑媽》上結結實實栽了個跟頭。

  “衝著 XX 也要看”不靈了,那“衝著 XX 也要用”呢?

  出獄一年,王欣做了兩件事。去年 9 月拿了貝塔斯曼和 IDG 的 3000 萬美元天使輪,以及今年 1 月宣布以匿名社交產品回歸創業。前者被他視為“拿給團隊看的”,後者則是他口中的“剛需”。

  這款產品就是定於今天早上 10:30 發布的馬桶。

  從 14 日晚間起,便有用戶陸續通過馬桶官方公布的方式提前試用。既然主打匿名,如你們所想馬桶里也的確充滿了馬桶里該有的東西:

  沒了“罪魁禍首”樂視作為發泄對象,作為社交產品老大,騰訊自然成為靶子。一如當年“3Q 大戰”時,被 360 煽動的吃瓜群眾一樣,熱烈非凡。

  王欣自己也加入了戰鬥中,但至於事實是不是如王欣字里行間暗示的“微信怕了”,作為看客的我不知道,但微信認定其“網頁包含不安全內容”,我認為並沒有任何過失。

  當然,新生力量被“打壓”的戲碼永遠是群眾喜聞樂見的。咱不用微信和短信邀請了,咱直接上官網也行。但事實證明,王欣的這隻馬桶完全沒有做好上線的準備。

  從今天上午開始,下載好 App 的,一直處於“驗證碼錯誤”的狀態。而沒還沒下載的,已經沒地兒下載了,iOS 下載鏈接已經被關停,蒲公英應用內測分發平台上,App 也已經被刪除。

  更扎心的在於已經有不少用戶開始質疑“為何一個匿名社交 App 要獲取通訊錄權限?”

  就“發布馬桶”這件事本身來說,已經成為了一場車禍。而一直以“產品經理”的標籤示人的王欣,顯然清楚一款產品在這一階段流失用戶的後果。

  我更想說的是,王欣在抓緊修復問題的同時,可能要開始審視一下自己的人設。

  1

  冷啟動,靠個人品牌靠譜嗎?

  正如開頭那個段子一樣,“欠 XX 一張電影票”從本質上來講,是社交貨幣的一種體現。

  譬如,你自稱“欠星爺一張電影票”,約等於為自己貼上了一個“周星馳影迷”的標籤。

  我來一句“欠王欣一張電影票/會員”,很大程度上為自己貼上的是“關注互聯網行業”或者“我也青春過”的標籤。

  別笑,在中國這個複雜且龐大的市場,整天把段子掛在嘴邊的人,不少就是他所在圈子中的“懂的人”。自詡“懂”的人,是不屑於整天把“雞湯味”更濃的馬雲、任正非掛在嘴邊的;他們更崇拜張小龍……以及王欣。

  而王欣很有可能陷入了一個“大V怪圈”。

  類似的情況經常出現在不少大V身上。社交時代,總有人囿於表達技巧的欠缺,或是懶於表達自己的態度與觀點,而被一個人設鮮明的大V吸粉。粉的人,奉為圭臬;黑的人,棄如敝履。

  王欣的人設是“堅信技術無罪的天才”,滿足了不少人“謝耳朵式幻想”。

  從過往的輿論來看,吹捧王欣,至少已經能聚集起相當一部分人。而這群人表現出的態度很大程度上主要關注的並不是“做了什麼”,而是“誰在做”。王欣目前聚集起的大量用戶,並不像微信早期切入市場時,是瞄準了“移動端即時通訊”這一需求的發芽,而僅僅因為他是王欣做的。

  在所謂的“苦微信久矣”大環境下,少年斗惡龍的戲碼自然是群眾喜聞樂見的。而如果這位少年還是“自帶青春回憶濾鏡”的王欣,戲劇程度顯然就更高了。

  換言之,馬桶是什麼不重要,“王欣的產品”才是重點。

  如果你有留心最近的新聞,王欣的各種採訪想必是刷到了不少。以個人品牌作為產品冷啟動的憑藉,的確是能夠在短時間內聚集起一大批種子用戶。

  那麼,然後呢?是不斷滿足這群快播延續下來的種子用戶的需求,為“拜王欣教”打造一款“圈地自萌”式的產品,還是以傳統邏輯燒錢拉新蹣跚前行?

  畢竟,個人品牌的反噬作用,我們在手機圈已經能找到案例。反觀當年快播做到 3 億用戶,也從未將王欣抬到台前。

  2

  匿名社交真的有戲?那麼多閃呢

  “微信無法撼動”已經成為共識,那麼放棄熟人社交,以“匿名”切入社交賽道的確順理成章。不過,以當下的初步顯露的問題來看,馬桶顯然有不少沒有考慮到問題。

  匿名社交不是什麼新鮮事物,從當年各種聊天室、BBS,到後來一度火爆的無秘、烏鴉、幾度。從 PC 互聯網,到移動互聯網,它的確是一種“剛需”,畢竟窺私慾是人性中天生的一部分。

  匿名是真的在“緩解壓力”嗎?恐怕不是,匿名潛台詞其實是“你不用為你的言論負責”

  互不相識地兩個人會匿名討論最喜歡的作家是誰嗎?顯然不會。

  所以你能看到最“長壽”的匿名社交產品是誰呢?是脈脈。原因無非兩點:一方面相對垂直,多為互聯網相關話題;另一方面是公司認證,好像一定程度上彌補了言論真實性的問題,也出現過翻車問題。

  既不垂直,亦無須為言論負責,顯然難逃一死。

  往輕了說,就像曾經的無秘,早期還是一片豐收的瓜田,最後卻成了造謠攻擊的溫床。而往嚴重了,LBS 配合匿名社交,想象空間不可謂不大。比如銷售某些違禁商品、拉皮條……至少我已經聽到的消息是,不少黑產玩家已經躍躍欲試了。

  以過往的經驗來看,監管的重鎚一旦落下,後續翻身的機會顯然渺茫。

  而最難堪的問題在於那個創投圈最經典的問題“騰訊做了怎麼辦?”

  騰訊的 QQ 和微信牢牢把握住熟人社交的市場,微信不必多說,QQ 至少是目前最大的年輕用戶社交平台,以至於外界會誕生出一種不切實際的看法:既然熟人市場已經結束,那麼陌生人社交呢?

  從陌陌到探探,陌生人社交真的那麼好做嗎?

  當年 Snapchat 與 Facebook 的那一場大戰不少人還記憶猶新。Snapchat 憑藉“閱后即焚”的亮點功能,從學生群體中開始爆紅,一度市值高達 330 億美元。

  而在拒絕 Facebook 的收購之後,前者開始全面將“閱后即焚”作為旗下產品的內建功能。如今 Snapchat 市值僅剩不足 82 億美元。

  和熟人社交以關係鏈作為壁壘不同,匿名社交可以說毫無壁壘可言。

  以王欣瞄準的微信為例,無論是已經作古的“漂流瓶”還是同樣 LBS 社交的“附近的人”,都曾是冷啟動時的殺手鐧。這對於如今的微信來講,並沒有技術壁壘。

  對微信而言,實現起來僅僅是在發現頁加一個按鈕而已,背後則是覆蓋的 10 億的裝機量。

  換言之,需要匿名交流場景,對效率的要求是極高的,這意味着微信/QQ 有着天然優勢。心如火燎地捧着半天沒幾個人的馬桶,和到處都是人的微信/QQ,你選誰呢。

  如果想得更遠一點,如果微信真的有了匿名社交。聊得來的話,隨口一句“加個微信吧”,這可能是殺手級的應用。

  總之,匿名社交可能有戲,但分誰來做。

  3

  最後:如何定義圈子?

  截止到完稿時,今天的第三場社交產品發布會還沒開始。從匿名社交的馬桶、到“專為年輕人打造”的多閃,其實我認為有一個本末倒置的地方。

  做社交,定義圈子的不是產品,而是文化。

  中國是個大市場,有極大的想象力。所以也不賴互聯網公司沒創意,扎堆兒做社交,誰都想複製當年騰訊以社交為根據地的打法。

  但問題是,中國這個市場也足夠複雜。所以“專為年輕人打造”的產品其實完全找不到落腳點、莫說是 90 后與 95 后相差甚遠,哪怕是細化到同一個班級,也是你愛二次元,我看 NBA。

  互聯網降低了獲取信息的難度,也解放了個體的發展方向。

  所以,倒回去看過去一段時間一度表現不錯社交產品,比如一起唱歌的音遇、一起看電影的微光、亦或是以愛好共同點匹配的 soul……無不適將落腳點放在“文化認同”上。

  顯然,打敗微信的,不會是下一個微信。

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

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

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

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

.NET高級特性-Emit(2)類的定義,.NET高級特性-Emit(1)

  在上一篇博文發了一天左右的時間,就收到了博客園許多讀者的評論和推薦,非常感謝,我也會及時回復讀者的評論。之後我也將繼續撰寫博文,梳理相關.NET的知識,希望.NET的圈子能越來越大,開發者能了解/深入.NET的本質,將工作做的簡單又高效,拒絕重複勞動,拒絕CRUD。

  ok,咱們開始繼續Emit的探索。在這之前,我先放一下我往期關於Emit的文章,方便讀者閱讀。

  《》

一、基礎知識

  既然C#作為一門面向對象的語言,所以首當其沖的我們需要讓Emit為我們動態構建類。

  廢話不多說,首先,我們先來回顧一下C#類的內部由什麼東西組成:

  (1) 字段-C#類中保存數據的地方,由訪問修飾符、類型和名稱組成;

  (2) 屬性-C#類中特有的東西,由訪問修飾符、類型、名稱和get/set訪問器組成,屬性的是用來控制類中字段數據的訪問,以實現類的封裝性;在Java當中寫作getXXX()和setXXX(val),C#當中將其變成了屬性這種語法糖;

  (3) 方法-C#類中對邏輯進行操作的基本單元,由訪問修飾符、方法名、泛型參數、入參、出參構成;

  (4) 構造器-C#類中一種特殊的方法,該方法是專門用來創建對象的方法,由訪問修飾符、與類名相同的方法名、入參構成。

  接着,我們再觀察C#類本身又具備哪些東西:

  (1) 訪問修飾符-實現對C#類的訪問控制

  (2) 繼承-C#類可以繼承一個父類,並需要實現父類當中所有抽象的方法以及選擇實現父類的虛方法,還有就是子類需要調用父類的構造器以實現對象的創建

  (3) 實現-C#類可以實現多個接口,並實現接口中的所有方法

  (4) 泛型-C#類可以包含泛型參數,此外,類還可以對泛型實現約束

  以上就是C#類所具備的一些元素,以下為樣例:

public abstract class Bar
{
    public abstract void PrintName();
}
public interface IFoo<T> { public T Name { get; set; } } //繼承Bar基類,實現IFoo接口,泛型參數T
public class Foo<T> : Bar, IFoo<T>
  //泛型約束
  where T : struct {
//構造器 public Foo(T name):base() { _name = name; } //字段 private T _name; //屬性 public T Name { get => _name; set => _name = value; } //方法 public override void PrintName() {
    Console.WriteLine(_name.ToString()); }
}

  在探索完了C#類及其定義后,我們要來了解C#的項目結構組成。我們知道C#的一個csproj項目最終會對應生成一個dll文件或者exe文件,這一個文件我們稱之為程序集Assembly;而在一個程序集中,我們內部包含和定義了許多命名空間,這些命令空間在C#當中被稱為模塊Module,而模塊正是由一個一個的C#類Type組成。

 

 

 

   所以,當我們需要定義C#類時,就必須首先定義Assembly以及Module,如此才能進行下一步工作。

二、IL概覽

   由於Emit實質是通過IL來生成C#代碼,故我們可以反向生成,先將寫好的目標代碼寫成cs文件,通過編譯器生成dll,再通過ildasm查看IL代碼,即可依葫蘆畫瓢的編寫出Emit代碼。所以我們來查看以下上節Foo所生成的IL代碼。

  

 

 

   從上圖我們可以很清晰的看到.NET的層級結構,位於樹頂層淺藍色圓點表示一個程序集Assembly,第二層藍色表示模塊Module,在模塊下的均為我們所定義的類,類中包含類的泛型參數、繼承類信息、實現接口信息,類的內部包含構造器、方法、字段、屬性以及它的get/set方法,由此,我們可以開始編寫Emit代碼了

三、Emit編寫

  有了以上的對C#類的解讀和IL的解讀,我們知道了C#類本身所需要哪些元素,我們就開始根據這些元素來開始編寫Emit代碼了。這裏的代碼量會比較大,請讀者慢慢閱讀,也可以參照以上我寫的類生成il代碼進行比對。

  在Emit當中所有創建類型的幫助類均以Builder結尾,從下錶中我們可以看的非常清楚

元素中文 元素名稱 對應Emit構建器名稱
程序集  Assembly AssemblyBuilder
模塊  Module ModuleBuilder
 Type TypeBuilder
構造器  Constructor ConstructorBuilder
屬性  Property PropertyBuilder
字段  Field FieldBuilder
方法  Method MethodBuilder

  由於創建類需要從Assembly開始創建,所以我們的入口是AssemblyBuilder

  (1) 首先,我們先引入命名空間,我們以上節Foo類為樣例進行編寫

using System.Reflection.Emit;

  (2) 獲取基類和接口的類型

var barType = typeof(Bar);
var interfaceType = typeof(IFoo<>);

  (3) 定義Foo類型,我們可以看到在定義類之前我們需要創建Assembly和Module

//定義類
var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("Edwin.Blog.Emit"), AssemblyBuilderAccess.Run);
var moduleBuilder = assemblyBuilder.DefineDynamicModule("Edwin.Blog.Emit");
var typeBuilder = moduleBuilder.DefineType("Foo", TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit);

  (4) 定義泛型參數T,並添加約束

//定義泛型參數
var genericTypeBuilder = typeBuilder.DefineGenericParameters("T")[0];
//設置泛型約束
genericTypeBuilder.SetGenericParameterAttributes(GenericParameterAttributes.NotNullableValueTypeConstraint);

  (5) 繼承和實現接口,注意當實現類的泛型參數需傳遞給接口時,需要將泛型接口添加泛型參數后再調用AddInterfaceImplementation方法

//繼承基類
typeBuilder.SetParent(barType);
//實現接口
typeBuilder.AddInterfaceImplementation(interfaceType.MakeGenericType(genericTypeBuilder));

  (6) 定義字段,因為字段在構造器值需要使用,故先創建

//定義字段
var fieldBuilder = typeBuilder.DefineField("_name", genericTypeBuilder, FieldAttributes.Private);

  (7) 定義構造器,並編寫內部邏輯

//定義構造器
var ctorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, CallingConventions.Standard, new Type[] { genericTypeBuilder });
var ctorIL = ctorBuilder.GetILGenerator();
//Ldarg_0在實例方法中表示this,在靜態方法中表示第一個參數
ctorIL.Emit(OpCodes.Ldarg_0);
ctorIL.Emit(OpCodes.Ldarg_1);
//為field賦值
ctorIL.Emit(OpCodes.Stfld, fieldBuilder);
ctorIL.Emit(OpCodes.Ret);

  (8) 定義Name屬性

//定義屬性
var propertyBuilder = typeBuilder.DefineProperty("Name", PropertyAttributes.None, genericTypeBuilder, Type.EmptyTypes);

  (9) 編寫Name屬性的get/set訪問器

//定義get方法
var getMethodBuilder = typeBuilder.DefineMethod("get_Name", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.SpecialName | MethodAttributes.Virtual, CallingConventions.Standard, genericTypeBuilder, Type.EmptyTypes);
var getIL = getMethodBuilder.GetILGenerator();
getIL.Emit(OpCodes.Ldarg_0);
getIL.Emit(OpCodes.Ldfld, fieldBuilder);
getIL.Emit(OpCodes.Ret);
typeBuilder.DefineMethodOverride(getMethodBuilder, interfaceType.GetProperty("Name").GetGetMethod()); //實現對接口方法的重載
propertyBuilder.SetGetMethod(getMethodBuilder); //設置為屬性的get方法
//定義set方法
var setMethodBuilder = typeBuilder.DefineMethod("set_Name", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.SpecialName | MethodAttributes.Virtual, CallingConventions.Standard, null, new Type[] { genericTypeBuilder });
var setIL = setMethodBuilder.GetILGenerator();
setIL.Emit(OpCodes.Ldarg_0);
setIL.Emit(OpCodes.Ldarg_1);
setIL.Emit(OpCodes.Stfld, fieldBuilder);
setIL.Emit(OpCodes.Ret);
typeBuilder.DefineMethodOverride(setMethodBuilder, interfaceType.GetProperty("Name").GetSetMethod()); //實現對接口方法的重載
propertyBuilder.SetSetMethod(setMethodBuilder); //設置為屬性的set方法

   (10) 定義並實現PrintName方法

//定義方法
var printMethodBuilder = typeBuilder.DefineMethod("PrintName", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual, CallingConventions.Standard, null, Type.EmptyTypes);
var printIL = printMethodBuilder.GetILGenerator();
printIL.Emit(OpCodes.Ldarg_0);
printIL.Emit(OpCodes.Ldflda, fieldBuilder);
printIL.Emit(OpCodes.Constrained, genericTypeBuilder);
printIL.Emit(OpCodes.Callvirt, typeof(object).GetMethod("ToString", Type.EmptyTypes));
printIL.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
printIL.Emit(OpCodes.Ret);
//實現對基類方法的重載
typeBuilder.DefineMethodOverride(printMethodBuilder, barType.GetMethod("PrintName", Type.EmptyTypes));

  (11) 創建類

var type = typeBuilder.CreateType(); //netstandard中請使用CreateTypeInfo().AsType()

  (12) 調用

var obj = Activator.CreateInstance(type.MakeGenericType(typeof(DateTime)), DateTime.Now);
(obj as Bar).PrintName();
Console.WriteLine((obj as IFoo<DateTime>).Name);

四、應用

  上面的樣例僅供學習只用,無法運用在實際項目當中,那麼,Emit構建類在實際項目中我們可以有什麼應用,提高我們的編碼效率

  (1) 動態DTO-當我們需要將實體映射到某個DTO時,可以用動態DTO來代替你手寫的DTO,選擇你需要的字段回傳給前端,或者前端把他想要的字段傳給後端

  (2) DynamicLinq-我的第一篇博文有個讀者提到了表達式樹,而linq使用的正是表達式樹,當表達式樹+Emit時,我們就可以用像SQL或者GraphQL那樣的查詢語句實現動態查詢

  (3) 對象合併-我們可以編寫實現一個像js當中Object.assign()一樣的方法,實現對兩個實體的合併

  (4) AOP動態代理-AOP的核心就是代理模式,但是與其對應的是需要手寫代理類,而Emit就可以幫你動態創建代理類,實現切面編程

  (5) …

五、小結

  對於Emit,確實初學者會對其感到複雜和難以學習,但是只要搞懂其中的原理,其實最終就是C#和.NET語言的本質所在,在學習Emit的同時,也是在鍛煉你的基本功是否紮實,你是否對這門語言精通,是否有各種簡化代碼的應用。

  保持學習,勇於實踐;Write Less,Do More;作者之後還會繼續.NET高級特性系列,感謝閱讀!

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

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

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

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

區塊鏈成重要突破口,與幣圈無關卻與5G有關

  幾乎是一夜之間,區塊鏈就成了更熱門的話題,此前,如果我們還在說“物聯網、大數據、雲計算、人工智能和 5G”,那麼,以後這一長串的背後可能就要加上“區塊鏈”。

  誠然,國家將區塊鏈當成戰略來發展,並“要把區塊鏈作為核心技術自主創新的重要突破口,明確主攻方向,加大投入力度,着力攻克一批關鍵核心技術,加快推動區塊鏈技術和產業創新發展”,這對整個區塊鏈產業都是巨大的利好,但是,這種利好卻實實在在與現在網絡上那些頂着區塊鏈帽子實際卻是在搞傳銷的“幣”們,毫無關係。如果有關係,那也一定是負面。

  在國內,區塊鏈技術佔據優勢的公司依然是 BAT,特別是阿里巴巴和螞蟻金服。在 2018 年的世界互聯網大會上,螞蟻金服“自主可控金融級商用區塊鏈平台”與“阿里雲 supET 工業互聯網平台”同時入選 15 項世界互聯網領先科技成果之列。前者的區塊鏈因素顯而易見,後者實際上也在由區塊鏈提供製造生產質量追溯和供應鏈管理服務。

  據全球知名智能信息服務機構科睿唯安公布信息,截至 2019 年 4 月 30 日,阿里巴巴以 290 件區塊鏈專利方案數量穩居全球第一。結合權威知識產權產業媒體 IPRdaily 過去兩年發布的“全球區塊鏈專利企業排行榜”显示,阿里巴巴申請的區塊鏈專利數量已經連續三年全球第一。2019 上半年全球區塊鏈企業發明專利排行榜(TOP100) 中,阿里巴巴以 322 件專利位列第一,中國平安以 274 件專利排名第二,Nchain 以 241 件專利排名第三。此外,百度( 7 名)、騰訊( 13 名)、京東( 14 名)、華為( 28 名)、獵豹( 40 名)、中國移動( 44 名)等均榜上有名。

  從上面的數據可以看出來,真正在區塊鏈的研究上佔據優勢且不斷應用的,沒有一個是“發幣”的,都是實實在在的在落地。

  當然了,也許與幣有關。此前有消息傳言,央行可能將在未來幾個月內正式推出國家支持的数字貨幣“DCEP”,初期將向中國工商銀行、中國建設銀行、中國銀行、中國農業銀行、阿里巴巴、騰訊以及銀聯七家機構發行。如果成行,那將是世界上是首個法定数字貨幣,意義深遠。

  在官方發布的新聞中,將區塊鏈發展方向定位為四個方面:

  1、要探索“區塊鏈+”在民生領域的運用,积極推動區塊鏈技術在教育、就業、養老、精準脫貧、醫療健康、商品防偽、食品安全、公益、社會救助等領域的應用,為人民群眾提供更加智能、更加便捷、更加優質的公共服務。

  2016 年,螞蟻金服聯合中國紅十字基金會等公益機構上線區塊鏈試驗項目,使捐款人可以追蹤善款的完整流轉情況。2017 年 3 月,支付寶愛心捐贈平台全面引入區塊鏈技術,所有捐贈數據上鏈。實現了實時賬目公示,有助於解決公益財務透明的“痛點”。螞蟻金服公益運用區塊鏈技術追蹤籌款,建立起第三方公示體系區塊鏈資金流公示,為公益機構進行數據統計、項目執行跟蹤提供便利。區塊鏈具有不可篡改的特性,任何寫入區塊鏈的記錄均不能更改,可以供公眾監督及審計。而“區塊鏈+公益”正是利用這一特性,發揮公眾賬本的價值,不論用戶是捐十塊、二十塊還是幾百塊,讓用戶所獻出的每一筆都記錄在區塊鏈上,有跡可循,持續追溯。

  2016 年 10 月,阿里與微軟、小蟻、法大大等合作開發“法鏈”,推出基於阿里雲平台的郵箱存證產品,通過法鏈上備份的电子郵件和雲服務,阿里將使中國法院能大規模採用数字證據郵件。

  2017 年 3 月,阿里巴巴與普華永道合作,打造可追溯的跨境食品供應鏈,用於跟蹤產品從生產者到消費者之間的整個流程。

  2017 年 8 月,阿里健康與江蘇常州市合作推出我國首個基於醫療場景的區塊鏈應用――“醫聯體+區塊鏈”試點項目。

  2017 年 10 月 11 日,螞蟻金服 CTO 程立在螞蟻金服金融科技開放峰會上首度披露未來的技術布局――“BASIC”戰略,其中的B對應的就是區塊鏈(Blockchain),同時,技術實驗室宣布開放區塊鏈技術,支持進口食品安全溯源、商品正品溯源等,第一個落地場景將是海外奶粉品牌的追蹤,先是產自澳洲、新西蘭的 26 個品牌的奶粉。2017 年 11 月 24 日,天貓國際宣布升級全球原產地溯源計劃,未來將覆蓋全球 63 個國家和地區,3700 個品類,14500 個海外品牌,也將向全行業開放,賦能整個行業。2018 年 2 月,菜鳥與天貓國際官方消息,已啟用區塊鏈技術跟蹤、上傳、查證跨境進口商品的物流全鏈路信息,涵蓋生產、運輸、通關、報檢、第三方檢驗等商品進口全流程,為每個跨境進口商品打上獨一無二的“身份證”,供消費者查詢驗證。

  騰訊旗下的微眾銀行於 2016 年 6 月開發出面向金融業的聯盟鏈雲服務 BaaS,並在 2017 年 1 月落地了第一個商業場景,即微黃金項目。微黃金是騰訊的一項在線黃金交易服務,用戶可以在微信低門檻靈活購買黃金,其背後正是由騰訊開發底層基礎架構的聯盟鏈。騰訊、工商銀行等多個節點共同參与記帳。2018 年 4 月底,騰訊發布第一款區塊鏈遊戲《一起來捉妖》,試圖通過區塊鏈技術保障了遊戲稀有內容投放的公開公平性,同時用戶可以將稀有妖怪上鏈永久保存。

  2017 年 12 月,沃爾瑪、京東、IBM、清華大學电子商務交易技術國家工程實驗室共同宣布成立安全食品區塊鏈溯源聯盟,運用區塊鏈技術搭建“京東區塊鏈防偽追溯開放平台”。該平台推出之後,用戶只需打開京東 APP 找到購物訂單,通過“一鍵溯源”或直接掃描產品溯源碼,即可獲取溯源信息。

  2018 年 10 月,百度正式發布自主研發的區塊鏈網絡系統——超級鏈。同時,宣布與海南省政府合作,區塊鏈實驗室及度鏈公司落戶海南,並推出“區塊鏈+大閘蟹溯源”應用。

  2、要推動區塊鏈底層技術服務和新型智慧城市建設相結合,探索在信息基礎設施、智慧交通、能源電力等領域的推廣應用,提升城市管理的智能化、精準化水平。

  5 月 22 日,上海、浙江、江蘇、安徽 4 地法院成立全國首個區域司法鏈,實現從起訴到執行全程上鏈,極大提高了訴訟效率和法院公信力,降低訴訟成本。最早引入區塊鏈技術的杭州互聯網法院,上鏈半年,其知識產權糾紛案件的調撤率上升至 95.3%。

  2017 年 5 月,阿里投資 Symbiont,該公司致力於利用區塊鏈技術打造一個發行和交易智能證券的平台。此外,深圳財富文化集團已經打造了一個文化產權交易的區塊鏈平台,並與螞蟻雙鏈打通,解決文化藝術品流通、交易和一系列金融服務。

  2017 年 11 月 8 日,阿里巴巴集團、螞蟻金服集團與雄安新區簽署了戰略合作協議,阿里巴巴與螞蟻金服將承建数字雄安區塊鏈實施平台。

  另外,國網電商公司已建成國家電網公司系統內首個司法級可信區塊鏈公共服務平台,作為唯一央企與北京互聯網法院“天平鏈”互信互通,掛牌工信部區塊鏈重點實驗室電力應用實驗基地,參与首個區塊鏈國家標準制定,實現了區塊鏈技術在電力積分通兌、光伏簽約、票據繳費、电子發票等多場景落地應用。

  3、要利用區塊鏈技術促進城市間在信息、資金、人才、徵信等方面更大規模的互聯互通,保障生產要素在區域內有序高效流動。

  在 9 月末舉行的雲棲大會·螞蟻區塊鏈生態峰會上,螞蟻金服集團副總裁蔣國飛透露,螞蟻區塊鏈已落地 40 多個應用。含括跨境支付、供應鏈金融、通用溯源、电子票據等多個行業領域。並於同期宣布了與全球最大的種子和農藥公司拜耳合作,應用方向進一步擴展。

  螞蟻金服 8 月份宣布,基於區塊鏈技術的供應鏈協作網絡——螞蟻區塊鏈“雙鏈通”全面升級開放。這一服務運用區塊鏈技術可解決供應鏈金融中的信任難題,同時讓小微商家也能享受高效便捷的金融服務。目前,這一模式已在成都率先應用。通過與成都商業銀行、成都中小企業融資擔保公司的合作,“雙鏈通”完成了供應鏈金融的全鏈路覆蓋。上鏈后,整個融資流轉過程清晰留痕、不可篡改,所有參与方都要通過“雙鏈通”進行身份核實和意願確認,数字簽名實時上鏈,杜絕了資金挪用等風險。

  4、要探索利用區塊鏈數據共享模式,實現政務數據跨部門、跨區域共同維護和利用,促進業務協同辦理,深化“最多跑一次”改革,為人民群眾帶來更好的政務服務體驗。

  3 月,杭州地鐵聯合支付寶、螞蟻區塊鏈推出了區塊鏈电子發票。全程手機操作,耗時不到 10 秒,上班族再也不用前往窗口排隊取票了。支付寶聯合雲南省相關部門,在醫療、教育等多個民生服務場景落地區塊鏈电子票據。從地鐵电子發票到法院訴訟案件,再到电子票據平台,螞蟻區塊鏈在過去近 3 年時間里,相繼落地了 40 多個場景。其中長三角佔比超過一半。“上鏈”后長三角人辦事效率大大提升,不少事項可享受“秒級”服務。

  我們看到,在 5G 時代,無差別計算能力的流通成本會大幅下降,無差別計算能力是 AI 最重要的勞動要素,而區塊鏈就是 AI 最重要的勞動要素。阿里巴巴達摩院在《2019 十大科技趨勢》中提到,5G 和區塊鏈是未來十年的發展方向。《福布斯》發布的《2020 十大科技趨勢》也提到,5G 和區塊鏈都將於 2020 年崛起,未來與人們日常生活相關的每一個行業都會被變革。還是那句話,“誰能把當前的技術和資源用到最充分,誰就是這個時代的最強者”,也許 5G 的流量充沛,正是區塊鏈的黃金歲月。

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

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

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

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

Python 命令行之旅:深入 click 之子命令篇

作者:HelloGitHub-Prodesire

HelloGitHub 的《講解開源項目》系列,項目地址:https://github.com/HelloGitHub-Team/Article

一、前言

在上兩篇文章中,我們介紹了 click 中的”參數“和“選項”,本文將繼續深入了解 click,着重講解它的“命令”和”組“。

本系列文章默認使用 Python 3 作為解釋器進行講解。
若你仍在使用 Python 2,請注意兩者之間語法和庫的使用差異哦~

二、命令和組

Click 中非常重要的特性就是任意嵌套命令行工具的概念,通過 和 (實際上是 )來實現。

所謂命令組就是若干個命令(或叫子命令)的集合,也成為多命令。

2.1 回調調用

對於一個普通的命令來說,回調發生在命令被執行的時候。如果這個程序的實現中只有命令,那麼回調總是會被觸發,就像我們在上一篇文章中舉出的所有示例一樣。不過像 --help 這類選項則會阻止進入回調。

對於組和多個子命令來說,情況略有不同。回調通常發生在子命令被執行的時候:

@click.group()
@click.option('--debug/--no-debug', default=False)
def cli(debug):
    click.echo('Debug mode is %s' % ('on' if debug else 'off'))

@cli.command()  # @cli, not @click!
def sync():
    click.echo('Syncing')

執行效果如下:

Usage: tool.py [OPTIONS] COMMAND [ARGS]...

Options:
  --debug / --no-debug
  --help                Show this message and exit.

Commands:
  sync

$ tool.py --debug sync
Debug mode is on
Syncing

在上面的示例中,我們將函數 cli 定義為一個組,把函數 sync 定義為這個組內的子命令。當我們調用 tool.py --debug sync 命令時,會依次觸發 clisync 的處理邏輯(也就是命令的回調)。

2.2 嵌套處理和上下文

從上面的例子可以看到,命令組 cli 接收的參數和子命令 sync 彼此獨立。但是有時我們希望在子命令中能獲取到命令組的參數,這就可以用 來實現。

每當命令被調用時,click 會創建新的上下文,並鏈接到父上下文。通常,我們是看不到上下文信息的。但我們可以通過 裝飾器來顯式讓 click 傳遞上下文,此變量會作為第一個參數進行傳遞。

@click.group()
@click.option('--debug/--no-debug', default=False)
@click.pass_context
def cli(ctx, debug):
    # 確保 ctx.obj 存在並且是個 dict。 (以防 `cli()` 指定 obj 為其他類型
    ctx.ensure_object(dict)

    ctx.obj['DEBUG'] = debug

@cli.command()
@click.pass_context
def sync(ctx):
    click.echo('Debug is %s' % (ctx.obj['DEBUG'] and 'on' or 'off'))

if __name__ == '__main__':
    cli(obj={})

在上面的示例中:

  • 通過為命令組 cli 和子命令 sync 指定裝飾器 click.pass_context,兩個函數的第一個參數都是 ctx 上下文
  • 在命令組 cli 中,給上下文的 obj 變量(字典)賦值
  • 在子命令 sync 中通過 ctx.obj['DEBUG'] 獲得上一步的參數
  • 通過這種方式完成了從命令組到子命令的參數傳遞

2.3 不使用命令來調用命令組

默認情況下,調用子命令的時候才會調用命令組。而有時你可能想直接調用命令組,通過指定 click.groupinvoke_without_command=True 來實現:

@click.group(invoke_without_command=True)
@click.pass_context
def cli(ctx):
    if ctx.invoked_subcommand is None:
        click.echo('I was invoked without subcommand')
    else:
        click.echo('I am about to invoke %s' % ctx.invoked_subcommand)

@cli.command()
def sync():
    click.echo('The subcommand')

調用命令有:

$ tool
I was invoked without subcommand
$ tool sync
I am about to invoke sync
The subcommand

在上面的示例中,通過 ctx.invoked_subcommand 來判斷是否由子命令觸發,針對兩種情況打印日誌。

2.4 自定義命令組/多命令

除了使用 來定義命令組外,你還可以自定義命令組(也就是多命令),這樣你就可以延遲加載子命令,這會很有用。

自定義多命令需要實現 list_commandsget_command 方法:

import click
import os

plugin_folder = os.path.join(os.path.dirname(__file__), 'commands')

class MyCLI(click.MultiCommand):

    def list_commands(self, ctx):
        rv = []  # 命令名稱列表
        for filename in os.listdir(plugin_folder):
            if filename.endswith('.py'):
                rv.append(filename[:-3])
        rv.sort()
        return rv

    def get_command(self, ctx, name):
        ns = {}
        fn = os.path.join(plugin_folder, name + '.py')  # 命令對應的 Python 文件
        with open(fn) as f:
            code = compile(f.read(), fn, 'exec')
            eval(code, ns, ns)
        return ns['cli']

cli = MyCLI(help='This tool\'s subcommands are loaded from a '
            'plugin folder dynamically.')

# 等價方式是通過 click.command 裝飾器,指定 cls=MyCLI
# @click.command(cls=MyCLI)
# def cli():
#     pass

if __name__ == '__main__':
    cli()

2.5 合併命令組/多命令

當有多個命令組,每個命令組中有一些命令,你想把所有的命令合併在一個集合中時,click.CommandCollection 就派上了用場:


@click.group()
def cli1():
    pass

@cli1.command()
def cmd1():
    """Command on cli1"""

@click.group()
def cli2():
    pass

@cli2.command()
def cmd2():
    """Command on cli2"""

cli = click.CommandCollection(sources=[cli1, cli2])

if __name__ == '__main__':
    cli()

調用命令有:

$ cli --help
Usage: cli [OPTIONS] COMMAND [ARGS]...

Options:
  --help  Show this message and exit.

Commands:
  cmd1  Command on cli1
  cmd2  Command on cli2

從上面的示例可以看出,cmd1cmd2 分別屬於 cli1cli2,通過 click.CommandCollection 可以將這些子命令合併在一起,將其能力提供個同一個命令程序。

Tips:如果多個命令組中定義了同樣的子命令,那麼取第一個命令組中的子命令。

2.6 鏈式命令組/多命令

有時單級子命令可能滿足不了你的需求,你甚至希望能有多級子命令。典型地,setuptools 包中就支持多級/鏈式子命令: setup.py sdist bdist_wheel upload。在 click 3.0 之後,實現鏈式命令組變得非常簡單,只需在 click.group 中指定 chain=True

@click.group(chain=True)
def cli():
    pass


@cli.command('sdist')
def sdist():
    click.echo('sdist called')


@cli.command('bdist_wheel')
def bdist_wheel():
    click.echo('bdist_wheel called')

調用命令則有:

$ setup.py sdist bdist_wheel
sdist called
bdist_wheel called

2.7 命令組/多命令管道

鏈式命令組中一個常見的場景就是實現管道,這樣在上一個命令處理好后,可將結果傳給下一個命令處理。

實現命令組管道的要點是讓每個命令返回一個處理函數,然後編寫一個總的管道調度函數(並由 MultiCommand.resultcallback() 裝飾):

@click.group(chain=True, invoke_without_command=True)
@click.option('-i', '--input', type=click.File('r'))
def cli(input):
    pass

@cli.resultcallback()
def process_pipeline(processors, input):
    iterator = (x.rstrip('\r\n') for x in input)
    for processor in processors:
        iterator = processor(iterator)
    for item in iterator:
        click.echo(item)

@cli.command('uppercase')
def make_uppercase():
    def processor(iterator):
        for line in iterator:
            yield line.upper()
    return processor

@cli.command('lowercase')
def make_lowercase():
    def processor(iterator):
        for line in iterator:
            yield line.lower()
    return processor

@cli.command('strip')
def make_strip():
    def processor(iterator):
        for line in iterator:
            yield line.strip()
    return processor

在上面的示例中:

  • cli 定義為了鏈式命令組,並且指定 invoke_without_command=True,也就意味着可以不傳子命令來觸發命令組
  • 定義了三個命令處理函數,分別對應 uppercaselowercasestrip 命令
  • 在管道調度函數 process_pipeline 中,將輸入 input 變成生成器,然後調用處理函數(實際輸入幾個命令,就有幾個處理函數)進行處理

2.8 覆蓋默認值

默認情況下,參數的默認值是從通過裝飾器參數 default 定義。我們還可以通過 Context.default_map 上下文字典來覆蓋默認值:

@click.group()
def cli():
    pass

@cli.command()
@click.option('--port', default=8000)
def runserver(port):
    click.echo('Serving on http://127.0.0.1:%d/' % port)

if __name__ == '__main__':
    cli(default_map={
        'runserver': {
            'port': 5000
        }
    })

在上面的示例中,通過在 cli 中指定 default_map 變可覆蓋命令(一級鍵)的選項(二級鍵)默認值(二級鍵的值)。

我們還可以在 click.group 中指定 context_settings 來達到同樣的目的:


CONTEXT_SETTINGS = dict(
    default_map={'runserver': {'port': 5000}}
)

@click.group(context_settings=CONTEXT_SETTINGS)
def cli():
    pass

@cli.command()
@click.option('--port', default=8000)
def runserver(port):
    click.echo('Serving on http://127.0.0.1:%d/' % port)

if __name__ == '__main__':
    cli()

調用命令則有:

$ cli runserver
Serving on http://127.0.0.1:5000/

三、總結

本文首先介紹了命令的回調調用、上下文,再進一步介紹命令組的自定義、合併、鏈接、管道等功能,了解到了 click 的強大。而命令組中更加高階的能力()則可看官方文檔進一步了解。

我們通過介紹 click 的參數、選項和命令已經能夠完全實現命令行程序的所有功能。而 click 還為我們提供了許多錦上添花的功能,比如實用工具、參數自動補全等,我們將在下節詳細介紹。

『講解開源項目系列』——讓對開源項目感興趣的人不再畏懼、讓開源項目的發起者不再孤單。跟着我們的文章,你會發現編程的樂趣、使用和發現參与開源項目如此簡單。歡迎留言聯繫我們、加入我們,讓更多人愛上開源、貢獻開源~

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

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

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

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

Class文件結構全面解析(下)

接上回書

書接,分享了Class文件的主要構成,同時也詳細分析了魔數、次版本號、主版本號、常量池集合、訪問標誌的構造,接下來我們就繼續學習。

歡迎關注微信公眾號:萬貓學社,每周一分享Java技術乾貨。

類索引和父類索引

類索引(this_class)和父類索引(super_class)都是一個u2類型的數據,類索引用於確定這個類的全限定名,父類索引用於確定這個類的父類全限定名。由於java語言不允許多重繼承,所以父類索引只有一個。

類索引和父類索引各自指向常量池中類型為CONSTANT_Class_info的類描述符,再通過類描述符中的索引值找到常量池中類型為CONSTANT_Utf8_info的字符串。再來看一下之前的Class文件例子:

歡迎關注微信公眾號:萬貓學社,每周一分享Java技術乾貨。

結合之前javap分析出來的常量池內容:

   #3 = Class         #17        // OneMoreStudy
   #4 = Class         #18        // java/lang/Object
  #17 = Utf8          OneMoreStudy
  #18 = Utf8          java/lang/Object

類索引為0x0003,去常量池裡找索引為3的類描述符,類描述符中的索引為17,再去找索引為17的字符串,就是“OneMoreStudy”。

父類索引為0x0004,去常量池裡找索引為4的類描述符,類描述符中的索引為18,再去常量池裡找索引為18的字符串,就是“java/lang/Object”。

歡迎關注微信公眾號:萬貓學社,每周一分享Java技術乾貨。

接口索引集合

接口索引集合(interface)是一組u2類型的數據的集合,由於java語言允許實現多個接口,所以接口索引也有多個,它們按照implements語句后的接口順序從左到右依次排列在接口索引集合中。接口索引集合的第一項數據是接口集合計數值(interfaces_count),表示有多少接口索引。如果該類沒有實現任何接口,那麼該計數值為0,後面的接口索引表不佔任何字節。之前的例子OneMoreStudy類沒有實現任何接口,所以接口集合計數值就是0,如下圖:

歡迎關注微信公眾號:萬貓學社,每周一分享Java技術乾貨。

字段表集合

字段表(field_info)是用來描述接口或類中聲明的變量。包括類級變量(靜態變量)和實例級變量(成員變量),但是不包括在方法內部聲明的局部變量。具體結構如下錶:

類型 名稱 數量 描述
u2 access_flags 1 字段的訪問標誌
u2 name_index 1 字段的簡單名稱索引
u2 descriptor_index 1 字段的描述符索引
u2 attributes_count 1 字段的屬性計數值
attribute_info attributes attributes_count 字段的屬性

字段表中的access_flags,和類的access_flags是非常類似的,但是標識和含義是不一樣的。具體如下錶:

標誌名稱 標誌值 含義
ACC_PUBLIC 0x0001 字段是否public
ACC_PRIVATE 0x0002 字段是否private
ACC_PROTECTED 0x0004 字段是否protected
ACC_STATIC 0x0008 字段是否static
ACC_FINAL 0x0010 字段是否為final
ACC_VOLATILE 0x0040 字段是否volatile
ACC_TRANSIENT 0x0080 字段是否transient
ACC_SYNTHETIC 0x1000 字段是否由編譯器自動產生的
ACC_ENUM 0x4000 字段是否enum

歡迎關注微信公眾號:萬貓學社,每周一分享Java技術乾貨。

這裏提到了簡單名稱、描述符,和全限定名有什麼區別呢?稍微說一下。

簡單名稱是沒有類型和參數修飾的方法或字段名稱,比如OneMoreStudy類中的number字段和plusOne()方法的簡單名稱分別是“number”和“plusOne”。

全限定名是把類全名中的“.”替換成“/”就可以了,比如java.lang.Object類的全限定名就是“java/lang/Object”。

描述符是用來描述字段的數據類型、方法的參數列表(包括數量、類型以及順序)和返回值。基礎數據類型和無返回的void類型都有一個大寫字母表示,對象類型用字符L加對象的全限定名來表示,如下錶:

標識字符 含義
B 基本類型byte
C 基本類型char
D 基本類型double
F 基本類型float
I 基本類型int
J 基本類型long
S 基本類型short
Z 基本類型boolean
V 特殊類型void
L 對象類型 如 Ljava/lang/Object

對於數組類型,每一維度使用一個前置的“[”字符來描述,比如java.lang.Object[][]的二維數據,就是“[[Ljava/lang/Object”。在描述方法時,按照先參數列表,后返回值的順序描述,參數列表按照嚴格順序放在“()”值中,比如boolean equals(Object anObject),就是“(Ljava/lang/Object)B”。

歡迎關注微信公眾號:萬貓學社,每周一分享Java技術乾貨。

再來看一下之前的Class文件例子:

OneMoreStudy類中只有一個字段number,所以字段計數值為0x0001。字段number只被private修飾,沒有其他修飾,所以字段的訪問標誌位為0x0002。字段的簡單名稱索引是0x0005,去常量池中找索引為5的字符串,為“number”。字段的描述符索引為0x0006,去常量池中找索引為6的字符串,為“I”,是基本類型int。以下是常量池相關內容:

   #5 = Utf8          number
   #6 = Utf8          I

字段number的屬性計數值為0x0000,也就是沒有需要額外描述的信息。

字段表集合中不會列出從父類或者父接口中繼承而來的字段,但有可能列出原版Java代碼中沒有的字段,比如在內部類中為了保持對外部類的訪問性,會自動添加指向外部類實例的字段。

歡迎關注微信公眾號:萬貓學社,每周一分享Java技術乾貨。

方法表集合

方法表的結構和字段表的是一樣的,也是依次包括了訪問標誌(access_flags)、名稱索引(name_index)、描述符索引(descriptor_index)和屬性表集合(attributes)。具體如下錶:

類型 名稱 數量 描述
u2 access_flags 1 方法的訪問標誌
u2 name_index 1 方法的簡單名稱索引
u2 descriptor_index 1 方法的描述符索引
u2 attributes_count 1 方法的屬性計數值
attribute_info attributes attributes_count 方法的屬性

對於方法的訪問標誌,所有標誌位和取值如下錶:

標誌名稱 標誌值 含義
ACC_PUBLIC 0x0001 方法是否public
ACC_PRIVATE 0x0002 方法是否private
ACC_PROTECTED 0x0004 方法是否protected
ACC_STATIC 0x0008 方法是否static
ACC_FINAL 0x0010 方法是否為final
ACC_SYNCHRONIZED 0x0020 方法是否sychronized
ACC_BRIDGE 0x0040 方法是否是由編譯器產生的橋接方法
ACC_VARARGS 0x0080 方法是否接受不定參數
ACC_NATIVE 0x0100 方法是否為native
ACC_ABSTRACT 0x0400 方法是否為abstract
ACC_STRICT 0x0800 方法是否為strictfp
ACC_SYNTHETIC 0x1000 方法是否由編譯器自動產生

方法中的Java代碼,經過編譯器編程成字節碼指令后,放在方法屬性表集合中一個名為“Code”的屬性里,後面會有更多分享。

歡迎關注微信公眾號:萬貓學社,每周一分享Java技術乾貨。

再來看一下之前的Class文件例子:

方法計算值為0x0003,表示集合中有兩個方法(編譯器自動添加的無參構造方法和源碼中的plusOne方法)。第一個方法的訪問標誌是0x0001,表示只有ACC_PUBLIC標誌為true。

名稱索引為0x0007,在常量池中為索引為7的字符串為“ ”,這就是編譯器自動添加的無參構造方法。描述符索引為0x0008,在常量池中為索引為7的字符串為“()V”,方法的屬性計數值為0x0001,表示該方法有1個屬性,屬性名稱索引為0x0009,在常量池中為索引為7的字符串為“Code”。以下是常量池相關內容:

   #7 = Utf8          <init>
   #8 = Utf8          ()V
   #9 = Utf8          Code

歡迎關注微信公眾號:萬貓學社,每周一分享Java技術乾貨。

屬性表集合

屬性表(attribute_info)在前面的分享中出現了幾次,在Class文件、字段表、方法表都可以有自己的屬性表集合,用來描述某些場景下特有的信息。

屬性表不在要求具有嚴格的順序,並且只要不與已有的屬性名重複,任何人實現的編譯器都可以寫入自己定義的屬性信息,Java虛擬機在運行時會忽略掉它不認識的屬性。

我總結了一些比較常見的屬性,如下錶:

屬性名稱 使用位置 含義
Code 方法表 Java代碼編譯成的字節碼指令
ConstantValue 字段表 final關鍵字定義的常量值
Exceptions 方法表 方法拋出的異常
InnerClasses 類文件 內部類列表
LineNumberTable Code屬性 Java源碼的行號與字節碼指定的對應關係
LocalVariableTable Code屬性 方法的局部變量描述
SourceFile 類文件 記錄源文件名稱

對於每個屬性,它的名稱都從常量池中引用一個CONSTANT_Utf8_info類型的常量,而屬性值的結構則是完全自定義的,只需要用一個u4類型來說明屬性值所佔的位數就可以了。具體結構如下:

類型 名稱 數量 含義
u2 attribute_name_index 1 屬性名稱索引
u2 attribute_length 1 屬性值所佔的位數
u1 info attribute_length 屬性值

歡迎關注微信公眾號:萬貓學社,每周一分享Java技術乾貨。

總結

Class文件主要由魔數、次版本號、主版本號、常量池集合、訪問標誌、類索引、父類索引、接口索引集合、字段表集合、方法表集合和屬性表集合組成。隨着JDK版本的不斷升級,Class文件結構也在不斷更新,學習之路,永不止步。

歡迎關注微信公眾號:萬貓學社,每周一分享Java技術乾貨。

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

收購3c,收購IPHONE,收購蘋果電腦-詳細收購流程一覽表

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

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

※公開收購3c價格,不怕被賤賣!

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

OpenJS基金會推出Node.js證書,JS開發者可以“考證”了

  OpenJS 基金會近日在其官方博客公布了最新啟動的專業認證計劃。據介紹,此項認證計劃重點關注 Node.js 開發者在專業環境中構建 Node.js 應用和服務所需的關鍵技能。

  開發者通過認證后,可獲得由 OpenJS 基金會頒發和認證的證書,證書有效期為三年,其中包括 PDF 證書和数字徽章,到期后可重新認證。

  正如上面提到的,此項認證主要是考查開發者構建 Node.js 應用和服務所需的關鍵技能,所以 OpenJS 基金會也推出了兩個證書來對這兩種技能進行認證,這兩個證書分別為 OpenJS Node.js 應用開發者證書和 OpenJS Node.js 服務開發者證書。

  據官方介紹,OpenJS Node.js 應用開發者 (JSNAD) 證書非常適合具有至少兩年 Node.js 使用經驗的開發者,有關報名或其他更多信息請點擊這裏進行了解。OpenJS Node.js 服務開發者 (JSNSD) 證書則更適合具有使用 Node.js 創建 RESTful 服務器以及服務的經驗。詳情請點此了解。

  另外,兩項考試的時長都為兩個小時,開發者通過基於瀏覽器的終端進行考試,如果有需要,每項考試都支持自動免費重考。考試現場會有監督員進行監督,並以英文的方式在線進行。

  OpenJS 基金會執行董事 Robin Ginn 表示:“ OpenJS Node.js 專業認證計劃旨在幫助開發者展示其在現實環境中的 Node.js 水平,併為他們提供將這些技術引入各自組織的知識。認證考試不僅僅是一種與供應商無關的考查方式,它還提供了一個由 Node.js 社區的專業從業者開發的框架,此框架還為經驗豐富的開發者闡述清楚關於 Node.js 的各種技能。”

  關於 OpenJS 基金會 

  OpenJS 基金會的使命是通過提供一个中立的組織來託管項目並協作資助有益於整個生態系統的活動,從而促進 JavaScript 和 Web 生態系統的健康發展。

  OpenJS 基金會由 32 個開源 JavaScript 項目組成,其中包括 Appium,Dojo,jQuery,Node.js 和 Webpack,並得到 30 個企業和最終用戶成員的支持,其中包括 GoDaddy,Google,IBM,Intel,Joyent 和 Microsoft。

  這些成員清楚地認識到 JavaScript 生態系統所具備的相互聯繫的性質,以及為代表重要共享價值的項目提供中心位置的重要性。 

 

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

收購3c,收購IPHONE,收購蘋果電腦-詳細收購流程一覽表

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

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

※公開收購3c價格,不怕被賤賣!

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

中子星合併產生的重元素鍶首次被確認

  科技日報記者 劉霞

  2017 年,科學家首次探測到兩顆中子星合併產生的引力波,引發科學界一片狂歡,但故事並沒有結束!研究人員在最新一期《自然》雜誌撰文稱,他們對這次合併產生的數據進行重新分析,首次確認重元素鍶來自於這場合併。證實宇宙中較重的元素可以在中子星合併中產生。

  據物理學家組織網 24 日報道,2017 年,在探測到中子星合併產生的引力波后,歐洲南方天文台將包括甚大望遠鏡(VLT)在內的多個望遠鏡指向了震源:名為“GW170817”的中子星合併事件。天文學家們懷疑,如果在中子星碰撞中確實形成了更重的元素,這些元素的“蛛絲馬跡”會在合併產生的爆炸殘骸——巨新星內“現形”。現在,他們藉助 VLT 上的X-shooter 光譜儀首次證實了這一點。

  自上世紀 50 年代以來,天文學家一直在研究製造元素的物理過程。幾十年內,除了“漏網之魚”鍶之外,他們發現了每個主要放射性元素在太空中形成的位置:普通恆星、超新星爆發、古老恆星的外層等,但一直未曾發現創造出更重元素的過程——快速中子捕獲的發生位置。

  在快速中子捕獲過程中,原子核足夠快地捕獲中子,使極重元素被製造出來。儘管許多元素是在恆星的內核產生的,但要製造出比鐵更重的元素(比如鍶),則需要擁有更多自由中子的更高溫環境。快速中子捕獲僅在原子被大量中子轟擊的極端環境中發生。

  研究主要作者、丹麥哥本哈根大學的達拉赫·沃森說:“通過重新分析 2017 年合併后的數據,我們確定了鍶的特徵,證明了中子星合併在宇宙中創造了這一元素。”在地球上,鍶存在於土壤中,並集中於某些礦物質中,鍶鹽可使煙花呈現出絢爛的紅色。

  馬克斯·普朗克天文學研究所的卡米拉·朱爾·漢森表示:“這是我們首次將通過中子捕獲形成的新物質與中子星合併直接聯繫在一起,證實了中子星由中子構成,並將快速中子捕獲過程與這種合併聯繫在一起。”

  GW170817 事件是對引力波的第五次證明,“幕後功臣”是美國的激光干涉儀引力波天文台(LIGO)和意大利的“室女座”引力波干涉儀。這次合併發生於星系 NGC 4993 中,是第一個、也是迄今唯一一個被地球上的望遠鏡探測到的引力波源。

  研究人員稱,最新研究表明,藉助 LIGO、“室女座”和 VLT,我們對中子星的內部運作及其爆炸性合併有最清晰的了解。

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

收購3c,收購IPHONE,收購蘋果電腦-詳細收購流程一覽表

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

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

※公開收購3c價格,不怕被賤賣!

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

古老!八千年前珍珠被發現

  科技日報訊 (記者劉霞)據美國趣味科學網站 24 日報道,考古學家在阿布扎比海岸附近的馬拉瓦島上發現了一顆古老的天然珍珠,他們表示,這是迄今世界上最古老的天然珍珠,這顆珍珠可以追溯到 8000 年前的新石器時代,表明在那個時候珍珠貿易就已經存在。

  這顆古老的天然珍珠被稱為“阿布扎比珍珠”(Abu Dhabi Pearl),顏色為誘人的淡粉色,長約 0.3 厘米。阿布扎比文化與旅遊部的一份聲明稱,這顆珍珠在新石器時代遺址的一層中發現,這一遺址可追溯到公元前 5800 年到公元前 5600 年,這一珍珠因此也成為迄今世界上最古老的珍珠。

  阿布扎比文化和旅遊部考古調查處所長阿卜杜拉·哈爾凡·阿爾-卡比亞比在該部門官方推特帳戶上發布的視頻中說:“考古遺址中存在珍珠,這證明珍珠貿易至少可以追溯到新石器時代。”

  新石器時代是考古學家設定的一個時間區段,大約從一萬多年前開始,結束時間從距今 5000 多年至 2000 多年。

  該新石器時代遺址由坍塌的石頭結構組成,最早於 1992 年發現。考古學家們也在那裡發現了許多人工製品,包括燧石箭頭、珠子和陶瓷等。此外,由於此地點位於一個島上,因此發現的許多文物,例如魚、烏龜、海豚、海牛和牡蠣的骨頭等,都與大海有關。阿爾-卡比亞比說:“這個時期的人們對大海非常熟悉,並認為大海已經成為他們日常生活的重要組成部分。”

  該聲明說,甚至在幾個世紀之後,在上世紀 30 年代之前,潜水捕撈珍珠一直是該地區的重要活動,是阿拉伯聯合酋長國重要的經濟推動力。

  據悉,這顆“阿布扎比珍珠”將在盧浮宮阿布扎比博物館即將舉行的名為“一萬年的奢侈品”展覽中首次展出。

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

收購3c,收購IPHONE,收購蘋果電腦-詳細收購流程一覽表

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

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

※公開收購3c價格,不怕被賤賣!

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