互联网圈有这么一句话:百度的技术,阿里的运营,腾讯的产品。那么代表互联网三座大山的BAT,内部人才体系有什么区别呢?今天小编就带领大家看一看~
★ 腾讯 ★
1. 职级
腾讯职级体系分6级,最低1级,最高6级。同时按照岗位又划分为四大通道,内部也叫“族”,比如:
产品/项目通道,简称P族
技术通道,简称T族
市场通道,简称M族
职能通道,简称S族
以T族为例,分别为:
T1:助理工程师 (一般为校招新人)
T2:工程师
T3:高级工程师 3-1相当于阿里的p6 到p7(能力强可能到p7)
T4:专家工程师
T5:科学家
T6:首席科学家
目前全腾讯貌似就一个T6。
每一级之间又分为3个子级,3-1是任命组长/副组长的必要条件,其他线也是这样。T4基本为总监级,也不排除有T3-3的总监,因为T4非常难晋级。
2. 晋升
腾讯的晋级还是很困难的。尤其是T2 升T3,T3升T4。非常多的人卡在2-3,3-3没办法晋级。有的小伙伴做了3、4年的2-3 也升不上去啊。
3. 薪水
腾讯薪资架构:12 1 1=14薪
年终奖:看部门盈利情况,一般是3个月
级别越高base薪酬也越高,一年根据你的performance大概能发15.3个月至18个月的工资,T3.1的base 2w ,T3以上级别的员工都会有股票期权,腾讯09以前的员工赚钱主要靠股票,从08到现在股票up了500% ,T5 的base薪酬在600w~800w/年。
4.人才
人才流动的可能:
在深圳:很多腾讯员工都买了房,当你的房子,妻子的工作,儿子的学校,你的朋友圈,都在一个城市的时候,换城市就有困难了。所以只能挖一些比较浅的人走。
在北京:人数不少 ,不过骨干员工不多。腾讯视频的主要团队在北京的倒是不少。
在成都、大连:在这些二线城市,腾讯就是当地最好的互联网公司了,提供的待遇也是非常高的,不少人都对自己的薪资比较满意,工作环境也很满意。跳槽的可能性低了很多。
人才结构:
腾讯的研发序列硕士学历的占多度,211大学,985大学占多数。大家都知道腾讯研究院解散了。去年走出来很多人,腾讯人才创业比例不高。
在腾讯最常碰到的晋升问题就是天花板。可能新人进去,学东西会很多,但业务线就这些,没有那么多坑,自然也就很难晋升高级岗。
在腾讯最悲剧的时刻就是公司有收购和整合。搜狗合并,搜搜的人哭了,京东合作,易迅的人哭了。在腾讯跳出来碰到最大的问题就是,外面的公司太不完善了。
★ 阿里巴巴 ★
1. 层级
阿里的职称大部分都归纳在P序列 ,你的title 工种。比如P7产品经理=产品专家。
一般到P3为助理
P4=专员
P5=资深专员
P6=高级专员(也可能是高级资深)
P7=专家
P8=资深专家(架构师)
P9=高级专家(资深架构师)
P10=研究员
P11=高级研究员
P12=科学家
P13=首席科学家
P14=马云
同时对应P级还有一套管理层的机制在:
M1=P6 主管
M2=P7 经理
M3=P8 资深经理
M4 =P9 总监
M5= P10 资深总监
M6 =P11 副总裁
M7=P12 资深副总裁
M8=P13 子公司CEO 或集团其他O
M9=P14 陆兆禧(前马云)
在阿里早些时候P级普遍偏低,专员可能是P2这样,后来有了一次P级通货膨胀,出现了更多的P级。在阿里只有P6(M1)后才算是公司的中层。不同的子公司给出P级的标准不一样。
比如:B2B的普遍P级较高,但是薪资水平低于天猫子公司的同级人员。同时到达该P级员工才有享受公司RSU的机会。(低于P6的除非项目出色有RSU奖励,否则1股都拿不到)
2.晋升
晋升很简单:
1. 晋升资格:上年度KPI达3.75。
2. 主管提名。一般KPI不达3.75主管不会提名。
3. 晋升委员会面试。(晋升委员会组成一般是合作方业务部门大佬、HRG、该业务线大佬等。)
4. 晋升委员会投票。
P5升P6相对容易,再往上会越来越难,一般到P7都是团队技术leader了,P6到P7非常难,从员工到管理的那一步跨出去不容易,当然有同学说P一般都是专家,M才是管理,actually,专家线/管理线有时并不是分的那么清楚的。
3. 薪水
• 阿里薪资结构:一般是12 1 3=16薪
• 年底的奖金为0-6个月薪资,90%人可拿到3个月
• 股票是工作满2年才能拿,第一次拿50%,4年能全部拿完
★ 百度 ★
1. 层级
百度的级别架构分成四条线。
技术序列 T:T3 - T11 (一般对应阿里高一级序列,如:百度T3=阿里P4,T5/T6属于部门骨干,非常抢手,人人猎中相当一部分offer人选都来自这个序列)
产品运营序列 P:p3-P11 (产品和运营岗,对应阿里高1-1.5级序列 百度p3=阿里P4-P5之间)
后勤支持部门 S :S3-S11 (主要是公共、行政、渠道等等,晋升比较困难)
管理序列 M:M1-M5 (每一级又分为2个子级 M1A、M1B , 最低的是M1A,至少是部门二把手了,李明远是M3.2,以前的汤和松都是这个级别,李彦宏是唯一的M5,其实从M3开始就有机会加入E——star,类似于阿里的合伙人会议,属于最高战略决策层。
2. 薪资
月薪14.6(12 0.6 2),其他岗位:月薪14
T5以上为关键岗位,另外有股票、期权。T5、T6占比最大的级别,T8、T9占比最小,级别越高,每档之间的宽幅越大。
3. 晋升
基本上应届毕业生应该是T3,但是内部晋升非常激烈。公司那么大,部门和部门之间有业务竞争,肯定也有人才竞争。
通常应届毕业生入职1年多能升到T4,但如果你的部门业务足够核心,或许1年就可以了。3年升T5。从目前百度的情况来看,核心工程师集中在T5/6,但是从5/6到7是非常艰难的过程。
百度是很唯KPI至上的,其次部门很核心,再次老大话语权比较高,相对晋升容易些。
一般情况分2种:
1. 自己提名,当你自己觉得已经具备下一level的素质,可以自己提名,提名后进入考察期,主管设定考察期目标,考察通过顺利晋升,考察不通过维持原层级不变;
2. 主管提名,如果是主管提名,一般都是直接通过的,但是如果你现层级已经比较高了,那就不是直接提名这么简单了。
P.S.如果你能升到T7,基本上是TL的级别,写代码/直接做业务的时间就很少了。
思考
看了以上BAT三家巨头公司人才体系的职位层级、薪酬、晋升标准,你是否有被触动或者震撼呢?
终身成长词典词条《464:花盆效应》中提到:
心理学上有这样一个词,叫“花盆效应”,指的是人如果在舒适的“花盆”中待久了,就会不思进取、安于现状。当你对现状心满意足,日复一日地去做着同样的事情,不再将时间花在提升自己,那么你的成长见识,将永远停留在原来的那块区域里。
曾看到这样一句话:一个人老去的标志,绝不是老成稳重、沉默寡言,而是不肯再尝试,不肯再容许自己置身不熟悉的境地。当你停止了学习、固步自封,将自己囚禁在得过且过的牢笼中,那么你已经朝平庸迈进了一大步。
想要了解架构技术知识点的,可以关注我一下,我后续也会整理更多关于分布式架构这一块的知识点分享出来,另外顺便给大家推荐一个交流学习群:650385180,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多,以下的知识体系图也是在群里获取。
并发编程
分布式
开发工具
性能调优
微服务架构
源码分析
总结
希望我分享出来的这些知识点可以帮助在这个行业发展的朋友和童鞋们,在论坛博客等地方少花些时间找资料,把有限的时间,真正花在学习上,我把这些视频分享出来。相信对于已经工作和遇到技术瓶颈的码友,在这个群里一定有你需要的内容。
目标已经有了,下面就看行动了!记住:学习永远是自己的事情,你不学时间也不会多,你学了有时候却能够使用自己学到的知识换得更多自由自在的美好时光!时间是生命的基本组成部分,也是万物存在的根本尺度,我们的时间在那里我们的生活就在那里!我们价值也将在那里提升或消弭!
Protocol buffer JSON XML
简介
Protocol Buffers(也称protobuf)是Google公司出口的一种独立于开发语言,独立于平台的可扩展的结构化数据序列机制。通俗点来讲它跟xml和json是一类。是一种数据交互格式协议。
网上有很多它的介绍,主要优点是它是基于二进制的,所以比起结构化的xml协议来说,它的体积很少,数据在传输过程中会更快。另外它也支持c++、java、python、php、javascript等主流开发语言。
Protocol编译安装
protocol的编译器是C语言编写的,如果你正在使用c++开发,请根据c++安装引导进行安装。
对于不是c++语言的开发者而言,最简单的方式就是从下面的网站下载一个预编译的二进制文件。
https://github.com/google/protobuf/releases
在上面的链接中,你可以按照对应的平台下载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
如果你要寻找之前的版本,通过下面的maven库:
http://repo1.maven.org/maven2/com/google/protobuf/protoc/
因为我主要用java开发应用,所以这篇文章重点讲解protocol的java实现。 还有这是在windows上操作。
Protocol buffer的安装
1 通过Maven方式安装
如果你机器上还没有安装maven.请到下面的网站安装
http://maven.apache.org/
选择相应的包。我这里选择的是apache-maven-3.3.9-bin.zip.
添加maven到path
将下载后的bin目录添加到path中。
然后用mvn -version测试一下
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"
说明安装成功
安装protoc
从https://github.com/google/protobuf/releases下载protoc,如protoc-3.1.0-win32.zip,然后解压然后添加到path.
在命令行中测试
protoc --version
正常情况应该打印版本信息,说明添加成功。
将protoc复制到protocol buffer解压的目录。
这一步很重要。
例如之前下载的protobuf-java-3.1.0.zip我将它解压在E盘
E:\xxxx\protobuf-java-3.1.0
,那么E:\xxxx\protobuf-java-3.1.0\protobuf-3.1.0
这个目录就当它是根目录。我用$ROOT表示。
将protoc.exe文件复制到$ROOT/src/
目录下。
然后在命令行中定位到$ROOT/java/
,
然后运行命令mvn package
,
如果一切成功的话,就会在$ROOT/java/core/target/
目录下生成protobuf-java-3.1.0.jar文件。
编译代码
在下载的protobuf-java-3.1.0.zip解压后,我们定义它的根目录为$ROOT。它下面有一个examples文件夹,里面有个adressbook.proto文件,.proto就是protocol buffer的文件格式后缀。
我们将之前生成的protobuf-java-3.1.0.jar复制到该目录下。然后执行下面的命令
protoc --java_out=. addressbook.proto
它就会自动生成com/example/tutorial/AddressBookProtos.java文件。
自此,protoc buffer就完全编译成功,并且能正常运行了。
接下来我讲解它的基本语法
语法
在Android开发中,json运用的很广泛,gson类可以直接将一个java类对象直接序列成json格式的字符串。
在protocol buffer中同样有类似功能的结构。
比如我要定义一个学生类,它包含学号、姓名、性别必要信息,也有兴趣爱好、特长等必要信息。
如果用java的话。大概如下面
class Student{
int number;
String name;
int sex;
String hobby;
String skill;
}
那么如果用Protocol buffer来定义呢?
这里有一个关键字message。message是消息的意思,等同于java中的class关键字和c中的struct,代表一段数据的封装。
简单示例
首先我们得创建.proto文件。这里为Student.proto
syntax = "proto3";
message Student
{
int32 number = 1;
string name = 2;
int32 sex = 3;
string hobby = 4;
string skill = 5;
}
syntax=”proto3”表示运用proto3的语法。而网上的教程大多还是proto2。
proto3提示required限制符不能起作用,默认的就是optional,表示任何域都是可选的。
那好,我们参加教程前面部分将.proto文件转换成.java文件。
protoc --java_out=. Student.proto
结果在当前目录生成了StudentOuterClass.java文件。至于为什么是StudentOuterClass.java这是因为我们在Student.proto没有指定它编译后生成的文件名称,protoc程序默认生成了StudentOuterClass.java,其实这个名字我们可以自定义,文章后面的内容我会介绍。
序列化
在IDE中新建项目,然后添加StudentOuterClass.java文件,并且添加protobuf-java-3.1.0.jar。
然后编写如下代码:
Student.Builder buidler = Student.newBuilder();
buidler.setName("Frank");
buidler.setNumber(123456);
buidler.setHobby("music");
Student student = buidler.build();
System.out.println(student.toString());
最终代码会在运行时打印如下信息:
I/System.out: number: 123456
I/System.out: name: "Frank"
I/System.out: hobby: "music"
说明从.proto中的message到java中的class转换已经成功。
最后
student.toByteArray();
这个方法会得到byte[],我们可以将它送到文件流中进行传输,这也是它的终极目的。也就是我们将protoc对象序列化成了字节流数据。
大家注意这个toByteArray()产生的byte[]数组,它代表要全部传输的二进制数据,大家可以打印它的大小,有心人可以用json实现两样的信息,然后打印json序列化后的数据长度做比较。看看,protocol buffre是不是更节省内存空间,但在这里,我不做过多探究。
那么如何将字节流数据反序列化成protoc对象呢?
反序列化
我们可以这样
byte[] array = student.toByteArray();
try {
Student student1 = Student.parseFrom(array);
System.out.println(student1.toString());
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
}
array是之前序列化后产生的byte数据,现在通过Student的静态方法parseFrom()可以数据反序列成Student对象。
现在想来这个是不是很简单???
除了开始的阶段编写.proto文件,然后再把.proto文件编译成java文件麻烦点,其余的步骤甚至比json转换的更便利。
message
上一节已经见识过了message,它等同于java中的class关键字和c中的struct关键字。
message Student
{
}
限定符
在proto2.0版本中有三个限定符
- required 必要的域
- optional 可选的
- repeated 可重复的(0~N)
其中被required修饰的变量是必不可少的。
optional可有可无。
repeated修饰的就要是数组字段。
而在proto3.0中required被删掉了。optional字符也不能使用,因为默认的域都是optional属性。
3.0新语法
syntax = "proto3";
或者
syntax="proto2";
这个写在.proto文件中,用来指定使用proto3语法还是使用proto2语法。目前protobuffer继续支持proto2
数据类型
我们在前面的内容中见到了int32这样的字眼,它其实是数据类型。
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除了支持上面的基本类型外还支持枚举。
关键字是enum
比如我们可以将前文提到的Student对象中的性别用一个枚举代替。
那么将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编译产生新的java文件,并添加到工程当中。再进行代码测试。
Student.Builder buidler = Student.newBuilder();
buidler.setName("Frank");
buidler.setNumber(123456);
buidler.setHobby("music");
//已经可以设置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();
}
在上面代码中有这两句
//设置性别
buidler.setSex(Sex.MALE);
//打印性别
System.out.println(student1.getSex().toString());
然后打印的结果如下:
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打印出来了。
数组
通过关键字repeated实现
看下面代码:
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];
}
我们通过repeated int32 array =6;
定义了一个int[]类型的数组。而后面[packed=true]是因为要优化之前的版本对一些int32数据进行字节对齐。
然后我们在java工程中测试
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();
}
通过builder.addArray()添加数组元素。
打印结果如下:
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
引用另一个message
在java中经常有一个对象包含另一个对象的情况。而在protocol buffer中这个也能实现。
一个message中能够嵌套另外一个message。
比如在Student.proto中添加一个Info对象。
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;
}
然后测试代码为:
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();
}
打印结果如下:
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中有内部类的概念,如
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,里面域代表两门成绩。中文和历史。
那好,测试代码如下:
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();
}
打印结果:
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: }
可以看到结果也是准确无误的。
import关键字
我们之前的示例中
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定义在同一个.proto文件当中。而在protocol buffer中可以通过import关键字引入其它.proto文件当中的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;
}
我们通过import "Info.proto";
就算导入了message Info.
然后我们对两个proto文件进行编译
protoc -I=. --java_out=. Info.proto Student.proto
将会产生InfoOuterClass.java与StudentDemo.java。我们可以将这两个文件添加到工程中,就能如此前那样正常使用。自此,import关键字导入其它proto文件中的message就完成了。
option之java_package
文章一开始我们编写Student.proto时没有指定这个选项,所以它编译后生成的java文件就在当前目录下。现在我们这样编写代码
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”;
添加了这段代码,它的作用是最终会将编译产生的java文件放在com/frank/protocdemo这个目录下。
所以java_package是用来定义编译后产生的文件所在包结构的
package
package与java_package有些不同,java_package是定义编写生成后的java文件所在的目录,而package是对应的java类的包名。
option之java_outer_classname
我们之前的代码中都没有指定Student.proto编译生成的java文件名称,所以它默认的就是StudentOuterClass.java。
现在我们试试这样
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";
,而最终它产生的java文件也不再是StudentOuterClass.java而是StudentDemo.java。
所以java_outer_classname是用来定义编译后的java文件名字的。
编译命令
还记得本文开始的地方吗?用
protoc --java_out =. addressbook.proto
将proto文件编译成java文件。
其实它的完整命令如下:
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 默认当前目录
- cpp_out 生成的c++文件目录
- java_out 生成的java文件目录
- pytho_out 生成的python文件目录
–proto_path等同于-I选项,它的意思是等待编译的.proto文件所在的目录,可以指定多个,如果不指定的话默认是当前目录。
path/to/file.proto 等待编译的proto数据文件。
所以
protoc --java_out =. addressbook.proto
就是将addressbook.proto文件编译产生java文件。
总结
protocol buffer的使用还是相对简单点,唯一麻烦的就是多了一个预编译的过程,将.proto文件转换成.java文件。但有的时候,这些过程是必须的。