1.你经常访问的技术类论坛有哪些?请推荐三篇你最近读到对你很有帮助的技术类帖子,列出帖子的标题和URL链接。
如下图看博客看的比较多,最近都是在看书,刚看完了Spring Cloud微服务实战,后续由于工作需要会学习hadoop和spark。

2.你在Github上关注(star)了哪些项目?请列举三个你在Github上关注的项目,列出项目名称和URL链接。
vue-element-admin:一个vue实现的前端页面,因为公司之前接了一个小项目(保费计算),想要使用vue实现,所以关注了这个项目,实现快速开发。(https://github.com/PanJiaChen/vue-element-admin/blob/master/README.md)
rocketmq:学习rocket的时候,了解了具体的api,然后看了一下底层的源码(https://github.com/apache/rocketmq)
WxJava:之前自己搞了一个公众号,实现自动回复等功能,所以就关注了这个项目,这个项目封装了微信官方提供的api。(https://github.com/Wechat-Group/WxJava)
3.你在Github上参与过开源项目吗?如果你在某个项目有代码贡献,请列举出来,列出项目名称和URL链接以及你贡献代码的Pull Request。
惭愧,目前还没有在参与官方的项目,不过自己开源了两个项目。
第一个叫转换服务,实现A转成B值。
第二个叫重试组件,因为目前自己负责的项目需要依赖第三方的接口获取数据,但是第三方的接口不稳定,所以会导致我们没法获取到数据,造成我们的系统数据统计会出错,所以自己开发了重试组件,当调第三方出错的时候,会定时重试,直到成功为止。
4.你最近正在学习或者计划学习的技术领域是什么?
因为最近公司需要重新规划产品,需要学习hadoop和spark流计算,这是目前的学习计划,因为自己之前都是纯前后端开发,所以能学习新的领域还是挺兴奋的。
5.请给出如下需求的解决方案或思路:需要对数百TB的文件(图片、视频或其他格式化文件,分两种情况,一种是单个文件尺寸不大,文件数量多;一种是单个文件尺寸较大)进行存储和管理。有如下要求:
a) .基于文件名(或存储路径)快速索引访问;
b) 基于文件内容快速索引访问;
c) 动态扩展存储容量,不影响应用层访问接口;
d) 应用层提供对这些文件的管理和访问接口。
请给出解决方案或者思路,包括:系统整体架构设计,底层架构选择,应用层解决方案。
如下方架构图所示。

6.请回答以下实际开发案例的问题(Java语言实现,基于SpringCloud框架):用户登录授权认证是应用系统种最常见的功能,有如下需求:
a) 用户基于用户名密码进行登录认证;
b) 用户登录成功后系统生成Token,后续所有接口访问基于Token判断是否有权限可以访问相应的接口(不同的接口有不同的权限)。
请给出以下问题的解决方案或者思路:
a) 如何存储和读取每一个登录用户的Token,每一个访问请求都需要通过Token来判断访问权限,需要确保效率;
b) 基于Token的接口访问权限控制如何设计;
c) 在SpringCloud的框架体系中,如何实现上述功能,需要用到哪些组件;
d) 将Token的存储和访问封装为一个Java类并给出实现代码,至少实现以下接口:插入新的用户Token;删除指定用户Token;根据Token获取用户基本信息(用户名,用户权限等);检查Token是否有某接口的访问权限。
业务流程如下图

设计思路:
1.用户请求发送到服务器,会被Loginfilter拦截器拦截到,判断用户的登陆状态和访问权限。
A.根据TokenId访问redis服务器,如果没有获取到值,则表示用户没有登陆,跳转到登陆页面,进行登陆。
a.登陆页面进行登陆,输入用户名和密码进行登录
b.登陆成功,生成tokenId,并读取用户表和用户资源权限表,并保存到redis中,为map格式 tokenId url true url true
B.根据TokenId访问redis服务器,如果获取到值则表示用户已经登陆,然后进一步判断redis取出来的value中是否包含该请求的url,有则表示有访问权限,没有则跳转到无权限页面。
创建数据库表
1.创建用户表
create table user
(
id bigint not null auto_increment,
username varchar(64) comment '用户名',
password varchar(64) comment '密码',
icon varchar(500) comment '头像',
nick_name varchar(200) comment '昵称',
create_time datetime comment '创建时间',
login_time datetime comment '最后登录时间',
status int(1) default 1 comment '帐号启用状态:0->禁用;1->启用',
primary key (id)
);
2.创建接口资源访问(接口地址,接口描述)
create table resource
(
id bigint not null auto_increment,
create_time datetime comment '创建时间',
name varchar(200) comment '资源名称',
url varchar(200) comment '资源URL',
description varchar(500) comment '描述',
primary key (id)
);
3.创建用户资源权限表:
create table user_resource_relation
(
id bigint not null auto_increment,
user_id bigint comment '用户ID',
resource_id bigint comment '资源ID',
primary key (id)
);
代码实现
/**
* 用户token service
*/
@Service
public class TokenServiceImpl implements TokenService {
@Autowired
private RedisTemplate redisTemplate;
/**
* 插入新的用户Token
* @param username
* @return
*/
@Override
public void addUserToken(String username){
Map<String,String> userInfoMap=new HashMap<String,String>();
//获取用户信息
User user= getUserByUserName(username);
userInfoMap.put("info",JSONObject.toJSONString(user));
//根据用户id获取该用户的资源权限
List<String> resource =getResourceByUserId(user.getId);
userInfoMap.put("resource",JSON.toJSONString(resource));
//根据user信息生成tokenId
String tokenId=getTokenId(user);
redisTemplate.opsForHash().putAll(tokenId,userInfoMap);
}
/**
* 删除指定用户Token
* @param userId
* @return
*/
@Override
public void deleteUserToken(String userId){
//获取用户信息
User user= getUserByUserId(userId);
//根据user信息生成tokenId
String tokenId=getTokenId(user);
//根据tokenId删除reids的值
redisTemplate.delete(tokenId);
}
/**
* 根据Token获取用户基本信息(用户名,用户权限等)
* @param tokenId
* @return
*/
@Override
public User getUserInfoByTokenId(String tokenId){
//获取用户信息
String userInfo=redisTemplate.opsForHash().get(tokenId,"info");
User user = JSONObject.parseObject(userInfo, User.class);
//获取用户信息
String resource=redisTemplate.opsForHash().get(tokenId,"resource");
List<String> resource = JSONObject.parseArray(resource, String.class);
user.setResource(resource);
return user;
}
/**
* 检查Tokenid和访问接口地址判断是否有某接口的访问权限
* @param tokenId
* @param url
* @return
*/
@Override
public User isRightByTokenIdAndUrl(String tokenId,String url){
//获取用户权限
String resource=redisTemplate.opsForHash().get(tokenId,"resource");
List<String> resource = JSONObject.parseArray(resource, String.class);
return resource.contains(url);
}
}