互聯(lián)網(wǎng)圈有這么一句話:百度的技術(shù)噪叙,阿里的運(yùn)營(yíng),騰訊的產(chǎn)品霉翔。那么代表互聯(lián)網(wǎng)三座大山的BAT睁蕾,內(nèi)部人才體系有什么區(qū)別呢?今天小編就帶領(lǐng)大家看一看~
★ 騰訊 ★
1. 職級(jí)
騰訊職級(jí)體系分6級(jí)债朵,最低1級(jí)子眶,最高6級(jí)。同時(shí)按照崗位又劃分為四大通道序芦,內(nèi)部也叫“族”臭杰,比如:
產(chǎn)品/項(xiàng)目通道,簡(jiǎn)稱P族
技術(shù)通道谚中,簡(jiǎn)稱T族
市場(chǎng)通道渴杆,簡(jiǎn)稱M族
職能通道,簡(jiǎn)稱S族
以T族為例宪塔,分別為:
T1:助理工程師 (一般為校招新人)
T2:工程師
T3:高級(jí)工程師 3-1相當(dāng)于阿里的p6 到p7(能力強(qiáng)可能到p7)
T4:專家工程師
T5:科學(xué)家
T6:首席科學(xué)家
目前全騰訊貌似就一個(gè)T6磁奖。
每一級(jí)之間又分為3個(gè)子級(jí),3-1是任命組長(zhǎng)/副組長(zhǎng)的必要條件蝌麸,其他線也是這樣点寥。T4基本為總監(jiān)級(jí),也不排除有T3-3的總監(jiān)来吩,因?yàn)門(mén)4非常難晉級(jí)敢辩。
2. 晉升
騰訊的晉級(jí)還是很困難的。尤其是T2 升T3弟疆,T3升T4戚长。非常多的人卡在2-3,3-3沒(méi)辦法晉級(jí)。有的小伙伴做了3怠苔、4年的2-3 也升不上去啊同廉。
3. 薪水
騰訊薪資架構(gòu):12 1 1=14薪
年終獎(jiǎng):看部門(mén)盈利情況,一般是3個(gè)月
級(jí)別越高base薪酬也越高,一年根據(jù)你的performance大概能發(fā)15.3個(gè)月至18個(gè)月的工資迫肖,T3.1的base 2w 锅劝,T3以上級(jí)別的員工都會(huì)有股票期權(quán),騰訊09以前的員工賺錢(qián)主要靠股票蟆湖,從08到現(xiàn)在股票up了500% 故爵,T5 的base薪酬在600w~800w/年。
4.人才
人才流動(dòng)的可能:
在深圳:很多騰訊員工都買(mǎi)了房隅津,當(dāng)你的房子诬垂,妻子的工作,兒子的學(xué)校伦仍,你的朋友圈结窘,都在一個(gè)城市的時(shí)候,換城市就有困難了充蓝。所以只能挖一些比較淺的人走隧枫。
在北京:人數(shù)不少 ,不過(guò)骨干員工不多棺克。騰訊視頻的主要團(tuán)隊(duì)在北京的倒是不少悠垛。
在成都线定、大連:在這些二線城市娜谊,騰訊就是當(dāng)?shù)刈詈玫幕ヂ?lián)網(wǎng)公司了,提供的待遇也是非常高的斤讥,不少人都對(duì)自己的薪資比較滿意纱皆,工作環(huán)境也很滿意。跳槽的可能性低了很多芭商。
人才結(jié)構(gòu):
騰訊的研發(fā)序列碩士學(xué)歷的占多度派草,211大學(xué),985大學(xué)占多數(shù)铛楣。大家都知道騰訊研究院解散了近迁。去年走出來(lái)很多人,騰訊人才創(chuàng)業(yè)比例不高簸州。
在騰訊最常碰到的晉升問(wèn)題就是天花板鉴竭。可能新人進(jìn)去岸浑,學(xué)東西會(huì)很多搏存,但業(yè)務(wù)線就這些,沒(méi)有那么多坑矢洲,自然也就很難晉升高級(jí)崗璧眠。
在騰訊最悲劇的時(shí)刻就是公司有收購(gòu)和整合。搜狗合并,搜搜的人哭了责静,京東合作袁滥,易迅的人哭了。在騰訊跳出來(lái)碰到最大的問(wèn)題就是灾螃,外面的公司太不完善了呻拌。
★ 阿里巴巴 ★
1. 層級(jí)
阿里的職稱大部分都?xì)w納在P序列 ,你的title 工種。比如P7產(chǎn)品經(jīng)理=產(chǎn)品專家睦焕。
一般到P3為助理
P4=專員
P5=資深專員
P6=高級(jí)專員(也可能是高級(jí)資深)
P7=專家
P8=資深專家(架構(gòu)師)
P9=高級(jí)專家(資深架構(gòu)師)
P10=研究員
P11=高級(jí)研究員
P12=科學(xué)家
P13=首席科學(xué)家
P14=馬云
同時(shí)對(duì)應(yīng)P級(jí)還有一套管理層的機(jī)制在:
M1=P6 主管
M2=P7 經(jīng)理
M3=P8 資深經(jīng)理
M4 =P9 總監(jiān)
M5= P10 資深總監(jiān)
M6 =P11 副總裁
M7=P12 資深副總裁
M8=P13 子公司CEO 或集團(tuán)其他O
M9=P14 陸兆禧(前馬云)
在阿里早些時(shí)候P級(jí)普遍偏低藐握,專員可能是P2這樣,后來(lái)有了一次P級(jí)通貨膨脹垃喊,出現(xiàn)了更多的P級(jí)猾普。在阿里只有P6(M1)后才算是公司的中層。不同的子公司給出P級(jí)的標(biāo)準(zhǔn)不一樣本谜。
比如:B2B的普遍P級(jí)較高初家,但是薪資水平低于天貓子公司的同級(jí)人員。同時(shí)到達(dá)該P(yáng)級(jí)員工才有享受公司RSU的機(jī)會(huì)乌助。(低于P6的除非項(xiàng)目出色有RSU獎(jiǎng)勵(lì)溜在,否則1股都拿不到)
2.晉升
晉升很簡(jiǎn)單:
1. 晉升資格:上年度KPI達(dá)3.75。
2. 主管提名他托。一般KPI不達(dá)3.75主管不會(huì)提名掖肋。
3. 晉升委員會(huì)面試。(晉升委員會(huì)組成一般是合作方業(yè)務(wù)部門(mén)大佬赏参、HRG志笼、該業(yè)務(wù)線大佬等。)
4. 晉升委員會(huì)投票把篓。
P5升P6相對(duì)容易纫溃,再往上會(huì)越來(lái)越難,一般到P7都是團(tuán)隊(duì)技術(shù)leader了韧掩,P6到P7非常難紊浩,從員工到管理的那一步跨出去不容易,當(dāng)然有同學(xué)說(shuō)P一般都是專家疗锐,M才是管理坊谁,actually,專家線/管理線有時(shí)并不是分的那么清楚的窒悔。
3. 薪水
? 阿里薪資結(jié)構(gòu):一般是12 1 3=16薪
? 年底的獎(jiǎng)金為0-6個(gè)月薪資呜袁,90%人可拿到3個(gè)月
? 股票是工作滿2年才能拿,第一次拿50%简珠,4年能全部拿完
★ 百度 ★
1. 層級(jí)
百度的級(jí)別架構(gòu)分成四條線阶界。
技術(shù)序列 T:T3 - T11 (一般對(duì)應(yīng)阿里高一級(jí)序列虹钮,如:百度T3=阿里P4,T5/T6屬于部門(mén)骨干膘融,非常搶手芙粱,人人獵中相當(dāng)一部分offer人選都來(lái)自這個(gè)序列)
產(chǎn)品運(yùn)營(yíng)序列 P:p3-P11 (產(chǎn)品和運(yùn)營(yíng)崗,對(duì)應(yīng)阿里高1-1.5級(jí)序列 百度p3=阿里P4-P5之間)
后勤支持部門(mén) S :S3-S11 (主要是公共氧映、行政春畔、渠道等等,晉升比較困難)
管理序列 M:M1-M5 (每一級(jí)又分為2個(gè)子級(jí) M1A岛都、M1B , 最低的是M1A律姨,至少是部門(mén)二把手了,李明遠(yuǎn)是M3.2臼疫,以前的湯和松都是這個(gè)級(jí)別择份,李彥宏是唯一的M5,其實(shí)從M3開(kāi)始就有機(jī)會(huì)加入E——star烫堤,類似于阿里的合伙人會(huì)議荣赶,屬于最高戰(zhàn)略決策層。
2. 薪資
月薪14.6(12 0.6 2),其他崗位:月薪14
T5以上為關(guān)鍵崗位鸽斟,另外有股票拔创、期權(quán)。T5富蓄、T6占比最大的級(jí)別剩燥,T8、T9占比最小格粪,級(jí)別越高躏吊,每檔之間的寬幅越大氛改。
3. 晉升
基本上應(yīng)屆畢業(yè)生應(yīng)該是T3帐萎,但是內(nèi)部晉升非常激烈。公司那么大胜卤,部門(mén)和部門(mén)之間有業(yè)務(wù)競(jìng)爭(zhēng)疆导,肯定也有人才競(jìng)爭(zhēng)。
通常應(yīng)屆畢業(yè)生入職1年多能升到T4葛躏,但如果你的部門(mén)業(yè)務(wù)足夠核心澈段,或許1年就可以了。3年升T5舰攒。從目前百度的情況來(lái)看败富,核心工程師集中在T5/6,但是從5/6到7是非常艱難的過(guò)程摩窃。
百度是很唯KPI至上的兽叮,其次部門(mén)很核心芬骄,再次老大話語(yǔ)權(quán)比較高,相對(duì)晉升容易些鹦聪。
一般情況分2種:
1. 自己提名账阻,當(dāng)你自己覺(jué)得已經(jīng)具備下一level的素質(zhì),可以自己提名泽本,提名后進(jìn)入考察期淘太,主管設(shè)定考察期目標(biāo),考察通過(guò)順利晉升规丽,考察不通過(guò)維持原層級(jí)不變蒲牧;
2. 主管提名,如果是主管提名赌莺,一般都是直接通過(guò)的造成,但是如果你現(xiàn)層級(jí)已經(jīng)比較高了,那就不是直接提名這么簡(jiǎn)單了雄嚣。
P.S.如果你能升到T7晒屎,基本上是TL的級(jí)別,寫(xiě)代碼/直接做業(yè)務(wù)的時(shí)間就很少了缓升。
思考
看了以上BAT三家巨頭公司人才體系的職位層級(jí)鼓鲁、薪酬、晉升標(biāo)準(zhǔn)港谊,你是否有被觸動(dòng)或者震撼呢骇吭?
終身成長(zhǎng)詞典詞條《464:花盆效應(yīng)》中提到:
心理學(xué)上有這樣一個(gè)詞,叫“花盆效應(yīng)”歧寺,指的是人如果在舒適的“花盆”中待久了燥狰,就會(huì)不思進(jìn)取、安于現(xiàn)狀斜筐。當(dāng)你對(duì)現(xiàn)狀心滿意足龙致,日復(fù)一日地去做著同樣的事情,不再將時(shí)間花在提升自己顷链,那么你的成長(zhǎng)見(jiàn)識(shí)目代,將永遠(yuǎn)停留在原來(lái)的那塊區(qū)域里。
曾看到這樣一句話:一個(gè)人老去的標(biāo)志嗤练,絕不是老成穩(wěn)重榛了、沉默寡言,而是不肯再嘗試煞抬,不肯再容許自己置身不熟悉的境地霜大。當(dāng)你停止了學(xué)習(xí)、固步自封革答,將自己囚禁在得過(guò)且過(guò)的牢籠中战坤,那么你已經(jīng)朝平庸邁進(jìn)了一大步遮婶。
想要了解架構(gòu)技術(shù)知識(shí)點(diǎn)的,可以關(guān)注我一下湖笨,我后續(xù)也會(huì)整理更多關(guān)于分布式架構(gòu)這一塊的知識(shí)點(diǎn)分享出來(lái)旗扑,另外順便給大家推薦一個(gè)交流學(xué)習(xí)群:650385180,里面會(huì)分享一些資深架構(gòu)師錄制的視頻錄像:有Spring慈省,MyBatis臀防,Netty源碼分析,高并發(fā)边败、高性能袱衷、分布式、微服務(wù)架構(gòu)的原理笑窜,JVM性能優(yōu)化這些成為架構(gòu)師必備的知識(shí)體系负懦。還能領(lǐng)取免費(fèi)的學(xué)習(xí)資源识补,目前受益良多送淆,以下的知識(shí)體系圖也是在群里獲取挠蛉。
并發(fā)編程
分布式
開(kāi)發(fā)工具
性能調(diào)優(yōu)
微服務(wù)架構(gòu)
源碼分析
總結(jié)
希望我分享出來(lái)的這些知識(shí)點(diǎn)可以幫助在這個(gè)行業(yè)發(fā)展的朋友和童鞋們,在論壇博客等地方少花些時(shí)間找資料断傲,把有限的時(shí)間脱吱,真正花在學(xué)習(xí)上,我把這些視頻分享出來(lái)认罩。相信對(duì)于已經(jīng)工作和遇到技術(shù)瓶頸的碼友箱蝠,在這個(gè)群里一定有你需要的內(nèi)容。
目標(biāo)已經(jīng)有了垦垂,下面就看行動(dòng)了宦搬!記住:學(xué)習(xí)永遠(yuǎn)是自己的事情劫拗,你不學(xué)時(shí)間也不會(huì)多间校,你學(xué)了有時(shí)候卻能夠使用自己學(xué)到的知識(shí)換得更多自由自在的美好時(shí)光!時(shí)間是生命的基本組成部分杨幼,也是萬(wàn)物存在的根本尺度撇簿,我們的時(shí)間在那里我們的生活就在那里!我們價(jià)值也將在那里提升或消弭差购!
Protocol buffer JSON XML
簡(jiǎn)介
Protocol Buffers(也稱protobuf)是Google公司出口的一種獨(dú)立于開(kāi)發(fā)語(yǔ)言,獨(dú)立于平臺(tái)的可擴(kuò)展的結(jié)構(gòu)化數(shù)據(jù)序列機(jī)制汉嗽。通俗點(diǎn)來(lái)講它跟xml和json是一類欲逃。是一種數(shù)據(jù)交互格式協(xié)議。
網(wǎng)上有很多它的介紹饼暑,主要優(yōu)點(diǎn)是它是基于二進(jìn)制的稳析,所以比起結(jié)構(gòu)化的xml協(xié)議來(lái)說(shuō)洗做,它的體積很少,數(shù)據(jù)在傳輸過(guò)程中會(huì)更快彰居。另外它也支持c++诚纸、java、python陈惰、php畦徘、javascript等主流開(kāi)發(fā)語(yǔ)言。
更多信息抬闯,你可以在這個(gè)它的官方網(wǎng)站查閱相關(guān)的資料
Protocol編譯安裝
protocol的編譯器是C語(yǔ)言編寫(xiě)的井辆,如果你正在使用c++開(kāi)發(fā),請(qǐng)根據(jù)c++安裝引導(dǎo)進(jìn)行安裝溶握。
對(duì)于不是c++語(yǔ)言的開(kāi)發(fā)者而言杯缺,最簡(jiǎn)單的方式就是從下面的網(wǎng)站下載一個(gè)預(yù)編譯的二進(jìn)制文件。
https://github.com/google/protobuf/releases
在上面的鏈接中睡榆,你可以按照對(duì)應(yīng)的平臺(tái)下載zip包:protoc-<nobr aria-hidden="true" style="box-sizing: border-box; outline: 0px; transition: none; border: 0px; padding: 0px; margin: 0px; max-width: none; max-height: none; min-width: 0px; min-height: 0px; vertical-align: 0px; line-height: normal; text-decoration: none; white-space: nowrap !important; word-break: break-all;">VERSION?</nobr><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>V</mi><mi>E</mi><mi>R</mi><mi>S</mi><mi>I</mi><mi>O</mi><mi>N</mi><mo>?</mo></math>PLATFORM.zip. 如protobuf-java-3.1.0.zip
如果你要尋找之前的版本萍肆,通過(guò)下面的maven庫(kù):
http://repo1.maven.org/maven2/com/google/protobuf/protoc/
因?yàn)槲抑饕胘ava開(kāi)發(fā)應(yīng)用,所以這篇文章重點(diǎn)講解protocol的java實(shí)現(xiàn)胀屿。 還有這是在windows上操作匾鸥。
Protocol buffer的安裝
1 通過(guò)Maven方式安裝
如果你機(jī)器上還沒(méi)有安裝maven.請(qǐng)到下面的網(wǎng)站安裝
http://maven.apache.org/
選擇相應(yīng)的包。我這里選擇的是apache-maven-3.3.9-bin.zip.
添加maven到path
將下載后的bin目錄添加到path中碉纳。
然后用mvn -version測(cè)試一下
C:\Users\xx-xxx>mvn -version
Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-11T00:41:4
7+08:00)
Maven home: E:\xxxxxx\apache-maven-3.3.9-bin\apache-maven-3.3.9\bin\..
Java version: 1.7.0_09, vendor: Oracle Corporation
Java home: C:\Program Files\Java\jdk1.7.0_09\jre
Default locale: zh_CN, platform encoding: GBK
OS name: "windows 7", version: "6.1", arch: "amd64", family: "windows"
說(shuō)明安裝成功
安裝protoc
從https://github.com/google/protobuf/releases下載protoc勿负,如protoc-3.1.0-win32.zip,然后解壓然后添加到path.
在命令行中測(cè)試
protoc --version
正常情況應(yīng)該打印版本信息劳曹,說(shuō)明添加成功奴愉。
將protoc復(fù)制到protocol buffer解壓的目錄。
這一步很重要铁孵。
例如之前下載的protobuf-java-3.1.0.zip我將它解壓在E盤(pán)
E:\xxxx\protobuf-java-3.1.0
,那么E:\xxxx\protobuf-java-3.1.0\protobuf-3.1.0
這個(gè)目錄就當(dāng)它是根目錄锭硼。我用$ROOT表示。
將protoc.exe文件復(fù)制到$ROOT/src/
目錄下蜕劝。
然后在命令行中定位到$ROOT/java/
檀头,
然后運(yùn)行命令mvn package
,
如果一切成功的話,就會(huì)在$ROOT/java/core/target/
目錄下生成protobuf-java-3.1.0.jar文件岖沛。
編譯代碼
在下載的protobuf-java-3.1.0.zip解壓后暑始,我們定義它的根目錄為$ROOT。它下面有一個(gè)examples文件夾婴削,里面有個(gè)adressbook.proto文件廊镜,.proto就是protocol buffer的文件格式后綴。
我們將之前生成的protobuf-java-3.1.0.jar復(fù)制到該目錄下唉俗。然后執(zhí)行下面的命令
protoc --java_out=. addressbook.proto
它就會(huì)自動(dòng)生成com/example/tutorial/AddressBookProtos.java文件嗤朴。
自此配椭,protoc buffer就完全編譯成功,并且能正常運(yùn)行了雹姊。
接下來(lái)我講解它的基本語(yǔ)法
語(yǔ)法
在Android開(kāi)發(fā)中股缸,json運(yùn)用的很廣泛,gson類可以直接將一個(gè)java類對(duì)象直接序列成json格式的字符串吱雏。
在protocol buffer中同樣有類似功能的結(jié)構(gòu)敦姻。
比如我要定義一個(gè)學(xué)生類,它包含學(xué)號(hào)坎背、姓名替劈、性別必要信息,也有興趣愛(ài)好得滤、特長(zhǎng)等必要信息陨献。
如果用java的話。大概如下面
class Student{
int number;
String name;
int sex;
String hobby;
String skill;
}
那么如果用Protocol buffer來(lái)定義呢懂更?
這里有一個(gè)關(guān)鍵字message眨业。message是消息的意思,等同于java中的class關(guān)鍵字和c中的struct沮协,代表一段數(shù)據(jù)的封裝龄捡。
簡(jiǎn)單示例
首先我們得創(chuàng)建.proto文件。這里為Student.proto
syntax = "proto3";
message Student
{
int32 number = 1;
string name = 2;
int32 sex = 3;
string hobby = 4;
string skill = 5;
}
syntax=”proto3”表示運(yùn)用proto3的語(yǔ)法慷暂。而網(wǎng)上的教程大多還是proto2聘殖。
proto3提示required限制符不能起作用,默認(rèn)的就是optional行瑞,表示任何域都是可選的奸腺。
那好,我們參加教程前面部分將.proto文件轉(zhuǎn)換成.java文件血久。
protoc --java_out=. Student.proto
結(jié)果在當(dāng)前目錄生成了StudentOuterClass.java文件突照。至于為什么是StudentOuterClass.java這是因?yàn)槲覀冊(cè)赟tudent.proto沒(méi)有指定它編譯后生成的文件名稱,protoc程序默認(rèn)生成了StudentOuterClass.java氧吐,其實(shí)這個(gè)名字我們可以自定義讹蘑,文章后面的內(nèi)容我會(huì)介紹。
序列化
在IDE中新建項(xiàng)目筑舅,然后添加StudentOuterClass.java文件座慰,并且添加protobuf-java-3.1.0.jar。
然后編寫(xiě)如下代碼:
Student.Builder buidler = Student.newBuilder();
buidler.setName("Frank");
buidler.setNumber(123456);
buidler.setHobby("music");
Student student = buidler.build();
System.out.println(student.toString());
最終代碼會(huì)在運(yùn)行時(shí)打印如下信息:
I/System.out: number: 123456
I/System.out: name: "Frank"
I/System.out: hobby: "music"
說(shuō)明從.proto中的message到j(luò)ava中的class轉(zhuǎn)換已經(jīng)成功豁翎。
最后
student.toByteArray();
這個(gè)方法會(huì)得到byte[]角骤,我們可以將它送到文件流中進(jìn)行傳輸,這也是它的終極目的心剥。也就是我們將protoc對(duì)象序列化成了字節(jié)流數(shù)據(jù)邦尊。
大家注意這個(gè)toByteArray()產(chǎn)生的byte[]數(shù)組,它代表要全部傳輸?shù)亩M(jìn)制數(shù)據(jù)优烧,大家可以打印它的大小蝉揍,有心人可以用json實(shí)現(xiàn)兩樣的信息,然后打印json序列化后的數(shù)據(jù)長(zhǎng)度做比較畦娄∮终矗看看,protocol buffre是不是更節(jié)省內(nèi)存空間熙卡,但在這里杖刷,我不做過(guò)多探究。
那么如何將字節(jié)流數(shù)據(jù)反序列化成protoc對(duì)象呢驳癌?
反序列化
我們可以這樣
byte[] array = student.toByteArray();
try {
Student student1 = Student.parseFrom(array);
System.out.println(student1.toString());
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
}
array是之前序列化后產(chǎn)生的byte數(shù)據(jù)滑燃,現(xiàn)在通過(guò)Student的靜態(tài)方法parseFrom()可以數(shù)據(jù)反序列成Student對(duì)象。
現(xiàn)在想來(lái)這個(gè)是不是很簡(jiǎn)單颓鲜?表窘??
除了開(kāi)始的階段編寫(xiě).proto文件甜滨,然后再把.proto文件編譯成java文件麻煩點(diǎn)乐严,其余的步驟甚至比json轉(zhuǎn)換的更便利。
message
上一節(jié)已經(jīng)見(jiàn)識(shí)過(guò)了message衣摩,它等同于java中的class關(guān)鍵字和c中的struct關(guān)鍵字昂验。
message Student
{
}
限定符
在proto2.0版本中有三個(gè)限定符
- required 必要的域
- optional 可選的
- repeated 可重復(fù)的(0~N)
其中被required修飾的變量是必不可少的。
optional可有可無(wú)艾扮。
repeated修飾的就要是數(shù)組字段既琴。
而在proto3.0中required被刪掉了。optional字符也不能使用栏渺,因?yàn)槟J(rèn)的域都是optional屬性呛梆。
3.0新語(yǔ)法
syntax = "proto3";
或者
syntax="proto2";
這個(gè)寫(xiě)在.proto文件中,用來(lái)指定使用proto3語(yǔ)法還是使用proto2語(yǔ)法磕诊。目前protobuffer繼續(xù)支持proto2
數(shù)據(jù)類型
我們?cè)谇懊娴膬?nèi)容中見(jiàn)到了int32這樣的字眼填物,它其實(shí)是數(shù)據(jù)類型。
protoc類型 | java類型 | c++類型 |
---|---|---|
double | double | double |
float | float | float |
int32 | int | int32 |
int64 | long | int64 |
uint32 | int | uint32 |
uint64 | long | uint64 |
sint32 | int | int32 |
sint64 | long | int64 |
fixed32 | int | uint32 |
fixed64 | long | uint64 |
sfixed32 | int | uint32 |
sfixed64 | long | uint64 |
bool | boolean | bool |
string | String | string |
bytes | ByteString | string |
最常用的就是float霎终、int32滞磺、bool string bytes。
枚舉
protocol buffer除了支持上面的基本類型外還支持枚舉莱褒。
關(guān)鍵字是enum
比如我們可以將前文提到的Student對(duì)象中的性別用一個(gè)枚舉代替击困。
那么將Student.proto文件修改如下:
syntax = "proto3";
enum Sex
{
MALE = 0;
FEMALE = 1;
}
message Student
{
int32 number = 1;
string name = 2;
Sex sex = 3;
string hobby = 4;
string skill = 5;
}
然后再用protoc.exe編譯產(chǎn)生新的java文件,并添加到工程當(dāng)中。再進(jìn)行代碼測(cè)試阅茶。
Student.Builder buidler = Student.newBuilder();
buidler.setName("Frank");
buidler.setNumber(123456);
buidler.setHobby("music");
//已經(jīng)可以設(shè)置Sex屬性了
buidler.setSex(Sex.MALE);
Student student = buidler.build();
System.out.println(student.toString());
byte[] array = student.toByteArray();
try {
Student student1 = Student.parseFrom(array);
System.out.println(student1.toString());
//在這里打印性別的值
System.out.println(student1.getSex().toString());
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
}
在上面代碼中有這兩句
//設(shè)置性別
buidler.setSex(Sex.MALE);
//打印性別
System.out.println(student1.getSex().toString());
然后打印的結(jié)果如下:
com.frank.protocdemo I/System.out: number: 123456
com.frank.protocdemo I/System.out: name: "Frank"
com.frank.protocdemo I/System.out: hobby: "music"
com.frank.protocdemo I/System.out: number: 123456
com.frank.protocdemo I/System.out: name: "Frank"
com.frank.protocdemo I/System.out: hobby: "music"
com.frank.protocdemo I/System.out: MALE
最后一行蛛枚,把MALE打印出來(lái)了。
數(shù)組
通過(guò)關(guān)鍵字repeated實(shí)現(xiàn)
看下面代碼:
syntax = "proto3";
enum Sex
{
MALE = 0;
FEMALE = 1;
}
message Student
{
int32 number = 1;
string name = 2;
Sex sex = 3;
string hobby = 4;
string skill = 5;
repeated int32 array = 6 [packed=true];
}
我們通過(guò)repeated int32 array =6;
定義了一個(gè)int[]類型的數(shù)組脸哀。而后面[packed=true]是因?yàn)橐獌?yōu)化之前的版本對(duì)一些int32數(shù)據(jù)進(jìn)行字節(jié)對(duì)齊蹦浦。
然后我們?cè)趈ava工程中測(cè)試
Student.Builder buidler = Student.newBuilder();
buidler.setName("Frank");
buidler.setNumber(123456);
buidler.setHobby("music");
buidler.setSex(Sex.MALE);
buidler.addArray(1);
buidler.addArray(2);
buidler.addArray(3);
Student student = buidler.build();
System.out.println(student.toString());
byte[] array = student.toByteArray();
try {
Student student1 = Student.parseFrom(array);
System.out.println(student1.toString());
System.out.println(student1.getSex().toString());
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
}
通過(guò)builder.addArray()添加數(shù)組元素。
打印結(jié)果如下:
com.frank.protocdemo I/System: FinalizerDaemon: finalize objects = 1
com.frank.protocdemo I/System.out: number: 123456
com.frank.protocdemo I/System.out: name: "Frank"
com.frank.protocdemo I/System.out: hobby: "music"
com.frank.protocdemo I/System.out: array: 1
com.frank.protocdemo I/System.out: array: 2
com.frank.protocdemo I/System.out: array: 3
com.frank.protocdemo I/System.out: number: 123456
com.frank.protocdemo I/System.out: name: "Frank"
com.frank.protocdemo I/System.out: hobby: "music"
com.frank.protocdemo I/System.out: array: 1
com.frank.protocdemo I/System.out: array: 2
com.frank.protocdemo I/System.out: array: 3
com.frank.protocdemo I/System.out: MALE
引用另一個(gè)message
在java中經(jīng)常有一個(gè)對(duì)象包含另一個(gè)對(duì)象的情況撞蜂。而在protocol buffer中這個(gè)也能實(shí)現(xiàn)盲镶。
一個(gè)message中能夠嵌套另外一個(gè)message。
比如在Student.proto中添加一個(gè)Info對(duì)象蝌诡。
message Info
{
int32 qq = 1;
int32 weixin = 2;
}
message Student
{
int32 number = 1;
string name = 2;
Sex sex = 3;
string hobby = 4;
string skill = 5;
repeated int32 array = 6;
Info info = 7;
}
然后測(cè)試代碼為:
Student.Builder buidler = Student.newBuilder();
buidler.setName("Frank");
Info.Builder infoBuilder = Info.newBuilder();
infoBuilder.setQq(1111111);
infoBuilder.setWeixin(222222);
buidler.setInfo(infoBuilder);
Student student = buidler.build();
System.out.println(student.toString());
byte[] array = student.toByteArray();
try {
Student student1 = Student.parseFrom(array);
System.out.println(student1.toString());
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
}
打印結(jié)果如下:
com.frank.protocdemo I/System.out: name: "Frank"
com.frank.protocdemo I/System.out: info {
com.frank.protocdemo I/System.out: qq: 1111111
com.frank.protocdemo I/System.out: weixin: 222222
com.frank.protocdemo I/System.out: }
com.frank.protocdemo I/System.out: name: "Frank"
com.frank.protocdemo I/System.out: info {
com.frank.protocdemo I/System.out: qq: 1111111
com.frank.protocdemo I/System.out: weixin: 222222
com.frank.protocdemo I/System.out: }
嵌套
java中有內(nèi)部類的概念溉贿,如
class Student{
class Score{
}
}
而在protocol buffer中同樣支持
message Student
{
message Score
{
int32 chinese = 1;
int32 history = 2;
}
int32 number = 1;
string name = 2;
Sex sex = 3;
string hobby = 4;
string skill = 5;
repeated int32 array = 6;
Info info = 7;
Score score = 8;
}
上面在Message Student定義了message Score,里面域代表兩門(mén)成績(jī)浦旱。中文和歷史宇色。
那好,測(cè)試代碼如下:
Student.Builder buidler = Student.newBuilder();
buidler.setName("Frank");
Student.Score.Builder scoreBuilder = Student.Score.newBuilder();
scoreBuilder.setChinese(99);
scoreBuilder.setHistory(88);
buidler.setScore(scoreBuilder);
Student student = buidler.build();
System.out.println(student.toString());
byte[] array = student.toByteArray();
try {
Student student1 = Student.parseFrom(array);
System.out.println(student1.toString());
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
}
打印結(jié)果:
com.frank.protocdemo I/System.out: name: "Frank"
com.frank.protocdemo I/System.out: score {
com.frank.protocdemo I/System.out: chinese: 99
com.frank.protocdemo I/System.out: history: 88
com.frank.protocdemo I/System.out: }
com.frank.protocdemo I/System.out: name: "Frank"
com.frank.protocdemo I/System.out: score {
com.frank.protocdemo I/System.out: chinese: 99
com.frank.protocdemo I/System.out: history: 88
com.frank.protocdemo I/System.out: }
可以看到結(jié)果也是準(zhǔn)確無(wú)誤的闽寡。
import關(guān)鍵字
我們之前的示例中
message Info
{
int32 qq = 1;
int32 weixin = 2;
}
message Student
{
int32 number = 1;
string name = 2;
Sex sex = 3;
string hobby = 4;
string skill = 5;
repeated int32 array = 6;
Info info = 7;
}
message Info和message Student定義在同一個(gè).proto文件當(dāng)中代兵。而在protocol buffer中可以通過(guò)import關(guān)鍵字引入其它.proto文件當(dāng)中的message。
[Info.proto]
syntax="proto3";
option java_package="com.frank.protocdemo";
message Info
{
int32 qq = 1;
int32 weixin = 2;
}
[Student.proto]
syntax = "proto3";
import "Info.proto";
option java_package="com.frank.protocdemo";
option java_outer_classname="StudentDemo";
enum Sex
{
MALE = 0;
FEMALE = 1;
}
message Student
{
message Score
{
int32 chinese = 1;
int32 history = 2;
}
int32 number = 1;
string name = 2;
Sex sex = 3;
string hobby = 4;
string skill = 5;
repeated int32 array = 6 [packed=true];
Score score = 7;
Info info = 8;
}
我們通過(guò)import "Info.proto";
就算導(dǎo)入了message Info.
然后我們對(duì)兩個(gè)proto文件進(jìn)行編譯
protoc -I=. --java_out=. Info.proto Student.proto
將會(huì)產(chǎn)生InfoOuterClass.java與StudentDemo.java爷狈。我們可以將這兩個(gè)文件添加到工程中植影,就能如此前那樣正常使用。自此涎永,import關(guān)鍵字導(dǎo)入其它proto文件中的message就完成了思币。
option之java_package
文章一開(kāi)始我們編寫(xiě)Student.proto時(shí)沒(méi)有指定這個(gè)選項(xiàng),所以它編譯后生成的java文件就在當(dāng)前目錄下∠畚ⅲ現(xiàn)在我們這樣編寫(xiě)代碼
syntax = "proto3";
option java_package="com.frank.protocdemo";
enum Sex
{
MALE = 0;
FEMALE = 1;
}
message Student
{
message Score
{
int32 chinese = 1;
int32 history = 2;
}
int32 number = 1;
string name = 2;
Sex sex = 3;
string hobby = 4;
string skill = 5;
repeated int32 array = 6 [packed=true];
Score score = 7;
}
option java_package=”com.frank.protocdemo”;
添加了這段代碼谷饿,它的作用是最終會(huì)將編譯產(chǎn)生的java文件放在com/frank/protocdemo這個(gè)目錄下。
所以java_package是用來(lái)定義編譯后產(chǎn)生的文件所在包結(jié)構(gòu)的
package
package與java_package有些不同妈倔,java_package是定義編寫(xiě)生成后的java文件所在的目錄博投,而package是對(duì)應(yīng)的java類的包名。
option之java_outer_classname
我們之前的代碼中都沒(méi)有指定Student.proto編譯生成的java文件名稱盯蝴,所以它默認(rèn)的就是StudentOuterClass.java毅哗。
現(xiàn)在我們?cè)囋囘@樣
syntax = "proto3";
option java_package="com.frank.protocdemo";
option java_outer_classname="StudentDemo";
enum Sex
{
MALE = 0;
FEMALE = 1;
}
message Student
{
message Score
{
int32 chinese = 1;
int32 history = 2;
}
int32 number = 1;
string name = 2;
Sex sex = 3;
string hobby = 4;
string skill = 5;
repeated int32 array = 6 [packed=true];
Score score = 7;
}
我們添加了這行option java_outer_classname="StudentDemo";
,而最終它產(chǎn)生的java文件也不再是StudentOuterClass.java而是StudentDemo.java。
所以java_outer_classname是用來(lái)定義編譯后的java文件名字的捧挺。
編譯命令
還記得本文開(kāi)始的地方嗎虑绵?用
protoc --java_out =. addressbook.proto
將proto文件編譯成java文件。
其實(shí)它的完整命令如下:
protoc --proto_path=IMPORT_PATH --cpp_out=DST_DIR --java_out=DST_DIR --python_out=DST_DIR path/to/file.proto
- proto_path=IMPORT_PATH 默認(rèn)當(dāng)前目錄
- cpp_out 生成的c++文件目錄
- java_out 生成的java文件目錄
- pytho_out 生成的python文件目錄
–proto_path等同于-I選項(xiàng)闽烙,它的意思是等待編譯的.proto文件所在的目錄翅睛,可以指定多個(gè),如果不指定的話默認(rèn)是當(dāng)前目錄。
path/to/file.proto 等待編譯的proto數(shù)據(jù)文件捕发。
所以
protoc --java_out =. addressbook.proto
就是將addressbook.proto文件編譯產(chǎn)生java文件疏旨。
總結(jié)
protocol buffer的使用還是相對(duì)簡(jiǎn)單點(diǎn),唯一麻煩的就是多了一個(gè)預(yù)編譯的過(guò)程爬骤,將.proto文件轉(zhuǎn)換成.java文件充石。但有的時(shí)候莫换,這些過(guò)程是必須的霞玄。