靠伙伴匹配系统找到实习工作

投递简历到获得第一次面试机会 10 天。


个人背景:民办二本,只有一个伙伴匹配项目,没有实习经验。


面试到发 offer 大概 2 天。


面试整体流程有卡壳但是还算挺顺畅的。这里感谢鱼皮哥提供的项目与项目面试题。


面经


1. 自我介绍

2. 项目问题

  1. 编辑距离算法
  2. 优先队列
  3. 如何使用Redis GEO 实现寻找附近的人
  4. 线程池批量导入数据
  5. 遇到了哪些难点
  6. 登录问题:分布式除了使用Redis实现 ,还有哪些实现方式

3. 技能

  1. 做过微服务项目吗
  2. 配置中心和注册中心用什么?
  3. Nacos,如何获得最新的配置
  4. Gateway 的作用
  5. Spring MVC 的请求流程
  6. 适配器模式

4. 其余:

  1. 你家住哪里,几号可以入职,毕业设计的问题


以下是复盘之后的回答,修改过,主要是伙伴匹配系统的回答(球友们仅供参考)...


自我介绍:

参考星球专栏-》面霸手把手教你面试》自我介绍

总结

  1. 向面试官问好,几句话介绍自己的优势,要与众不同
  2. 讲述下自己的技术成长经历 7-8句
  3. 几个关键词总结,以及结束语


答:

面试官,你好,我叫xxx,我是一名xx大学生同时是24届毕业生,我在学校不仅每天拿出大量的时间学习编程,我还担任班长团支书,xxx的负责人。


我是从 xxx年xx月开始自学Java 后端编程,至今已经有着xx年的编程学习经验,参与过多个项目的开发。熟练掌握SpringBoot进行后端开发和MySQL,Redis等数据库进行项目开发。


用两个关键词总结我的学习经历是,“坚持”、“复盘迭代”。接下来我会继续投入在编程学习中。


我的介绍完毕,谢谢你的倾听。


(总结:其实写的一般般,并没有数据的量化,例如拿到什么比赛的名次,写过多少篇技术文章等等,项目达到什么效果也没说。不过是因为我没得说哈哈,太菜了,下一步要继续努力,做一些可以数据量化的事情。)


项目

编辑距离算法:


编辑距离算法是可以实现两个字符串之间的相识度与差异度的算法。

字符串A 进行多少次 增删改 可以变成字符串B

项目的是标签:【java,大一】变成【java,大二】需要经过一次修改。相识度分数为 1


我当时的实现思路是

引入网上一个现成的运算字符串匹配度的算法。

在单元测试类中,将其转化为字符串数组的匹配度的算法。

在项目中封装成一个工具类,使用的时候将用户的标签转化为String字符串数组来做为参数。


优先队列:


优先队列是根据优先级来实现出队入队的。

项目中,维护一个优先队列,保持 N 个,比优先队列内优先级低的不选择入队,比优先队列优先级大的,实现入队,并淘汰一个低的,使得队列保持在 N 中,减少内存的使用,Java的优先队列使用 PriorityQueue


具体的实现思路:

  1. 创建大顶堆的优先队列。
  2. 通过传入比较器创建,泛型是Pair(Pair 是存储键值对的,第一个键是user,第二个是相识度的分数),
  3. 先查询数据库中的所有用户
  4. 优先队列初始化,将前 num(这个值是前端传递过来的,默认为5) 个用户数量插入队列中。
  5. 计算相识度
  6. 将之后的用户与登录用户逐一相比较计算分数,比较堆顶的距离与计算的分数,若计算分数要小于,则删除堆顶元素,插入新元素到优先队列中。
  7. 通过Stream 流将优先队列中存储的userid 获取出来,收集为UserIdList。
  8. 根据 UserIdList 查询出最终的用户列表,进行脱敏返回。


Redis GEO实现查询附近的人:


我提供两个接口。1.上传地理位置,2.查询附近的人。查询附近的人之前必须先上传地理位置


  1. 先封装一个请求类:包含userId,经度lon,纬度lat,半径redius,两个接口的请求参数都是使用这个类
  2. 封装常量类,用来定义上传Redis的key值


上传地理位置接口:


  1. 校验参数:是否为空?
  2. 上传地址位置,存入Redis中,创建 RedisGeoCommands.GeoLocation对象,使用redisTemplate.opsforGeo.add


查询附近的人接口:


校验参数

1 获取用户id是否登录

2 redius 是否为空,空则默认为3000m

3 查询经度,纬度,为空的话在 redis 中获取

查询

1 根据 Redius 创建 Distance 对象,根据经度、纬度创建 point,根据 point,distance对象 创建 circle

2创建 Geo 命令参数对象 RedisGeoCommands.GeoRadiusCommandArgs设置查询限制条件返回限制 20人,返回包含距离,按由近及远排序。

3开始查询:使用命令查询redisTemplate.opsForGeo().radius(key, circle, args);获取附近的人的结果。

处理结果

1.创键map,第一个参数 是 userid 第二参数是泛型参数 Vo 类包装着(userId ,distance距离,username昵称,userUrl头像),forEach遍历查询GeoResults 结果,将其封装到 map 中,根据 map.keySet()方法获取UserId 查询附近的人的信息,并添加到对应的 vo类中。

返回结果

通过map.values(),返回结果:newArrayList(map.values())


线程池批量导入数据:


项目中,我使用 ThreadPoolExecutor 来实现线程池,创建任务列表,在循环中创建单一任务,加入到任务列表中。循环外使用线程池异步,并发的执行任务列表


遇到了哪些难点:


  1. 腾讯云实现头像
  2. 编辑距离算法
  3. 定时任务+Redisson分布式锁

具体的球友按照自身实际情况


用户登录问题:分布式除了使用Redis实现 ,还有哪些实现方式


Session 复制:利用 Tomcat 等 Web 容器同步复制

Session 前端存储:利用用户浏览器中 Cookie 保存 Session 信息

Session 粘滞方案:利用 Nginx 可以做四层 Hash 或七层 Hash 的特性,保证用户的请求都落在同一台机器上

Session 后端集中存储方案:利用 Redis 集中存储 Session,Web 应用重启或扩容,Session 也无需丢失。

上面四种方案,优先推荐第四种。

当然第四种方案需要一定的开发工作量,前期还没改造的过程可以选择 第三种方案中间过渡。



0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
辉
下载 APP