个人
自我介绍
1、面试官您好,我是蔡枫,本科就读于华南理工大学计算机学院
2、在校期间,我学习 Java 开发技术与相关组件,也跟着学校的创业团队的开发了一些项目
3、有几段实习经历,让我对团队中的开发流程有了一定的了解,并且也参与到了实际业务代码的编写
4、我与您公司岗位比较匹配:中台数据转发、、银行数字化转型、、
5、我的求职动机:挑战性,成长,机会,,自己清晰的职业规划,表示愿意长期从事这个岗位,,自我推荐。
我觉得我对所从事的每一个项目都很努力、负责、勤勉。我在努力成为一个能够不惧解决困难和能够持续学习的人。校园经历?
- 大学里最大的收获:在母校的关怀中茁壮成长,敢于尝试,从课内学习、科研、项目经验都积累了,,(因为学校鼓励我们敢于尝试,又会包容我们犯错,激励我们成长)
- 重来一次哪方面可以做的更好:多融入社会,多尝试新东西,把技能学的更加深入、、
- 挂科:确实挂了数学,主要原因是刚入学没有适应大学的这种学习模式(上课没学进去,课后也没补上来,或者说不知道如何自学)后面的课程我虽然有的在课上没学到什么,但是课后会主动地通过网络课程、技术网站等方式增进了解,也是增强了信息查找和自我学习的能力、、
- 参加了什么比赛,实验室项目?
参加过学院的acm竞赛,,到老师的实验室学习过,参与过一些科研学习的项目,发布过一篇论文。我积极参与实践,有一些项目开发经验,有三段实习经历。。。 - 你的论文?
我参加了一个“深度学习-图像处理”项目。五周的时间里,通过导师的授课讲解与指导,我拓展了该领域的专业知识,接着着手阅读文献和动手做实验。之后,我便与小组成员紧密合作,从主题确定,到文献的深入研读,完成论文写作,最终也发表了一篇论文。主要是希望接触学习人工智能这一块的知识(在学校没有机会和资源,,,) - 说一下你的社团活动?
我在华工青年志愿者指导中心宣传部担任了为期一年的(副)部长,这将我的摄影能力和对志愿服务的热情结合起来。我多次承担志愿活动现场的拍摄任务,用相机展现志愿者们的奉献精神,通过青志公众号推文等形式在校园中传播志愿精神。
你对本公司的情况了解吗?为什么选择我们公司?
1、对公司的了解:、、(行业的前景+公司的规模+公司在行业中的地位+特色产品)
2、自己跟岗位的匹配:、、(结合岗位要求+自我经历)
3、符合自己的职业规划:、、了解 Java 后端开发这个行业岗位吗?是否符合期许?
我认为 Java 后端开发是一个非常有挑战性的领域,开发能够为人们的生活带来便利的软件,对我来说是有趣的。在互联网企业应用广泛,有活力,发展前景好??
Java 作为一门强大而灵活的编程语言,具有广泛的应用领域,尤其在企业级应用开发中表现出色。
我在大学期间学习和做项目的过程中接触到了Java编程,并且在后来的时间加强了对相关技术的学习。我期望能够在一个具有挑战性、创新性和学习机会的团队中工作,我也希望自己能成为一个能够解决困难和不断学习的人。Java开发是一个不错的领域。“想到一个什么样的平台发展?”
我希望能够在一个具有挑战性的环境中工作,可以让我不断学习和提升自己。
我注意到贵公司在(行业/领域)取得了显著的成就,我相信我的Java开发技能可以在这里发挥出色的作用,我认为通过在这样一个领先的平台上工作,我将有机会为公司的发展和创新做出贡献,与公司一起成长。“对于第一份工作,你更看重什么?”
- 技术挑战和学习机会: 对技术挑战有热情,渴望学习新技术。希望这份工作能够提供丰富的项目经验,快速成长、、
- 导师与团队: 当然我希望积累团队协作、项目开发的经历,与不同的人合作,分享知识并共同解决问题。对我的职业生涯进行规划、、
- 公司文化和价值观: 强调你对公司文化和价值观的认同。你可以说你更看重一份工作能够与你的价值观相符,让你在一个积极、支持性的工作环境中工作。
认为怎样是好的开发工程师?
1.技术深度和广度:了解Java语言的方方面面,包括基础语法、多线程、IO等,熟悉常用的框架和工具。以及其他相关技术
2.问题解决能力:具有良好的问题解决能力。能够独立分析问题、理解需求、提出解决方案,并快速有效地实现。
3.代码质量:写出高质量的、可维护的代码。注重代码规范、模块化和可测试性。
4.团队协作:良好的团队协作能力是软件开发中至关重要的一环。有效沟通、分享知识,并能够与团队成员协作解决问题。
5.持续学习:技术日新月异,一个好的开发者应该保持持续学习的习惯,关注新技术的发展,随时准备适应行业的变化。
6.创新思维:善于提出新的、创造性的解决方案,对于提升产品和团队的效率具有积极的作用。
7.用户导向:理解产品和项目的业务需求,站在用户的角度思考问题,以用户体验为中心。
实习(骏伯)
广州骏伯网络?
使命:让移动互联网营销简单高效; 价值观:创造价值,分享价值; 愿景:做最受信赖的移动互联网营销服务商;
产品研发中心 - 应用开发部-基础建设组 - Java开发实习生 - 2024.1.8 ~ 4.12介绍一下实习经历、、
- 岗位职责:互联网营销行业公司,主要接触了公司核心的拉新系统的迭代开发,另外独立开发了公司内部的报表平台的接口
- 一个项目:其中拉新系统让我印象深刻、、
- 项目是什么:拉新指的是给例如 APP 拉取新的用户,实现方法是 我发根据 APP 的要求投放广告到如 抖音 等媒体平台,那么就会产生广告的曝光、用户点击等数据消息,需要转发给 APP 端。我方的拉新系统就在消息转发过程中,进行一个消息拦截的工作。具体来说,消息会先发送到我方拉新系统的mq,一方面进行了kbs的削峰,然后根据需求和策略进行拦截处理,最后才转发给 APP,,
- 简化版(非技术介绍):我方投放广告,接收“上游”的数据,感觉业务逻辑拦截以及一系列处理后,转发到“下游”;一方面进行了前后行为解耦,一方面削峰处理,为客户提供合适的数据;
- 为何这样做:这样,就给企业提供了符合要求的消息数据,我方获得收益
- 负责的工作:就是参与拉新系统的迭代开发,我负责数据拦截这一部分,具体来说实现了白名单功能,,
- 有什么成果:,,实现联调,,节约成本
- 最大的收获:
- 最大的成果:
- 重来会改变:
拦截到底做了什么??
- 通过 stream() 调用一系列方法:
- 参数前置处理(initPreValidate)(一些通用逻辑,比如点击数据ID、时间字段的初始化)。
- 参数校验(isValid)(校验点击数据是否有效,如果无效则不发给客户,比如媒体可能会将用户曝光数据发过来,此时不需要发给客户)。
- 参数后置处理(initPostValidate)(一些带有复杂业务逻辑的处理,比如RTA拦截)。
- 将校验通过的点击数据发给客户(transferToCustomer),http请求。
- 保存数据到数据库/缓存(save)。
- 内部处理逻辑(在initPostValidate部分,进行RTA拦截)
- 拦截指什么:设置状态为 NON_CLICK_NOT_TRANSFER_TO_CUSTOMER,后续代码流程识别出此状态后,不会将该数据发给客户。
- 拦截逻辑:
- 校验点击数据是否有效,如果无效则不发给客户,比如媒体可能会将用户曝光数据发过来,此时不需要发给客户
- RTA拦截:对于某些客户,我方在发送点击数据给对方时,需要调用客户的接口进行确认,判断当前用户是否是客户的目标用户,如果不是,则不发送点击数据给客户。则设置状态RTA_EXCLUDED,后续代码流程识别出此状态后,不会将该数据发给客户。
- 走RTA拦截,有一些前置条件,包括:
1、业务方指定了客户点击监测链接ID为RTA链接(客户的点击监测链接是客户提供过来用于接收我方点击数据的接口)(RTA链接是一个标记,标识当前点击数据发给客户前,要先调用客户的RTA接口过滤一道,最终只发送客户需要的用户)
2、如果当前数据类型为曝光,且曝光总数与点击总数的比例小于requestRate(默认为4:1)
对于满足前置条件的数据,则发起RTA请求,将结果记录下来(结果指的是客户是否接受当前用户,即是否参竞-isParticipated),用于业务方后续使用 - 白名单:为实现整个转发过程的联调,不拦截内部测试设备号(可能遭到rta拦截),即使客户不接受当前用户(内部测试手机),不设置状态RTA_EXCLUDED,此时后续流程会正常将该数据发给客户
- 可以用spring的设计模式或者技术吗???
- 策略模式,
- aop非业务,,暴露接口给监控系统
- 通过 stream() 调用一系列方法:
kafka 架构?kafka 如何实现高性能,高吞吐量?kafka 消费模式?如何不消费重复数据,顺序消费数据?如何不丢失数据?kafka内部是怎么实现限流的?、、、
你们项目中为什么要用消息队列? MQ 的作用是什么?
- 【异步】拉新系统接收媒体数据存放于 kafka,再消费即拦截处理后才转发,涉及io、阻断、调用客户接口、数据库、、
- 【削峰】接口接收2000qps的请求,以 200kbs 消费 mq中的数据,解决系统前后处理能力不一致的问题
不使用kafka,如何优化消息前后处理速度不一致的问题?
- 异步处理:将消息的后续处理逻辑设计成异步执行,可以使用 Java 中的线程池或者异步任务(CompletableFuture)来实现。
- 使用线程池:用
ThreadPoolExecutor
或者ExecutorService
来创建线程池,然后将需要异步执行的任务提交到线程池中。线程池会自动管理线程的创建、执行和销毁,可以有效地减少线程的创建和销毁开销。1
2
3
4
5ExecutorService executor = Executors.newFixedThreadPool(10); // 创建固定大小的线程池
executor.submit(() -> {
// 异步执行的操作,例如IO操作、数据库操作等
});
executor.shutdown(); // 关闭线程池 - 使用异步框架:有些框架提供了异步执行的支持,例如Spring框架的
@Async
注解。通过在方法上添加@Async
注解,可以将方法变成异步执行的方法。1
2
3
4
5
6
7
public class MyService {
public void asyncMethod() {
// 异步执行的操作
}
}
- 使用线程池:用
- 批量处理:将一批消息聚合在一起批量处理,而不是单个消息逐一处理。这样可以减少处理的次数和开销。
- 并发处理:考虑使用多线程或者并发框架来提高处理效率。注意处理任务的并发性要合理控制,避免因并发导致的资源竞争和数据一致性问题。
- 异步处理:将消息的后续处理逻辑设计成异步执行,可以使用 Java 中的线程池或者异步任务(CompletableFuture)来实现。
白名单功能如何实现?
- 白名单使用逻辑:1、先查看是否在白名单中(认为是目标用户)2、若不在白名单中,再调用户提供的接口进行RTA拦截(目标用户判断)
- 如何使用:直接查本地缓存caffeine的白名单,因此,必须保证本地缓存与Redis数据的一致性!!(事实上有20min延误)
- 白名单在Redis中的保存形式:一个 Set
- 白名单如何维护:需要新增时(上线前)手动Postman调接口,使用 SADD 命令向 Set 中添加一个或多个成员(事实上在数据库中保存了完整的精准的数据,需要时从数据库中同步)
1
SADD whitelist member1 member2 member3 # 白名单的 key-value
- Redis 数据何时过期?可以调用 Redis 的 EXPIRE 命令为单个键(Key)或整个 Set 设置过期时间,也可以通过 SETEX 命令一次性设置键的值和过期时间以确保设置值和过期时间的原子性。
1
2EXPIRE myset 60 # 设置 myset 整个 Set 结构的过期时间为 60 秒
EXPIRE myset:value1 60 # 设置 myset 中的 value1 元素的过期时间为 60 秒 - Redis-MySQL-caffeine数据一致:Redis 提供了键过期时的通知功能,可以通过配置 Redis 的 notify-keyspace-events 参数来开启过期事件通知。在 Redis 配置文件中设置 notify-keyspace-events Ex,表示开启键过期事件通知。
设置redis数据过期时长为20分钟,到期后,会触发数据库查询,同时会将数据加载到本地缓存中,用于接下来一个20分钟;
为什么需要Redis+caffeine二级缓存?
- 关系数据库(Mysql)数据最终存储在磁盘上,每次读取会因为磁盘本身的IO影响读取速度,所以考虑Redis这种内存缓存。
- 内存缓存(Redis)确实能够很大程度的提高查询速度,但也许避免同一查询大量的并发查询,也会有明显的网络IO上的消耗。
- 那我们针对这种查询非常频繁的数据(热点key),可以考虑存到应用内缓存如caffeine,当应用内缓存有符合条件的数据时,就可以直接使用而不用通过网络到redis中去获取;另外我个人认为,可能对于一些“常规业务无关”的数据,也可以放在本地缓存,避免对Redis查询、、
本地缓存与Redis不同步、、
- 延时双删:参考redis与mysql缓存一直方法,先删除 Redis存数,再更新 MySql,延迟几百毫秒除 Redis存数据,这样就算在更新 MySql时,有其他线程读了Mysql,把老数据读到了 Redis中,那么也会被制除掉,从而把数据保持一致
- 定时刷新:设置redis数据过期时长为20分钟,到期后,会触发数据库查询,同时会将数据加载到本地缓存中,用于接下来一个20分钟
- 异步更新:在应用中实现异步更新机制,当 Redis 中的数据发生变化时,异步地更新 Caffeine 本地缓存中的数据。可以使用消息队列或者异步任务来处理更新操作,确保更新操作不影响应用的正常运行。
- 手动更新:更新 Redis 缓存后,由业务代码手动触发本地缓存的更新操作。
如何保持Redis与数据库一致?
- 延时双删:对于读数据,我会选择旁路缓存策略,如果 cache 不命中,会从 db 加载数据到 cache。对于写数据,我会选择更新 db 后,再删除缓存。
- 针对删除缓存异常的情况,我还会对 key 设置过期时间兜底,只要过期时间一到,过期的 key 就会被删除了。
- 除此之外,还有两种方式应对删除缓存失败的情况,都是异步操作:
- 消息队列:重试缓存的删除
我们可以引入消息队列,将第二个操作(删除缓存)要操作的数据加入到消息队列,由消费者来操作数据。
如果应用删除缓存失败,可以从消息队列中重新读取数据,然后再次删除缓存,这个就是重试机制。当然,如果重试超过的一定次数,还是没有成功,我们就需要向业务层发送报错信息了。如果删除缓存成功,就要把数据从消息队列中移除,避免重复操作,否则就继续重试。 - Canal+MQ:订阅 MySQL binlog再操作缓存
订阅 MySQL binlog,再操作缓存「先更新数据库,再删缓存」的策略的第一步是更新数据库,那么更新数据库成功,就会产生一条变更日志,记录在 binlog 里。
于是我们就可以通过订阅 binlog 日志,拿到具体要操作的数据,然后再执行缓存删除,阿里巴巴开源的 Canal 中间件就是基于这个实现的。
Canal 模拟 MySQL 主从复制的交互协议,把自己伪装成一个 MySQL 的从节点,向 MySQL 主节点发送 dump 请求,MySQL 收到请求后,就会开始推送 Binlog 给 Canal,Canal 解析 Binlog 字节流之后,转换为便于读取的结构化数据,供下游程序订阅使用。
- 消息队列:重试缓存的删除
报表平台的开发流程?
- 根据产品原型图设计数据库表,主键自增,,
- 使用junboGenerator插件生成表结构对应的MyBatis代码(DO, BO, Mapper文件),用于操作数据库。
- 实现分页功能,大致步骤包括:
①【newenergy-api】定义XXXApi接口及page方法
②【newenergybg-service】定义XXXService接口及page方法
③【newenergybg-service】定义XXXApiImpl类(Controller),实现XXXApi接口及page方法,通过调用XXXService完成分页查询数据的操作
④【newenergybg-service】定义XXXServiceImpl类,实现XXXService接口及page方法,通过MyBatis分页插件及XXXMapper的查询方法,完成分页查询。
⑤【newenergy-api】发布XXXApi:修改版本号(xx.snapshot),发布新的jar包(包含新的XXXApi接口)到 Maven 仓库;
⑥【newenergy-web-admin】引入最新的XXXApi:更新maven,依赖新版本jar包,以使用新的XXXApi接口
⑦【newenergy-web-admin】定义XXXWebApi类及page方法(Controller),通过XXXApi的page方法,完成分页查询。 - SOA架构,服务关系:
【newenergy-api】:定义接口信息,同时被【newenergybg-service】和【newenergy-web-admin】依赖
【newenergybg-service】是【newenergy-api】的实现,实际的服务端;
【newenergy-web-admin】接收前端请求(防止暴露实际服务端),从 maven 获取 jar 包反射获取接口和实体类信息。
实际请求发送流程为:前端客户端程序发起请求 ->【newenergy-web-admin】XXXWebApi.page -> 【newenergybg-service】XXXApiImpl.page -> 【newenergybg-service】XXXServiceImpl.page -> 【newenergybg-service】 XXXMapper.selectByExample - 参数信息:
Api方法中:XXXRequest、XXXResponse,在【newenergy-web-admin】XXXWebApi.page方法上加了 @JunboResponse,,,
分页查询entity类:由于需要返回的数据是由多表查询而来,任一 BO 或 DO 都没法涵盖所有属性字段。所以新增一个 类 ConvCallbackRuleDailyReportPageItem,要在 mapper.xml 里修改 resultMap 中查询数据与返回值的对应关系,在后续数据转换的过程中主要前后类的字段的对应。 - 集成测试:本地启动newenergybg-service服务和newenergy-web-admin服务,通过postman调用接口进行测试,期望结果是,查出来的结果与数据库中的数据一致。
- 协同开发:git
分页查询细节、、
- 先到 “a表” 获取第i到第i+size行的“广告报表数据”(广告id,报表数据类型,时间,,),再根据“广告id”到 “b表” 关联查询该广告的详细信息(客户方,创建时间,,)
- SQL:
select * from a left join b on a.id = b.id limit 9, 10 where a.id < 10
- 执行 FROM 和 LEFT JOIN 操作,将表 a 和表 b 进行关联查询。
- 然后根据 WHERE 条件进行过滤,筛选出 a 表中 id 小于 10 的数据。
- 最后应用 LIMIT 9, 10,表示从第 9 行开始,获取 10 行数据,即获取 id 小于 10 的数据中的第 10 ~ 19 行数据。
- 优化:在查出表 a 的数据后先进行分页(使用子查询或者临时表来实现)再对表 b 进行关联查询。好处在于:减少不必要的数据传输和处理,提高查询效率和性能。
1
2
3SELECT a.*, b.*
FROM (SELECT * FROM a WHERE id < 10 LIMIT 9, 10) AS a
LEFT JOIN b ON a.id = b.id;
为什么不考虑转正?
应届生自然想去大平台,渴望挑战性和创新性的项目,,骏伯是一个比较小的公司,业务是互联网营销行业的,可能就会缺少一些技术积累,,,遇到了什么困难?
环境架构都已经配好并且部署在在线环境中,对组件的使用也封装好了,难的难在对实际业务的理解
我个人开发中遇到的crud不难。比较麻烦的是理解公司的开发模式??使用插件生成BO, DO, Mapper,,工作中学习到了些什么?和同事沟通了什么?
工作方面:熟悉团队开发流程(敏捷开发,需求澄清和故事点评估), k8s,掌握git的开发使用,单元测试??
技术方面:mq的选型与使用、枚举类型直接对应数据库的INTEGER??配置、SOA架构、、(高版本Java的特性(虚拟线程、模式匹配、lambda、ZGC、GraalVM-aot),高并发->NIO、协程、虚拟线程,单元测试)如何保证代码质量?
单元测试??+测试在项目开发中,什么时候让你感到获得了成就感?
1.项目完成阶段: 成功地完成一个项目的不同阶段或整个项目时,会带来成就感。2.解决难题: 遇到复杂的技术难题,经过努力和钻研后成功解决,这种时刻会让你感到非常有成就感,特别是那些曾经让你感到困扰的问题。3.用户满意。 4.团队协作: 项目中的团队合作是一个重要的方面。当你与团队成员协同工作,成功地推动项目的进展,共同克服了困难,整个团队的成功会带来强烈的成就感。5.学到新知识: 在项目中学到新技术、工具或方法,应用这些知识解决实际问题,这种学习和应用的过程本身就是一种成就感。6.项目的成功实施: 当项目成功实施,交付给用户并产生了积极的影响时,你会感到自己的努力和贡献是有意义的。7.持续改进: 成功地推动了项目的持续改进,通过引入新的工程实践、工具或流程,使项目更加高效和可维护。
实习(创世)
“牙医星球”小程序,做了什么?
- 接口设计?
根据用户提供的功能清单和产品原型图,结合已有的数据库表字段,尝试设计了小程序“个人中心”部分的接口以及相关的数据库字段设计。
例如,根据用户id查询和修改用户信息,分页查询用户在这个小程序上报名的课程列表,查询用户学习在线课程的记录。
同时,也设计了在线课程学习记录表,按照用户id分区创建不同的线上课学习记录表,避免把所有用户的学习记录放到一张表中。其中“连续学习天数”这个字段,放到了user_info表中作为用户属性字段;同时在user_info表中增加了一个“最近学习日期”,在更新“连续学习天数”时可根据“最近学习日期”判断是否连续,同时将“最近学习日期”更新。 - 视频弹幕功能?
使用 WebSocket 协议,在一个持久连接上进行全双工通信,实现客户端和服务器之间的实时通信。与传统的HTTP通信相比,减少了网络开销和延迟。
使用 ws 实现实时弹幕的功能:客户端与服务端建立 ws 连接后,使用 WebSocket包中的Session类保存与这个客户端的连接会话,根据ws 连接中携带的用户的connectionId,将这个session保存在静态的线程安全的ConcurrentHashMap中,同时在redis中创建/刷新该用户信息;当服务端收到客户端通过ws连接发送的消息时,从reids中找到所有 最近70s内创建/刷新的 用户连接的connectionId,在Map中找到对应的session,给用户端发送这条新弹幕,同时刷新redis中的用户信息。
第一次接触http以外的协议,websocket协议是http的升级,服务端接口使用的是@ServerEndpoint(“/“)获取连接信息。对于获取connectionId这个请求,应该在ws连接之前发生,所以使用一个controller实现获取connectionId请求,随后客户端使用js代码调用ws接口,建立ws连接。在开发过程中,发现有关弹幕的service类无法在ws接口中正确注入,所以建议把(通过mybatis)保存弹幕信息到数据库这个行为也分开在controller中实现,点击“发送弹幕”后,先调用controller保存弹幕信息,然后调用ws接口实现实时弹幕。
- 接口设计?
编程平台项目,做了什么?
- 项目整体情况:一个在线少儿编程竞赛平台,学生登录平台,在竞赛时间内获取试题,答题和提交。构建在SSM + SpringBoot上,有统一的返回结果格式 JsonResult,统一的成功/失败返回码。
- 学生登录:
- 生成图像验证码uuid:UUID生成验证码唯一标识 uuid,Hutool 库生成一个圆形验证码。将 uuid 和 验证码的base64编码 返还前端。将验证码标识和验证码内容以键值对的形式(uuid,code)存储到 Redis中,有效期为60秒。
- 发生短信验证码sendsms:同时以 JsonResult给前端返回该手机号下的所有学生账号(以label、value形式,返回数组 List<Map<String, Object>> stu)因为一个家长的手机号可对应多个孩子的学生账号
- 登录:使用手机号+学生姓名+密码登录。验证密码是否正确(base64编码+md5加密【不可逆】后,与数据库中存的密码去除头四个尾两个字符后比较),验证码uuid是否存在(返还给前端的标识)且正确(用户输入的验证码),
- 修改密码:一系列的判断,提交是否为null或空、账号是否存在、新密码是否满足给定的正则格式,接着要与数据库中的原密码(可)和同一登录账号下其他学生密码(不可)判断是否重复。用户输入的密码存入数据库,要经过:base64加密,和项目密钥连接后进行 MD5哈希加密,再通过randomTest.getRandomStr()随机增加到前4个字符和后2个字符。
- 编程题判题:
- @Transactional(rollbackFor = Exception.class) 声明事务,将提交编译题方法
getCompileAnswer
包裹在一个数据库事务中,抛异常后回滚。 - 判断学生id存在,是否在比赛时间,是否已提前交卷(有scoreRecord记录)
- 使用 restTemplate给布置在服务器上的”判题机”发生编程题判题请求,返回判题结果
- 如果没有提交记录,新增compileAnswer,判断剩余提交次数;如果此次提交编程题成绩大于原纪录中的,更新记录
- 返回前端:(success: ; resultCode: ; resultMsg: ; data:通过样例数,平均时间,平均内存)
- @Transactional(rollbackFor = Exception.class) 声明事务,将提交编译题方法
与产品经理,前端沟通?
原来使用coding代码协同和项目管理,在蓝湖放了原型设计,通过微信沟通。后面统一改用飞书。
先开一个项目启动会,确定如静态页面,接口开放,前后端连接调试的进度,时间管理。。??
开发过程里,我通过看产品原型进行理解,结合项目代码和文档理解,开发接口时与前端对接。。。你遇到的最大的挑战是什么?怎么解决的?
一开始的时候,我虽然有ssm,mybatis基础,但是等于一些注解,方法还是一知半解,而且没有看过项目代码,不会看接口文档,没用过git等,,一整个就是非常无从下手。后来就是硬着把需求相关的代码看完,每个小细节都自己查方法或者问同事,从最简单的一个需求开始一个个解决,测试,提交,逐渐上手。当然后面也把缺的技术补上了。
(技术上遇到的困难,应该就是复杂的业务逻辑吧,如编程题判题)
项目1(跑个腿)
“校跑跑”校园代拿平台 https://www.naoffer.com/course/class/302
- 项目描述:”校跑跑”平台是一款致力于解决大学校园内代拿服务需求的创新型应用,提供方便快捷的外卖、快递、文件等代拿业务,同时确保支付双方的信用和流程的可跟踪
- 主要工作:
- 在任务发布模块,通过产品原型总结出代拿服务任务模型,并使用双值枚举的方式对类型、数量、状态等进行存储。
- 在任务列表模块,实现了多筛选和多排序条件下的动态分页列表查询。
- 使用数据库悲观锁,解决同一跑腿任务的超卖订单问题,实现抢单唯一。
- 为代拿双方的陌生人服务安全性,对每个状态进行流水记录。流程状态切换中实现了照片上传的可靠性,为了节省服务器带宽,使用腾讯云 COS 直传方案,提供预签名给前端,保障了 COS 的安全性。
- 在接单前,需要接单人支付押金,实现押金支付、押金退还的事务处理。
介绍一下跑腿项目!!
- “校跑跑”是我们学校创业团队做的一个项目,后续会上线运营。它是根据校园中的真实的外卖、文件等物品代拿需求而设计的,另外同学看到送货路线与自己顺路可以顺手接单跑腿。同学们在平台上发布订单,接单,支付,同时能够确保支付双方的信用和流程的可跟踪、、
- 我参与了项目中几个模块的后端开发。(考虑到校园内用户量和流量量级不大,使用的是单体架构,对于存在的订单超卖等一些场景问题,参考了一些别的项目中的做法);我做的模块里面难点比较多的:
- 一个是跑腿任务的发布模块,这个模块一是要对信息进行非法过滤,另一个也要基于redis实现非重复支付的方案
- 然后在详情模块,针对学生代拿需求比较聚集如午饭的情况,会导致多个人同时抢列表的第一个,导致出现并发问题,我这里使用了悲观锁来解决
- 另外,要在配送过程中,如何去保证双方陌生人的信用安全?比如说在取货的时候,怎么能够知道是跑腿人去拿的货?而不是别人拿着这个验证码去拿到货,或者是说物品送到了,但是说没送到,或者、、
我们采用的是基于拍照确定地点的方式,比如他到现场,拍照上传,我们才给他公开取货码,他必须在五分钟之内取货,再拍照片,进行验证、、那这个地方就会产生很多的图片,传统的直传方案,会对服务器带宽造成很大的影响,所以项目采用了阿里云或者腾讯云的直传方案,解决了有效性和跨域的签名 - 第四个押金模块就可以不说了。事务。。
你做过最有挑战的项目?难点是、、
- S:背景 - T:任务 - A:举措 - R:结果
项目背景
- 我参与学校创业团队(非全职,有需求就去)的商业项目,目前还未(准备在南航)上线运营,产品需求真实,产品业务做的都是核心的(而一般的实习都是打杂)
- 需求分析:发单人懒的动弹,需要校内代拿服务;接单人查看送达地点与宿舍很近,回宿舍路上顺便接个单
- 竞品差别:美团跑腿是根据点到点距离计算费用,我们是根据校内距离不重要,是点到面或者是点到线,也就是这个学生的终点附近的也可以顺手去送,所以可以实现单价比较便宜,一单正常是两块钱
- 项目架构:单体项目 SpringBoot + Maven
- 四大模块:跑腿需求发布、跑腿抢单和列表、双方状态和安全、押金和微信支付
- 产品规划:1、目前是第一版,极小版本上线,核心发布功能、接单功能、押金功能;2、双方信用和评价体系上线;3、集中引用第三方方案(即货物送达方+已经智能货柜)、盗窃监控
- 团队成员:产品经理*2,后端^3,前端^2
一、跑腿需求发布模块
- 产品原型(图)
- 数据库设计
订单id、发布人id、取货地点、收货地点、货物种类、货物重量、期望送达时间(datetime)、费用、订单状态、创建时间、修改时间 - 亮点难点
- (小亮点): 物品信息非法关键字过滤
提交时,使用小程序的过滤接口,对发起人的物品信息要素进行非法关键字过滤,并对手机号和“微信”“vx”等字眼进行正则查验,防止后序跑腿双方私下沟通, - (小亮点): 分类等信息使用双重枚举
对送货的类型、重量等固定有限项要素,要用多值举的方式实现,方便在前端接口和数据库里以字典id类型进行插入,前端传过来的url中携带的是id值(如1:食品、2:文件、、)而不是易错的字符串类型 - (大亮点): 后端防止重复提交(一个用户下了多次单)
(1) 目前是单机项目:在提交接口,使用并发方法(sychronized方法),使用redis随机Key来进行验证(前端生成随机key)
在下单页面加载时,在后端生成一个唯一的标识符(例如 UUID)作为订单提交的唯一标识符,将这个一次性的标识符存到 Redis。当用户点击提交订单时,在后端根据用户提交的标识符从 Redis 中获取对应的标识符。如果获取到了,则是首次提交,处理后返回提交成功,并且删除redis中的标识符;如果未获取到,则表示是重复提交。
(2) 后序推广到更多高校,变成分布式环境时,考虑升级到redis分布式锁
- (小亮点): 物品信息非法关键字过滤
防止重复提交的逻辑:
在下单页面加载时,后端生成一个UUID作为订单提交的唯一标识符,将这个一次性的标识符存到 Redis。当用户点击提交订单时,根据用户提交的标识符从 Redis 中获取对应的标识符。如果获取到了,则是首次提交,处理后返回提交成功,并且从Redis中删除;如果未获取到,则表示是重复提交。二、跑腿抢单和动态列表模块
- 产品原型
查看跑腿订单详细信息后点击“立即接单”,抢单后才可查看发布人信息(电话,取货码(在安全模块处理),备注)
跑腿动态列表通过排序、筛选,展现跑腿订单(接单人可以将自己宿舍作为收货地址进行筛选) - 业务逻辑
- 跑腿任务详情模块目前只做展示和下单,接单过程不在本模块。需要提供任务详情展示接口和抢单接口
- 列表模块需要考虑多条件动态排序、筛选,实现分页接口
- 抢单跑腿详情和订单支付的逻辑
跑腿详情状态有:1 等待抢单; 2 已被抢; 3 已确认(抢单后需要手动确定或取消,如果1分钟内不取消,自动变成确认);4 超时费单
(1) 某一用户点击抢单时,需要判断是否是1和2的状态,这两个状态都可以触发排队60s流程
(2) 如果是1,则用户抢单成功,这个时间详情状态变为2,其它用户只能等待60s(60S退出的时候,再做一次(1)r的逻辑)
(3) 如果(2)用户取消订单,则状态变成1
(4) 如果支付成功,则其它用户不能进入流程,已在流程中的依然等待
(5) 20分钟未支付的逻辑需要定时任务触发,详情变成1
- 亮点难点
- 在抢单模块,因为学生代拿时间集中,会造成同一任务的超卖订单,项目使用悲观锁解决(小规模并发)问题
并使用60s倒计时的方案,实现并发抢、已抢但放弃的场景 - 本模块多处使用定时任务(quartz schedule)更改订单状态,比如1分钟内自动确认和超时废单等
- 在列表模块,因为校内多地点的选择场景,实现多筛选、多排序下的动态分页接口
3.1排序项:最新(默认)、按金额从大到小
3.2筛选项:多地点、重量、送达时间、类型、数量
- 在抢单模块,因为学生代拿时间集中,会造成同一任务的超卖订单,项目使用悲观锁解决(小规模并发)问题
- 产品原型
乐观锁与悲观锁的区别?怎么用?
- 悲观锁:认为资源一定存在竞争,加悲观锁,具备阻塞特性,以保证多事务对统一数据的访问的安全性;
- 在并发量不大且冲突频率较低的情况下是有效的,悲观锁可以提供更加稳定和可靠的数据操作保护,提供较为简单和直接的控制方式;尽管乐观锁在并发量较小且冲突频率不高的情况下具有优势,但在数据修改频率较高、竞争激烈的情况下,悲观锁通常更加高效;
- 但是如果并发量很高或者冲突频率很高,则可能会导致性能问题和系统的阻塞。
- 使用方法:
- 查询订单信息并加锁:在抢单逻辑中,首先要查询订单信息并加锁,防止其他用户同时抢单。读和写是在同一步,查询并加排他锁,确保其他事务无法修改这些数据,直到当前事务提交或回滚。
1
2START TRANSACTION;
SELECT * FROM orders WHERE id = ? AND status IN (1, 2) FOR UPDATE; - 更新订单状态:如果查询到符合条件的订单,就可以更新订单状态并完成抢单操作,示例代码如下:
1
UPDATE orders SET status = 2 WHERE id = ?;
- 提交事务:完成操作后,需要
COMMIT;
提交事务来释放锁并保证数据的一致性 - ??处理超时情况:针对20分钟未支付的逻辑,可以使用定时任务来触发查询并加锁,然后更新订单状态为1(等待抢单状态)。
- 查询订单信息并加锁:在抢单逻辑中,首先要查询订单信息并加锁,防止其他用户同时抢单。读和写是在同一步,查询并加排他锁,确保其他事务无法修改这些数据,直到当前事务提交或回滚。
- 乐观锁:认为大部分情况不存在竞争,不加锁(不阻塞),使用版本号version判断是否修改(修改数据同时修改version)
- 在并发量大的时候,悲观锁用不了,可以考虑用乐观锁;CAS,MVCC是乐观锁的实现
- 实现方法:
- 版本号字段实现乐观锁:在数据库表中增加一个版本号(version)字段,数据类型通常选择整数。每次更新数据时,将版本号加一。在更新数据时,通过比较当前查询到的版本号与更新时的版本号来判断是否更新成功。
1
2
3
4
5
6
7
8
9
10
11CREATE TABLE orders (
id INT PRIMARY KEY,
order_id VARCHAR(50) UNIQUE,
version INT,
-- Other columns
);
-- 更新订单方法,使用乐观锁
UPDATE orders
SET version = version + 1
WHERE order_id = 'xxx' AND version = current_version; - 时间戳字段实现乐观锁:与之类似
- 注意事项:
- 在使用乐观锁时,需要保证更新操作的原子性,通常可以使用数据库事务来确保。
- 在比较版本号或者时间戳时,可以通过数据库的原子性操作来实现,例如使用
WHERE
子句中的条件来比较版本号或者时间戳。 - 当更新操作失败时,可以根据具体业务需求选择重试更新操作或者抛出乐观锁异常供上层处理。
- 版本号字段实现乐观锁:在数据库表中增加一个版本号(version)字段,数据类型通常选择整数。每次更新数据时,将版本号加一。在更新数据时,通过比较当前查询到的版本号与更新时的版本号来判断是否更新成功。
- 悲观锁:认为资源一定存在竞争,加悲观锁,具备阻塞特性,以保证多事务对统一数据的访问的安全性;
跑腿抢单的请求是直达数据库吗?可以优化吗?
- 是的。我们项目是第一版,目标也只是在南航一所学校先试点运营,用户量很小,每一个订单的抢单并发 评估过 1s不过超过5人。所以直接使用数据库锁方案。所以我们测试人员只给业务case,完全不做压力测试。
- 在量级很大的情况下,使用数据库的悲观锁来实现抢单唯一可能会导致性能问题和系统瓶颈。优化方案:
- 锁优化:尽量缩短悲观锁的持有时间,只在必要的操作时使用锁,然后尽快释放锁,可以使用事务管理来确保在合适的时候释放锁。尽量减少锁的粒度,比如只针对需要保护的数据进行锁定,而不是整个表或整个数据库。使用乐观锁。
- 使用缓存:对于频繁读取的数据,可以考虑使用缓存来减轻数据库压力,提高响应速度。
- 异步处理:对于一些非实时性要求较低的操作,可以考虑使用异步处理方式,将任务放入消息队列或异步任务队列中处理,减少对数据库的直接访问。
- 分布式架构:如果系统规模非常大并且需要处理大量并发请求,可以考虑使用分布式架构;1、微服务架构:将系统拆分出抢单微服务; 2、负载均衡:将请求分散到多个节点上处理,从而减轻单个节点的压力;3、分布式数据库:分担数据库的读写压力,提高数据库的处理能力和容量;4、分布式锁:确保在分布式环境下,同时只有一个节点(或者说一个进程)能够获取到锁,从而保证对共享资源的操作是互斥的,避免出现数据不一致或者并发冲突的情况。
三、跑腿双方状态与安全保障
- 模块说明:本模块是指在跑腿人接单后整体送货流程的状态变化,即针对任务详情状态的”进行中”,进一步扩展细化。包括发布人和接单人双方。
- 发布人和跑腿人的状态:其中234属于一个阶段,567属于一个阶段
- 任务已被接单
- 物品已被取到
- 物品未正常取到(物品损坏、没有该商品、取货人故意没取)
- 物品已损坏(取货和过程中,结束)
- 物品已通知送达(跑腿人状态)
- 物品确认收到
- 物品未确认收到
- 物品确认有问题(破损等)
- 任务正常结束
另外,本模块进行最基本的流程安全保障,即在送货人在取货和收货环节拍照确认;发布人在收货环节当面确认(后序加入可选收货码)。
- 确保跑腿人到达取货位置,才能显示取货码,防止每三方恶意盗窃,通过”拍照上传” + “5分钟之内上传取货拍照”的双重验证 (实际上,产品角度还有两个后期更可靠的方案,1是所有地点接入地图,以位置距离确认 2是商家可变二维码)
- 亮点难点
- 在用户跑单时,通过拍照上传(获取取货码) + 5分钟之内上传取货拍照 的双重验证,保证取货码不被第三方获取。
同时该方案造成大量图片的上传,为缓解服务器带宽压力,使用腾讯云C0S直传来代替传统的后端上传的流程 - 用户跑单会在双方产生将近10种状态,以送单人的角度设计状态的分类
- 在用户跑单时,通过拍照上传(获取取货码) + 5分钟之内上传取货拍照 的双重验证,保证取货码不被第三方获取。
腾讯云COS的参数是怎么配置的?
https://cloud.tencent.com/document/practice/436/9067图片直传那一块具体做了什么?
就是后端,使用的官方SDK,针对前端指定的cos文件夹 和指定的文件名,进行临时权限签名的生成, 同时也保证其它人和文件没有权限直传 保证cos安全性。四、押金和钱包事务模块
- 模块说明:因为业务上与钱的流水关系很大,需要单独分离是钱包模块,可以是记录流水、以及押金和收入的提现、发起人的退款记录等
- 亮点难点
1 押金的退还属于原路退回,主要接入对应支付渠道的退款接口,但是核心是退款流程分为两部分,一是退款成功,二是押金流水变更,两个阶段存在原子性,因为这部分业务,属于较低频型业务,所以使用事务方案,而不是补偿方案。
2 提现需要使用另外的支付宝公对私打款接口,在收取10%的平台费用后(不做个税扣除),进行批量打款。打款不做强可靠性,用户对提现和退款 不像支付要求那么高
???押金退款的事务?
- 押金的原路退回可能会破坏退款流水和押金流水的原子性,两个步骤必须一起进行,属于最常见的事务场景 1 退款流水状态变成“已退款” 2 押金退款接口返回成功
接口肯定得有返回值 正常逻辑不要总想着加异常 就算有可能出现异常 在service方法级别 一般都是内部处理 不抛出??
能不能理解为退款是调接口实现,押金流水是数据库操作???事务逻辑如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class RefundService {
private CrudService crudService;
public void refundAndChangeFlow() throws RefundException, CrudException {
try {
crudService.changeFlow(); // !!先调用流水变更的业务逻辑
退款(); // 这里是退款的业务逻辑,需要根据具体情况实现
} catch (RefundException e) {
退款撤销();
throw e;
} catch (CrudException e) {
throw e;
}
}
}
- 押金的原路退回可能会破坏退款流水和押金流水的原子性,两个步骤必须一起进行,属于最常见的事务场景 1 退款流水状态变成“已退款” 2 押金退款接口返回成功
升级成分布式、、
- 实现:把单体架构中的service调用变成了微服务的rpc调用,代码层面区别不大
- 难点:就是要解决网络的不可靠性。分布式架构无非就是把进程内调用变成进程间调用,跨网络、跨节点的网络调用在时间足够长、流量足够大的情况下,就要考虑网络超时的问题,设置超时时间,避免整个系统被拖挂。
- 读请求,超时重试
- 写请求,分布式事务
- 其他挑战:服务治理(服务发现,服务集群,负载均衡,优雅启停,熔断降级),数据一致性问题(对于开发更重要)
数据一致性
- 缓存与数据库:异步化
- 分布式事务
项目2(黑马商城+牛客论坛)
高校闲置资源交易系统
- 系统架构:SpringCloud + SpringBoot + Nacos + Redis + MySQL
- 项目描述:系统采用微服务架构,旨在为消费者提供一站式商品交易平台。通过细致的业务划分,系统分为用户模块、商品模块、购物车模块与支付模块,确保每个模块服务的高效、可维护、可扩展。
- 主要工作:
- 使用 Nacos 实现服务注册,消费者服务通过 Nacos 拉取和订阅服务。
- 引入 Redis 数据库,优化项目中登录验证码的使用,对需要频繁访问的数据进行缓存。
- 使用 Gateway 及拦截器实现了登录信息校验,避免各微服务中的代码重复。
- 通过 Sentinel 完成系统限流熔断功能,防止服务故障后影响整个系统运行。
单体架构改为微服务架构(分布式架构的一种实现)
微服务架构,是服务化思想指导下的一套最佳实践架构方案。服务化,就是把单体架构中的功能模块拆分为多个独立项目。
优点:粒度低、团队自治、服务自治登录的流程,登录状态的检验??
提交登录表单,登录请求 controller —> sevice —> Dao,查询、校验用户信息,生成jwt(用jwtTool生成token),返回登录信息和jwt(或登录失败信息),提示登录成功(失败)。登录成功后,用户在发送请求时(如购物车),在请求头中携带 Authorization(即jwt)用户登录。。redis怎么用的?
- ???Redis 结合 Gateway 完成登录校验(直接拦截后调用 jwtTool 验证不就行了)
- 使用Redis缓存用户信息:将user缓存到Redis中,获取user时,先从Redis获取。取不到时,则从数据库中查询,再缓存到Redis中。因为很多界面都要用到user信息,并发时,频繁的访问数据库,会导致数据库崩溃。变更数据库时,先更新数据库,再清空缓存;
- ???使用Redis缓存验证码:原本添加到session中,减轻服务器压力。将验证码存到Redis中,方便查询检验;
当⽤户点击刷新验证码时,服务端⾸先给当前需要登陆的游客,设置⼀个随机字符串(kaptchaOwner),⽤于标识当前这个游客,然后将随机字符串存⼊到cookie中,返回给浏览器,然后服务端的redis保存 “key:随机字符串,value:验证码”。接着⽤户输⼊⽤户名,密码,验证码,再次点击登陆时,服务端会从cookie中拿到kaptchaOwner,通过它,可以从Redis中得到正确的验证码,然后与⽤户输⼊的验证码做⽐较,看是否⼀致。
验证码需要频繁的访问与刷新,对性能要求很高;验证码不需要永久存储,通常在很短的时间内就会失效;分布式部署时,存在session共享问题;
Nacos 服务发现
- 消费者需要连接nacos以拉取和订阅服务,因此服务发现的前两步与服务注册是一样(引入nacos-discovery依赖和配置nacos地址),后面再加上服务调用即可
1
2
3
4
5
6
7
8
9private final DiscoveryClient discoveryclient;
private void handlecartItems(List<CartVO> vos) {
// 根据服务名称拉取实例列表,负藏均衡挑选一个实例
List<ServiceInstance> instances = discoveryclient.getInstances("item-service");
ServiceInstance instance = instances.get(RandomUtil.randomInt(instances.size()));
// 获取实例的TP和端口
URI uri= instance.getUri();
// ...发送请求
}
- 消费者需要连接nacos以拉取和订阅服务,因此服务发现的前两步与服务注册是一样(引入nacos-discovery依赖和配置nacos地址),后面再加上服务调用即可
Nacos 配置管理。
当微服务部署的实例越来越多,业务配置如 JDBC、日志、openfeign 时常变动,逐个修改微服务配置就会让人抓狂。
Nacos实现配置共享,配置热更新,动态路由
https://www.bilibili.com/list/watchlater?oid=961238101&bvid=BV1kH4y1S7wz&spm_id_from=333.1007.top_right_bar_window_view_later.content.click&p=34OpenFeign
- ??
- 最佳实践
网关 Gateway
- application.yml 配置;
1
2
3
4
5
6
7
8
9
10cloud:
routes: # 网关路由配置
- id: user-service # 1. 路由id,自定义,只要唯一即可
# uri: http://127.0.. # 2. 路由的目标地址 http 就是固定地址
uri: lb://userservice # lb(loadbalance) 就是负载均衡,后面跟服务名称
predicates: # 3. 路由断言(可多条),判断请求是否符合路由规则的条件
- Path=/user/** # 按照路径匹配,只要以/user/开头就符合要求
filters: # 4. 路由过滤器,,
- id: order-service # ...
# ...
- application.yml 配置;
网关登录校验。
- 基于jwt实现登录校验
- hmall.jks:密钥文件,加密存储
- application.yml:配置文件,配置密钥文件目录、别名、解析密钥文件的密码、、excludePath(不用登录校验的路径)
- JwtPropertities:加载 jw t属性配置的类
- AuthPropertities:加载 excludePath 属性配置的类
- SecurityConfig:加载jwt配置后,真正读取文件生成密钥的类,类本身声明为一个 @Bean;过程为注入配置,获取密钥工厂,读取密钥对
- JwtTool:jwt工具类,接收用户id与时间生成jwt密钥、解析token
- 各模块校验:登录在user模块,验证成功后得到token,后续使用每个微服务(购物车、下单,,)时,如果都要都要进行检验,会造成重复代码以及重复发送jwt秘钥造成泄露风险,,所以,在网关中,转发请求给微服务之前,进行jwt登录校验
- 基于jwt实现登录校验
如何登录校验?
具体来说,要定义一个(自定义)过滤器,放在pre阶段;在过滤器中实现校验业务逻辑,校验通过后才会向下执行(下面的过滤器),最后由 Netty 路由过滤器转发给微服务全局过滤器的作用也是处理一切进入网关的请求和微服务响应,与路由过滤器GatewayFilter的作用一样。 区别在于GatewayFilter通过配置定义,可以自由的指定作用的范围,配置自定义参数,使用灵活,但处理逻辑是固定的,难以自定义GatewayFilter; 而GlobalFilter可以自己写代码实现,实现需要的业务逻辑,需要自定义过滤器时大多会选择 GlobalFilter。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public class AuthGlobalFilter implements GlobalFilter, Ordered {
// 添加 @RequiredArgsConstructor 后自动使用构造器注入下面成员变量
private final AuthProperties authProperties;
private final JwtTool jwtTool;
@0verride
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 1.获取请求
ServerHttpRequest request = exchange.getRequest();
// 2.判断是否需要做登录拦截(使用 AntPathMatcher 匹配 authProperties 中的路径)
if(isExclude(request.getPath().tostring())){
// 放行(如 /user/login)
return chain.filter(exchange);
}
// 3.获取token
string token = null;
List<string> headers = request.getHeaders().get("authorization");
if(headers != null && !headers.isEmpty()){
token= headers.get(0);
}
// 4.校验并解新token
Long userId = null;
try {
userId = jwtTool.parseToken(token);
}catch(UnauthorizedException e) {
// 拦裁,设置响应状态码为401(只是抛异常的话响应500,看不出具体错误)
ServerHttpResponse response = exchange.getResponse();
response.setstatusCode(Httpstatus.UNAUTHORIZED);
return response.setcomplete(); // 结束
}
// TODO 5.传递用户信息
// 6.放行
return chain.filter(exchange);
}
public boolean isExclude() {
// ...
}
@0verride
public int getOrder() {
//过滤器执行领序,信越小,优先级越高
return 0;
}
}如何将用户信息传递给微服务?
对于单体架构系统,所有功能在部署在一个tomcat上,一个tomcat内部不同线程之间共享ThreadLocal;对于微服务架构,网关本身就是一个微服务,和其他微服务要通过 HTTP请求传递信息,把用户信息放在请求头中不会对业务造成影响,后续从请求头中取出用户信息、、
修改gateway模块中的登录校验拦截器,在校验成功后保存用户到下游请求的请求头中,使用ServerWebExchange类提供的API:1
2
3
4
5
6
7// 5.传递用户信息
String userInfo = userId.tostring();
ServerWebExchange swe = exchange.mutate().
request(builder -> builder.header("user-info", userInfo))
.build();
// 6.放行修改后的请求头(到下面过滤器链)
return chain.filter(swe);在后续的微服务中,通过拦截器,从请求头中获取登录凭证,进行登录校验,并保存在 ThreadLocal;
由于每个微服务都可能有获取登录用户的需求,因此我们直接在hm-common模块定义拦截器,这样微服务只需要引入依赖即可生效,无需重复编写。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19// 定义 springmvc 拦截器
public class UserInfoInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpservletRequest request, HttpservletResponse response, obiect handler) throws Exception {
// 1.获取登录用户信息
String userInfo = request.getHeader("user-info");
// 2.判断是否获取了用户,如果有,存入ThreadLocal
if(Strutil.isNotBlank(userInfo)) {
UserContext.setUser(Long.ValueOf(userInfo));
}
// 3.放行
return true;
}
public void afterCompletion(HttpservletRequest request, HttpservletResponse response, 0bject handler, Exception ex) throws Exception {
// 清理用户
UserContext.removeUser();
}
}最后,修改每个微服务的配置扫描文件,使其能够扫描到 hm-common模块中定义的 UserInfoInterceptor 拦截器; 注意:网关微服务不能引用 hm-common模块中的 拦截器,因为网关的底层不是 SpringMVC 实现的,无法加载SpringMVC拦截器的功能,会报错;1
2
3
4
5
6
7
8
9
10// 编写 springmvc 配置类
// 防止网关微服务加载此配置
public class MvcConfig implements WebMvcConfigurer {
@0verride
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new UserInfoInterceptor());
}
}如何在微服务间传递信息?
微服务项目中的很多业务要多个微服务共同合作完成,而这个过程中也需要传递登录用户信息;
方法同样是把用户信息保存到请求头,发送 Http请求。不同的是微服务之间发送请求通过 Openfeign,而网关发送请求是通过其内部的 http 请求方式(netty过滤器路由分发),,
拦截器(Interceptor),,
??
目的:让未登录用户不能访问某些页面
原理:在方法前标注自定义注解,拦截所有的请求,只处理带有该注解的方法。
拦截器:1.自定义拦截器 2.配置拦截器
首先验证用户(preHandle方法),如果用户存在,则在本次请求中持有用户,放进hostHolder里
经过controller后,返回到拦截器,拦截器再将用户信息存入model。
自定义拦截器需要实现HandlerInterceptor,然后重写preHandle(controller前执行),postHandle(controller后执行),以及afterCompletion(模板解析后执行)
配置拦截器:需要实现WebMvcConfigurer接口,然后重写addInterceptors方法,排除拦截静态页面。ThreadLocal(线程安全)
从上面的代码可以看出,ThreadLocal set赋值的时候首先会获取当前线程thread,并获取thread线程中的ThreadLocalMap属性。如果map属性不为空,则直接更新value值,如果map为空,则实例化threadLocalMap,并将value值初始化
ThreadLocalMap是ThreadLocal的内部静态类,而它的构成主要是用Entry来保存数据 ,而且还是继承的弱引用。在Entry内部使用ThreadLocal作为key,使用我们设置的value作为value。
通过当前线程对象的getMap()方法获取ThreadMap对象 然后将当前ThreadLocal对象作为key值存入map 这能保证线程内的资源共享而不同线程之间独立
- Sentinel
,,
项目系统(牛客论坛)
- 论坛系统项目(高校信息平台。。。)
- 项目描述:一个基本功能完整的论坛项目。主要功能有:基于邮件激活的注册方式,区别登陆状态为游客或已登录用户展示不同界面与功能。支持用户上传头像,实现了发布、评论帖子,发送私信等功能,以及点赞,关注与系统通知功能。
项⽬构建在 Spring Boot + SSM 框架之上,并统⼀的进⾏了状态管理、事务管理、异常处理。 - 核心功能与项目优化:
- 使用 Spring Email 辅助发送注册激活邮件,并且使用 Interceptor 拦截器赋予不同类型的用户权限,解决 http 无状态带来的缺陷问题,保护需登录才能查看的资源。
- 使用 Spring AOP 面向切面编程思想统一记录日志;
- 引入 Redis 数据库,优化项目中 Session 的使用并利用 Redis 实现点赞和关注功能。
- 使用 Kafka 消息队列构建异步消息系统,实现点赞关注与通知间削峰。
- 使用 Caffeine + Redis 实现两级缓存,优化了热门帖子的访问。
- 项目描述:一个基本功能完整的论坛项目。主要功能有:基于邮件激活的注册方式,区别登陆状态为游客或已登录用户展示不同界面与功能。支持用户上传头像,实现了发布、评论帖子,发送私信等功能,以及点赞,关注与系统通知功能。

- 介绍项目
- 梳理系统的项目背景以及整个系统架构设计与运转流程
- 技术上的亮点:”我在处理数据的过程中,实现了数据的一致性和可靠性,做到了数据零丢失”、“项目引入了规则引擎,其中解决了xxx的业务问题,使得工作效率极大提升”… 等等
- 业务上的亮点:”实现了业务隔离,不同类型之间的业务互不干扰,从原来的xxx提升到了、”参考自某平台的xx功XXx”能,从零开始实现了业务,使得平台收益增加了xxx”.. 等等
- 梳理项目还可提升的地方:无论是提高性能,还是提高工作效率,总会有的。这时候如果能吹下自己对比过某某公司的同类型系统,借鉴了某某某优点,基于目前自身的业务觉得还有哪里可以继续优化
算法
排列组合(C上n下m,A上n下m)
A上n下m
是排列,有顺序,表示m是起点(逐个减1,n是个数),从m中按顺序取n个数
Amn = m x(m-1)x(m-2)x(m-3)x … x(m-n+1);例如:A74= 8x7x6x5C上n下m
是组合,无顺序,表示从m中选出n个
Cmn = Amn / Ann; 例如: C84 = A84 / A44 = (8x7x6x5)/(4x3x2x1)
5万人进行年龄排序
“使用快速排序算法来进行年龄排序,它的时间复杂度通常为O(n log n)。
我会首先将人口数据存储在一个数组中,然后根据每个人的年龄进行排序。在排序的过程中,我会使用递归来不断地划分数组,并交换元素的位置,直到整个数组按照年龄有序。如果数据量较大,我也可以考虑一些优化策略,比如随机化快速排序来避免最坏情况的发生,或者利用多线程来加速排序过程。最后,我会对排序后的结果进行验证,确保排序是准确的。”智力题:25匹马选前3名,有5条赛道
将25匹马分成 A、B、C、D、E 5组,每组进行组内比赛,假设每组的排名就是A1>A2>A3>A4>A5(以A组为例),这里比赛5次
第6次,每组的第一名进行比赛,可以找出最快的马,这里假设A1>B1>C1>D1>E1,D1,E1肯定进不了前3,直接排除掉 D、E 两组
第7次,A2 A3 B1 B2 C1 比赛,可以找出第二、第三名。所以最少比赛需要7次???智力题:1000瓶酒,其中只有1瓶毒酒,10只小白鼠,如何1轮测试出来毒酒是哪一瓶?
用小白鼠喝这瓶酒or不喝这评酒分别用1、0表示。可以凑出1024种组合,大于1000种,所以可以给1000瓶酒按照这种方式编号。
需要十只老鼠,如果按顺序编号,ABCDEFGHIJ分别代表从低位到高位每一个位。 每只老鼠对应一个二进制位,如果该位上的数字为1,则给老鼠喝瓶里的药。
然后用对应的2进制码的方式给10只小白鼠喝酒,过一段时间之后。通过观察小白鼠是哪些编号死亡,哪些编号存活,可以分别用1和0表示,然后凑出来的2进制转10进制就是答案。智力题:绳子两头烧
现有若干不均匀的绳子,烧完这根绳子需要一个小时,问如何准确计时15分钟,30分钟,45分钟,75分钟。。。
15:对折之后两头烧(要求对折之后绑的够紧,否则看45分钟解法)
30:两头烧
45:两根,一根两头烧一根一头烧,两头烧完过了30分钟,立即将第二根另一头点燃,到烧完又过15分钟,加起来45分钟
75:=30+45
反问
一面最后的时候,面试官一般会问:你有什么要问我的吗?这个时候不要乱问,你可以问以下几个问题:
- 你们部门在做些什么?主要业务是什么?如果自己很荣幸的能够进入贵部门会负责些什么?
因为面试者就是这个部门的,通过他的回答,你也能够了解到这个部门正在做的产品和使用的技术。 - 岗位的发展情况、、如果我有幸应聘成功,公司对我会有哪些期望呢,
- 您认为我在哪些方面还存在着不足?
这是一个很巧妙的问题,因为它可以从侧面反映出你这次面试的结果。如果面试官带有指导性的回答出了你的不足,你需要补充的知识点,这样就代表你这次面试差不多了,应该是能好好准备二面了;如果面试官直言不讳的说你很差或者基础太弱这样的话,你也就知道凉凉了。 - 请问面试官对自己职业规划的建议?
面试官大概率是技术大佬或者工作过几年的前辈了,在社会上摸爬滚打了几年,知道的肯定比在校生多。这个问题既表达了对面试官身份的认可,也表现出求职者对当前这份工作得在意程度,并且还能得到技术大佬的分享,怎么看都不是亏本的买卖。 - 这个岗位所在的的团队是什么氛围?我这个比较外向(千万要说自己外向,不要说自己内向,原因不必多说了吧)
- 你们部门在做些什么?主要业务是什么?如果自己很荣幸的能够进入贵部门会负责些什么?
关于公司,岗位有什么想问的?
1.关于公司:“公司的核心价值观是什么?” “能否分享一下公司的发展战略和未来规划?” “公司的文化是怎样的?”
2.关于团队和领导: “我将会与哪些团队成员合作?” “对于这个岗位,我将直接报告给谁?””团队的工作氛围是怎样的?”
3.关于岗位: “这个岗位的主要职责是什么?绩效评估标准?” “在这个岗位上,有没有机会进行培训和专业发展?”
4.关于工作环境:“公司对于员工的工作生活平衡看法?公司的灵活工作政策?” “关于工作场所和设施有什么特别的安排?”
5.关于发展机会: “公司是否鼓励内部晋升和职业发展?” “可以谈谈员工在公司成长的例子吗?”
6.关于期望:“对于这个职位,你们期望新员工在短期和长期内能够做到什么?” “公司对于创新和改进有怎样的期望?”
7.关于团队协作:“在团队中如何促进协作和团队精神?” “有没有定期的团队活动或培训?”
8.关于招聘流程:“对于这个岗位的招聘流程是怎样的?” “预计多久会有关于我的招聘决定?”??你如何评价我们的面试过程?
1、积极、建设性的角度:强调你对面试过程的积极印象,比如面试官的专业性、问题的多样性和挑战性等。表达感激之情,感谢他们给予的机会并展现出你对公司或团队的兴趣。
2、注意事项和改进建议:提及你认为面试过程中可能的改进点,但要以建设性的方式提出,不要过于批评或负面。例如,可以提议增加某些技术领域的深入问题,或者更多关于公司文化和团队合作的问题,以更好地了解公司的工作环境。??有什么要分享给面试官的?
1.、展示你的准备和兴趣:提到你在公司产品、服务、项目方面的研究和了解,表现出你对公司的热情和积极性。说明你对该公司的价值观、愿景或在该领域的兴趣,并解释为什么你认为你的技能和经验与公司的需求相匹配。
2、自我评价和亮点:强调你认为自己最突出的技能、经验或个人特质,并解释为什么这些对公司或团队会有价值。提供具体的案例或经验,展示你的领导能力、团队合作精神、解决问题的能力等方面的优势。
3、职业发展展望:谈论你对未来职业发展的期望,并说明你希望在该公司或类似领域发展自己的职业生涯。表现出你对个人成长和对公司做出贡献的愿望。
HR 面
对公司文化的理解和价值观的认同
- 先去了解一下公司的文化和公司的优势之处,这样在被问到为什么选择本公司的时候能够把自己对公司的了解和优势说出来,体现自己的诚意
- 华为:”我对华为的文化印象深刻,特别是关于坚持自主创新、追求卓越和不断学习的价值观。我接受的教育,使我深刻理解和认同华为一贯的追求卓越的精神。我认为,华为强调的团队协作和开放式沟通也非常符合我的工作风格。我期待能够在这样一个注重技术创新和全球合作的公司中发展自己的职业生涯。”
- 腾讯:”我对腾讯的文化深感兴奋,尤其是关于用户至上、创新驱动和团队合作的价值观。在我之前的项目中,我注重倾听用户反馈,并通过创新的方式解决问题,这与腾讯强调用户体验和创新的文化非常契合。我也非常欣赏腾讯在团队协作方面的努力,我认为一个团结协作的团队是实现伟大目标的关键。因此,我相信我的工作风格和价值观与腾讯的文化非常匹配,我渴望能够为腾讯的发展贡献力量。”
- 感觉您这边平台大,技术积累多,项目挑战多,能力提升多
你对加班的看法?
如果是工作需要我会义不容辞加班。我现在单身,没有任何家庭负担,可以全身心的投入工作。但同时,我也会提高工作效率,减少不必要的加班你对薪资的要求?
①:“我对工资没有硬性要求。我相信贵公司在处理我的问题上会友善合理。我注重的是找对工作机会,所以只要条件公平,我则不会计较太多
②:我作为一个科班出身,具备比较完备的工作技能的人,我相信自己能为公司带来价值。。因此,我希望公司能根据我的情况和市场标准的水平,给我合理的薪水。
③:如果你必须自己说出具体数目,请不要说一个宽泛的范围,那样你将只能得到最低限度的数字。最好给出一个具体的数字,这样表明你已经对当今的人才市场作了调查,知道像自己这样学历的雇员有什么样的价值。眼下你生活中最重要的是什么?未来几年的规划是什么?
对我来说,能在这个领域找到工作是最重要的。
规划好职业生涯,与同事们很好地合作。我希望能充分展示我在这个行业的能力和智慧。说说你对行业、技术发展趋势的看法?
???
回答提示:企业对这个问题很感兴趣,只有有备而来的求职者能够过关。求职者可以直接在网上查找对你所申请的行业部门的信息,只有深入了解才能产生独特的见解。企业认为最聪明的求职者是对所面试的公司预先了解很多,包括公司各个部门,发展情况,在面试回答问题的时候可以提到所了解的情况,企业欢迎进入企业的人是“知己”,而不是“盲人”。职业发展规划?
T型人才,一方面在技术领域深挖,一方面对整个产品的端到端有一个了解、、请用三个词描述您的性格特点
诚实,勤奋,谦虚。在学习知识和与人交往的过程中,我始终保持坦诚和真实,对自己和他人负责。面对生活中的挑战,我积极看待并勤奋努力,相信努力终会有所回报。谦虚让我保持谦逊和虚心,愿意倾听他人意见并不断学习成长。举例说明你的勤奋。。
我详细安排毕业设计开发进度,一周内每天熬夜到3点。。
我想说的是很多时候即使早已做好安排,到头来还是因为各种情况不得不赶进度,重要的是能够在需要时赶好进度的能力。。你身边的人如何评价你?
他们说我是一个诚实、学习和工作努力、负责任的人。我一旦答应别人的事情,就一定会负责到底,否则我不会轻易许诺。
以及我是一个比较随和的人,与不同的人都可以友好相处,在与人相处时,我总是能站在别人的角度考虑问题。你的优点和缺点。
- 我是一个诚实,比较勤奋和乐观的人。我的适应能力比较强,喜欢向他人学习,也愿意帮助他人。在以往的实习、项目中,能够很快适应团队开发流程。我相信在经过一段时间的培训及项目实战后,能够在这份工作中取得成功。
- 我缺乏工作经验。。
- 在之前的实习过程中只是参与了开发这一环节,没有跨部门合作、与不同岗位的同事深度交流的经验。
- 有点强迫症,会对任务的细节核对多遍,比如发邮件,填资料的时候必须要重复检查,把信息正着反着过一遍,这样虽然有点浪费时间,但就基本不会出什么差错了;
- 另外就是有点钻牛角尖,在学习新的知识时有个点花了很长时间都没弄懂,会比较泄气。后来发现可以把不懂的先放着,等学了别的知识,再返回来看这个知识点就触类旁通了;我目前也很习惯使用chatgpt进行学习,通过提问快速发散知识点,建立联系。
高中到大学以来,最大的挫折。
高中以来一直遭到失败,学业、社团、人际交往,,一度让我十分沮丧,但也是我思考了很多的一段时间,,我渐渐了解:失败是人生的常态。
我很庆幸一次次经历失败的过程中,我都还是选择了再努力一下,也许就有改变呢,往往最后问题都能够解决了,,
最重要的,我学会在任何情况下保持冷静,,在未来,在大学面对各种压力时,都可以比较体面地应对了,并且思考如何做得更好、、学习方法。
某一个点:根据需求针对性的官方文档,,查技术论坛、、
某一领域:(看B站视频 ×) 在有了大致了解后,使用chatgpt,不断提问、发散,把知识点都连接起来最近看了什么书?读了什么开源库?
???没看。考研弃考?秋招0 offer?空白期?
没考研!!找工作比较晚(因为有java基础和项目经验、、)并且夏令营,毕业实习占用了很多时间,,
秋招期间,我一直学习java技术栈,(没把握所以)没怎么投简历,,后面我为了丰富自己对开发的了解,也在12月底找了一份实习做到现在了。。目前不考虑考研
春招期间,,,表现抗压能力以及处理意外情况的能力。
- 分享一件你觉得压力比较大的事?你的压力从何来?你是如何克服他的?
??1.适应压力,有压力动力更足。2.会合理安排时间,取得工作效率很好的平衡 - 你长这么大以来遭受过的最大挫折是什么?你是如何克服它的?
?? - 二十多年来,你取得的最大成就是什么?
?? - 你通过多年努力获得的一项技能是什么?你是如何学习从而获得这项技能的,做了哪些工作去改善、精进这项技能?
??
学会面对任何困难保持冷静。从上学时突然被点名发言、突然被委任参加一个比赛,到现在做项目时面对需求从头开始学习新的技术,我发现在面对困难时,有效的方法就是冷静分析局势,以及最重要的是尽早的着手做。这样即使最后无法完成,也有所收获。
- 分享一件你觉得压力比较大的事?你的压力从何来?你是如何克服他的?
你能使组里气氛活跃,并且易于沟通吗?
我会尽力,和团队中的成员沟通,向他们发问、学习。因为在团队里工作最重要的一件事就是集思广益,而不要只是一个人闷头单干。沟通是很重要的,不仅可以提高工作质量和效率,也可以产生活力。如何处理与同事在工作中意见的不和?与上级意见冲突?
我要以更清楚和文明的方式提出我的看法,使对方了解我的观点。
我会尊重上级,上级一般更有经验,思考更全面,要通过积极沟通找到一个更合适的解决方法。在完成某项工作时,你认为领导要求的方式不是最好的,自己还有更好的方法,你应该怎么做?
原则上我会尊重和服从领导的工作安排;同时私底下找机会以请教的口吻,婉转地表达自己的想法,看看领导是否能改变想法;
如果领导没有采纳我的建议,我也同样会按领导的要求认真地去完成这项工作;
还有一种情况,假如领导要求的方式违背原则,我会坚决提出反对意见;如领导仍固执己见,我会毫不犹豫地再向上级领导反映。工作中你难以和同事、上司相处,你该怎么办?
我会服从领导的指挥,配合同事的工作。
我会从自身找原因,仔细分析是不是自己工作做得不好让领导不满意,同事看不惯。还要看看是不是为人处世方面做得不好。如果是这样的话 我会努力改正。
如果我找不到原因,我会找机会跟他们沟通,请他们指出我的不足。有问题就及时改正。
作为优秀的员工,应该时刻以大局为重,即使在一段时间内,领导和同事对我不理解,我也会做好本职工作,虚心向他们学习,我相信,他们会看见我在努力,总有一天会对我微笑的!偶像?企业家?
梅西?除了足球方面的,他有着世界上最宝贵的天赋,谦逊。他沉默地担下所有责任,用实际行动回复质疑和诋毁,以及他个人和职业生涯中的种种挫折,共同让他成长为了这个世界上最坚强的人。
任正非??一位民族企业家,经历了苦难的人,实干家,尊重教师和科学家。。他的企业即使在最艰难的时刻,也坚持研发投入,有着向上的风气。如果通过这次面试我们单位录用了你,但工作一段时间却发现你根本不适合这个职位,你怎么办?
??
如果你确实热爱这个职业,那你就要不断学习,虚心向领导和同事学习业务知识和处事经验,了解这个职业的精神内涵和职业要求,力争减少差距;
你觉得这个职业可有可无,那还是趁早换个职业,去发现适合你的,你热爱的职业,那样你的发展前途也会大点,对单位和个人都有好处。如果你的工作出现失误,给本公司造成经济损失,你认为该怎么办?
我本意是为公司努力工作,如果造成经济损失,我认为首要的问题是想方设法去弥补或挽回经济损失。
如果我无能力负责,希望单位帮助解决;
分清责任,各负其责,如果是我的责任,我甘愿受罚;如果是一个我负责的团队中别人的失误,作为一个团队,需要互相提携共同完成工作,安慰同事并帮助同事查找原因总结经验。
总结经验教训,一个人的一生不可能不犯错误,重要的是能从自己的或者是别人的错误中吸取经验教训,并在今后的工作中避免发生同类的错误。检讨自己的工作方法、分析问题的深度和力度是否不够,以致出现了本可以避免的错误。如果你在这次考试中没有被录用,你怎么打算?
第一:要敢于面对,面对这次失败不气馁,接受已经失去了这次机会就不会回头这个现实,从心理意志和精神上体现出对这次失败的抵抗力。要有自信,相信自己经历了这次之后经过努力一定能行.能够超越自我;
第二:善于反思,对于这次面试经验要认真总结,思考剖析,能够从自身的角度找差距。正确对待自己,实事求是地评价自己,辩证的看待自己的长短得失,做一个明白人;
第三:走出阴影,要克服这一次失败带给自己的心理压力,时刻牢记自己弱点,防患于未然,加强学习,提高自身素质;
第四:认真工作,回到原单位岗位上后,要实实在在、踏踏实实地工作,三十六行,行行出状元,争取在本岗位上做出一定的成绩;
第五:再接再厉,成为一名架构师一直是我的梦想,以后如果有机会我仍然后再次参加竞争。谈谈你对跳槽的看法?
正常的”跳槽”能促进人才合理流动,应该支持;
频繁的跳槽对单位和个人双方都不利,应该反对。你能为我们公司带来什么呢?
假如你可以的话,试着告诉他们你可以减低他们的费用——“我已经接受过惠普公司一段时间的培训,立刻就可以上岗工作”。
企业很想知道未来的员工能为企业做什么,求职者应再次重复自己的优势,然后说:“就我的能力,我可以做一个优秀的员工在组织中发挥能力,给组织带来高效率和更多的收益”。企业喜欢求职者就申请的职位表明自己的能力,比如申请营销之类的职位,可以说:“我可以开发大量的新客户,同时,对老客户做更全面周到的服务,开发老客户的新需求和消费。”等等。你的业余爱好是什么?
我喜欢足球,我享受和我的队友一起拼尽全力,互相信任,无论输赢一起共进退。在足球比赛中,一个团队的成功不仅仅取决于个别球员的技术水平,更重要的是整个团队的协同合作、沟通和相互理解。(回答提示:找一些富于团体合作精神的)最喜欢的十本书?
- 《三体》- 刘慈欣
- 《活着》- 余华
- 《围城》- 钱钟书
- 《1984》- 乔治·奥威尔
- 《动物农场》- 乔治·奥威尔
- 《白夜行》- 东野圭吾
- 《窗边的小豆豆》- 黑柳彻子
- 《苏菲的世界》- 乔斯坦·贾德
- 《水浒传》- 施耐庵
- 《红楼梦》- 曹雪芹
作为被面试者给我打一下分
“我认为在这次面试中,我有机会深入了解公司,并且很高兴能够分享我的经验和能力。
面试官提出的问题涉及到我的专业领域和与公司文化相关的方面,这让我感到这次面试非常有价值。我觉得这是一个很好的机会,展示了我与公司的匹配度,同时也让我更深入地了解了贵公司的期望和文化。
我期待着有机会为公司做出积极的贡献,如果有进一步的机会,我将非常愿意深入探讨我如何能够在公司中蓬勃发展。”
(回答提示:试着列出四个优点和一个非常非常非常小的缺点,,可以抱怨一下设施,没有明确责任人的缺点是不会有人介意的)喜欢这份工作的哪一点?
???
在回答面试官这个问题时可不能太直接就把自己心理的话说出来,尤其是薪资方面的问题,不过一些无伤大雅的回答是不错的考虑,如交通方便,工作性质及内容颇能符合自己的兴趣等等都是不错的答案,不过如果这时自己能仔细思考出这份工作的与众不同之处,相信在面试上会大大加分。说说你的家庭。
(企业不喜欢探究个人隐私,而是要了解家庭背景对求职者的塑造和影响。企业希望听到的重点也在于家庭对求职者的积极影响。企业最喜欢听到的是:)
我的家庭一向很和睦,虽然我的父亲和母亲都是普通人,但是从小,我就看到父母为了家庭起早贪黑,每天勤劳工作,他的行动无形中培养了我认真负责的态度和勤劳的精神。他们也教育我对人诚实、友善,要乐于助人。就你申请的这个职位,你认为你还欠缺什么?
回答建议(仅供参考):企业喜欢问求职者弱点,但精明的求职者一般不直接回答。他们希望看到这样的求职者:继续重复自己的优势,然后说:“对于这个职位和我的能力来说,我相信自己是可以胜任的,只是缺乏经验,这个问题我想我可以进入公司以后以最短的时间来解决,我的学习能力很强,我相信可以很快融入公司的企业文化,进入工作状态。”
企业喜欢能够巧妙地躲过难题的求职者。你欣赏哪种性格的人?
诚实、不死板而且容易相处的人、有”实际行动”的人。你通常如何处理別人的批评?
沈默是金。不必说什么,否则情况更糟,不过我会接受建设性的批评; 我会等大家冷靜下来再讨论。你怎样对待自己的失敗?
我们大家生来都不是十全十美的,我相信我有第二个机会改正我的错误。你和别人发生过争执吗?你是怎样解决的?
(千万不要说任何人的过错。应知成功解决矛盾是一个协作团体中成员所必备的能力。考官希望看到你是成熟且乐于奉献的。他们通过这个问题了解你的成熟度和处世能力。)
在没有外界干涉的情况下,通过妥协的方式解决。为了做好你工作份外之事,你该怎样获得他人的支持和帮助?
???项目中遇到困难,你怎么办?怎么回答
???
第一种这个要找项目负责人商量、甚至要找产品/运行或其他甲方沟通、
第二种普遍技术难点的话、参考资料或者和项目负责人商量看看怎么办、
第三种的话、先自己查资料试着解决、不行就找人其他资讯、、意向城市,人生发展(以提高自己为主,强化学习,找到一个好的环境)
压薪:如果工资达不到您的预期,还来吗?
1、感谢hr在面试这几轮的工作和时间
2、我感觉其实很适合这个岗位了(我就是公司需要的人,不要压我工资完成你的kpi
3、不管结果如何,希望您能够再帮我争取一下(我也和,,打打招呼,表达诚意,不让您这边为难?
不直接回答,只表达希望hr能帮我争取,不保证接不接offer??