1.先作个自我介绍吧
面试官您好,我叫张睿超,来自湖南长沙,大学毕业于湖南农业大学,是一名智能科学与技术专业的统招一本本科生。今天主要过来面试贵公司的Java后端开发工程师岗位。
大学里面主修的课程是Java、Python、数字图像处理、JavaEE。
大学期间,英语获得6级460分,参加过华为云的比赛,获得了全国高校绿色计算系列大赛团体三等奖。
我熟悉的技术栈在简历上都写了,我自己认为自己的亮点在以下几点:能进行简单的JVM调优;有实际处理高并发问题的经验;熟悉MySQL的操作,了解数据库调优原理;熟悉Linux的基本操作。
我自学C#两周、听学校讲解Python的Django框架2周,都写出了简单的项目;半年时间研究出了一个图像加密算法,并发表为了毕业论文。Java学习了一个学期、自学了2个月,之后在校企合作的项目中做出了这两个Java项目。
领导过小组作出Django框架的项目,参与过校企合作的两个Java项目。
了解到贵公司的业务需求偏向于xxx,我正好擅长xxx,所以我来应聘贵公司的Java开发岗位。
(或者衔接)
了解到贵公司的业务需求偏向于xxx,我最近做了一个xx项目,正好做了xxx,您看需不需要作一个简单的项目介绍。
2.你们微服务是怎么划分的
我们微服务按业务来划分,包括智能调度模块、路线规划模块、运单/任务管理模块,还有其他微服务。
智能调度负责调度运单、取件任务、派件任务、延时派件任务。
延时和实时派件任务存在区别,是为了满足2小时内快递员上门取件的服务需要。比如现在是10点半,用户期望11到12点取件,就发送实时取件任务;用户期望13到14点取件,就发送延时取件任务。
路线规划负责网点管理、路线管理、时间优先路线规划、成本优先路线规划等。
我们的网点、路线都存储在Neo4j数据库中,Neo4j是用来存储图关系的非关系型数据库。
Neo4j种,节点存的是机构,分为三种标签:一级转运中心、二级转运中心和节点。
节点的属性包括:Neo4j自带的id、业务id、名称、电话、地址、坐标等。
关系存的是路线,属性包括自带id和成本。
时间优先的查询语句如下:
MATCH path = shortestPath((start:AGENCY) -[*..10]-> (end:AGENCY))
WHERE start.bid = 123123 AND end.bid = 123456
RETURN path
转为Java的API,用到了stream流等工具。
运单/任务管理模块就包括运单管理、运输任务管理、取件任务管理、派件任务管理等。
业务包括创建运单、司机入库等。
其他微服务有基础微服务、快递员微服务、司机微服务、订单微服务、范围微服务、支付微服务等等。
3.你用过RabbitMQ吗
4.登陆功能是你写的吗,登录功能是怎么实现的
是的。
比如微信小程序的登录,首先微信小程序准备好appid、appsecret、code和phoneCode发送给后端,后端将其中的appid、appsecret和code转发给微信接口进行校验处理,如果校验失败则返回异常的响应状态码,成功则返回200。
在成功的基础上,解析得到响应中对应用户标识的openid,然后查询数据库中是否存在该用户。如果有则返回用户信息,没有则创建。
然后再次调用微信接口,获取用户的手机号,拿这个手机号更新或新增用户的信息。
用户的信息处理完了之后,根据这些信息生成登录校验的token,再返回给前端。
之后前端每一次请求都带上token,后端校验这个token就可以处理业务了。
我们使用的身份校验的技术是JWT。
(后面就可以接上我上一篇文章Java后端模拟面试 题集④-CSDN博客的第3个问题“JWT了解过吗,有用过吗”的回答内容,打一套丝滑小连招~)
5.你们JWT令牌认证,加密是怎么处理的
我们的加密是采用的RSA加密模式。
JWT全名叫JSON Web Token,由三部分组成:
Header头,记录令牌类型、签名算法等。 例如:{"alg":"HS256","type":"JWT"}
Payload有效载荷,携带一些自定义信息、默认信息等。 例如:{"id":"1","username":"Tom"}
Signature签名,防止Token被篡改、确保安全性。将header、payload,加入指定秘钥,通过指定签名算法计算而来。
加密方法RSA就写在Header中。我们校验的就是加密后的第三部分。
6.你知道MySQL的常用索引有什么
按数据结构分类:
B+数索引、Hash索引、全文索引。
按物理存储分类:
聚簇索引、非聚簇索引(辅助索引、二级索引)。
按字段特性分类:
主键索引、唯一索引、普通索引、前缀索引。
按索引字段个数分类:
单列索引、联合索引(复合索引、组合索引)。
7.你数据库的表的设计是什么样子的,比如你负责的登录的表是什么样子的
因为登录业务比较独立,所以我们设计这个表的时候没有关系字段,更别说设计什么冗余字段。这个表的字段是这样的:
1.基本字段:
主键id
统一认证id auth_id
身份证号id_card_no
实名认证状态id_card_no_vertify 0未验证 1验证通过 2验证未通过 3异常状态
手机号phone
名称name
头像avatar
微信openID open_id
性别sex 1男 0女
生日birthday
其中要提一下的是这个统一认证id auth_id,这个是方便日后确定多个小程序、网站应用等端中同一用户的认证,类似于微信中的UnionId。只不过,这个auth_id是针对我们开发的程序的,UnionId是针对微信开发的平台的。
还可以提一下的是,我们用数字类型来存储日期,这样存储空间更小,并且可以用索引来提升查找性能。
存储时,用int(10)来存,这样存:
update sl_member
set birthday=UNIX_TIMESTAMP('年年年年-月月-日日 12:00:00')
where id=xxxx;
取时这样:
SELECT DATE_FORMAT(FROM_UNIXTIME(birthday), '%Y-%m-%d') AS hour
FROM sl_member;
2.辅助字段:
创建时间created
更新时间updated
同上birthday的存储方式,用数字类型来存储,占空间更小,利用索引效率更高。
存取就更简单了,不用转格式了。
存:
update sl_member
set birthday=UNIX_TIMESTAMP('年年年年-月月-日日 时时:分分:秒秒')
where id=xxxx;
取:
SELECT FROM_UNIXTIME(birthday) AS hour
FROM sl_member;
关系字段和三种字段中冗余的部分没有。