- 博客(33)
- 资源 (1)
- 收藏
- 关注
原创 总结面试中可能会涉及到简历的问题
面试管你好!我叫张凯,毕业于青岛农业大学计算机科学与技术专业,目前在哈尔滨理工大学攻读软件工程硕士。过去几年我主要在Java开发领域积累了丰富的项目经验,例如在“健身交流网”项目中负责设计Redis集群、实现缓存优化与秒杀模块,在“即时聊天室”项目中搭建了基于WebSocket的聊天系统,同时熟练掌握了Spring Boot、SSM、Vue等主流技术。设计并实现基于Redis集群的会话存储,解决多节点Session共享问题。利用拦截器和JWT令牌统一鉴权,保证用户登录状态一致性。采用。
2025-04-01 11:27:10
469
原创 总结面试中可能会问的八股
跳表(Skip List)是一种基于概率的动态数据结构,主要用于有序数据的高效查找、插入和删除操作,其时间复杂度平均为 O(log n)。下面是关于跳表的详细说明:跳表由多层链表组成,最底层是一条完整的有序链表,每一层都包含部分节点,这些高层链表相当于对底层链表的“索引”。每个节点可能会在多个层级中出现,这些层级通过随机算法决定。工作原理:从最高层开始,顺着链表向右查找,直到发现下一个节点大于或等于目标值,然后下移到下一层继续查找,直至到达最底层。
2025-03-31 10:33:03
859
原创 消息队列Message Queue
前面,我们在黑点点评中秒杀场景中,首次了解到消息队列MQ,它主要解决了秒杀场景中异步场景,提升了并发性,吞吐量。可是还是对消息队列又很多的疑惑?
2025-03-28 19:53:30
941
原创 SpringBoot底层原理
传统的项目构建是需要Spring中提供众多的子项目来构建Spring应用程序,Spring Framework提供核心功能,其他的负责数据获取消息传递等等,其他的子项目都依赖于Spring Framework,整合成一个完整的项目随着业务需求的复杂化,大型化,传统的方式已经不再满足,比如,
2025-03-26 11:14:38
399
原创 栈和队列相关知识题目
栈(Stack)是一种的线性数据结构,所有操作(如插入、删除)仅在栈顶进行。它的底层实现可以是数组或链表,具体取决于编程语言和应用场景。
2025-03-25 20:55:36
704
原创 黑马点评-UV统计
但UV统计在服务器端实现会很麻烦,因为要判断过该用户是否统计过了,需要将统计过的用户信息进行保存,若将所有访问过的用户都存储在redis,会消耗大量的内存,所以redis中HyperLogLog。
2025-03-23 15:14:35
362
原创 黑马点评-用户签到
假设我们用一个数据库表来存储用户的签到信息所以,我们采取01的方式存储用户的签到信息这样一个用户一个月的签到情况就可以用一个最多31bit,3字节的的二进制串表示,高效还节省空间。
2025-03-23 14:51:22
353
原创 黑马点评-好友关注
需求:1.修改新增探店笔记的业务,将笔记内容保存到数据库的同时(相对来说,数据库持久且安全),只需要将用户id推到粉丝的收件箱中即可,然后按照用户id再去查询笔记2.收件箱需要满足按照时间戳进行排序,使用redis数据结构实现(LIst和sortedset都满足排序和利用角标分页查询的功能,但list不支持滚动分页,sortedset支持滚动分页3.查询收件箱用户id时,再进行分页查询(因为feed流中的数据会不断更新,数据的角标也在随之变化,若采取传统的分页查询会导致出现内容重复 ,所以要采取。
2025-03-23 12:03:20
812
原创 反转字符串中的单词
给你一个字符串s,请你反转字符串中的顺序。是由非空格字符组成的字符串。s中使用至少一个空格将字符串中的分隔开。返回顺序颠倒且之间用单个空格连接的结果字符串。输入字符串s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。反转后的字符串中不能存在前导空格和尾随空格。如果两个单词间有多余的空格,反转后的字符串需要将单词间的空格减少到仅有一个。这其中设计了非常多的知识点。
2025-03-20 21:29:41
291
原创 黑马点评-基于redis的stream结构的消息队列,实现异步秒杀下单
需求:1.在redis中创建名为stream.orders的消息队列,用于传递认定抢购资格后封装的voucherId,userId,orderId0表示从队列中的第一个消息开始读取2.修改lua脚本,增加向stream.orders队列中添加封装消息的工作,这样可以减少java代码的工作量,减少java与lua的交互这个方法是为了执行lua脚本,并且判断是否由购买资格,返回封装3个id的。 这个方式是为了获取消息队列中的订单消息,并且确认订单消息,完成创建订单操作handlePend
2025-03-19 20:37:32
188
原创 黑马点评—redis消息队列
1.无法避免消息丢失:因为采取POP操作是直接移除remove消息2.一对一:因为一个消费者拿走消息后,其他消费者就无法或者该消息1.因为List队列本身就是数据结构,具有存储功能,所以可以做到数据持久化,而PubSub本身就只是一个发送消息模型,无法做到数据持久化2.无法做到持久化,就无法避免数据的丢失3.消息发送时需要生产者和消费者都同时在线,否则一方不再就无法传递消息,4.安全问题较大基于Stream的消息队列stream是redis5.0新引入数据类型,注意是数据类型。
2025-03-19 19:51:25
1398
原创 黑马点评-秒杀优惠券优化
秒杀业务的优化思路:原本,应该先判断抢购是否开始,库存是否足够,是否一人一单,最后才创建订单,同时还要为怎么多的业务添加各种事务管理和锁,同时请求数据库的操作也比较慢,导致消耗了大量的时间。所以我们就将业务进行简化,异步完成,分为两部分,一部分是在redis中对抢购资格的判断,包括库存是否足够,是否符合一人一单,另一部分时下单,从组测队列中拿到符合抢购资格的用户id,优惠券id,订单id,完成下单操作。同时,上述思路还存着一定的问题。
2025-03-19 13:28:03
901
原创 黑马点评-rdission
redission是redis基础上实现的分布式系统的工具,它提供了很多分布式服务,包括各种分布式锁的实现,所以上述优化的步骤可以借助工具,而不需要亲自敲由于redis的主从不一致问题容易产生安全问题:比如一个java应用向redis执行写的操作并获取锁,主节点在完成读写操作后,要向从节点进行数据同步,就在这时,主节点宕机,数据没有同步完成,redis的哨兵机制就会从从节点当中选择一个晋升为主节点,但这是java应用只能向新的主节点发送请求,但之前获取的锁已经失效了,就会导致一定的安全问题。
2025-03-18 20:50:46
978
原创 redis的lua脚本
即也是写入name=jack的内容,但后面跟了个0,表示传递参数的个数,0就代表了传递的参数后续不能做任何修改。redis提供lua脚本功能,在一个脚本中编写多条redis命令,确保多条命令执行的原子性。lua脚本的命令格式是。
2025-03-18 13:34:12
304
原创 黑马点评-分布式锁
setnx key value: 若key存在则无法设置,可以看见下图中就thread1获得了锁,其他的线程并不能。若在获取锁的过程中服务宕机,又只能手动释放锁,导致长时间无法释放,可以通过设置TTL过期时间来让锁自动释放。1.集群模式下的锁是每个JVM中都有个锁监视器,并不能保证线程并发的安全,也就无法实现一人一单这种要求。2.所以引入了分布式锁,即在集群模式下公用一个锁监视器,这样保证了线程并发运行和安全问题。del key:可以释放锁,释放lock之后,thread55又获得锁。
2025-03-18 10:44:05
295
原创 黑马点评项目总结2
利用redis中的自增数值生成序列号(32bit)与时间戳(31bit)符号位(1bit)生成唯一ID。定义prefix,用于区分不用的项目。普通优惠券和秒杀优惠券共享同一个controller层。3.2实现优惠券秒杀功能。秒杀券超卖和一人一单问题。3.1实现全局唯一ID。
2025-03-17 14:30:42
254
原创 黑马点评项目代码总结1
extends ServiceImpl<UserMapper, User>是为了改写接口层中的方法。implements IUserService是为了继承IUserService操作数据库的方法。在userController创建发送验证码和登录的接口,用于实现这两个功能。在 UserServiceImpl改写上面这四个方法,并且实现具体的逻辑。在IUserService层实现方法上述四个方法的接口层。1.实现基于session的登录功能。
2025-03-17 10:33:54
356
原创 有效的括号:括号匹配
思路:利用栈后进先出的特性去遍历字符串,遍历到左括号就往栈里放一个右括号,这样后续好做比较。遍历到右括号就与栈顶元素进行匹配,相同就出栈继续遍历,不同就输出匹配失败。下面这个思路虽然看起来非常直观,担时间复杂度和空间复杂度都很大,每次都要重新遍历字符串,并且每次都要重新为字符串分配新的空间,作为扩展思路。1、遍历完整个字符串还有,栈里还有一个右括号,说明字符串中有多余的左括号没匹配。2、遍历到右括号是,与栈顶元素比较不对,匹配失败。3、还没遍历完字符串,栈为空,说明有多余的右括号。
2024-03-18 20:12:17
510
1
原创 重温链表知识点
2、链表的结点由两部分,一部分存储数据,一部分指针指向下一个结点的地址。1、链表是在逻辑上连续,物力结果上不连续的存储结构。3、单链表——single linked list。5、链表创建一个新的结点,需要提前分配地址。4、链表示不需要初始化的。
2024-03-18 19:12:55
401
1
原创 找出字符串中第一个匹配项的下标
字符串的第一个匹配项的下标(下标从 0 开始)。思路2、substring字串来替换下,一个一个检测。题目描述:给你两个字符串。
2024-03-13 21:34:25
373
原创 罗马数字转整数
数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4。同样地,数字 9 表示为。通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做。思路2、直接将题目中所有的特殊情况进行替换,然后创造一个新的函数。思路1、本质就是罗马数字I在左边就是加法,在右边就是减法。给定一个罗马数字,将其转换成整数。,即为两个并列的 1。
2024-03-13 20:27:52
371
原创 【无标题】
2、利用双指针,pa一个从a的头节点开始遍历,pb从b的头节点开始遍历,当pa遍历a结束时从b重新开始遍历,当pb遍历结束b后吗,从a重新开始遍历,若pa,pb同时指向一个结点或同时为null,则返回该节点或说明两链表不相交。题目描述:给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。1、利用哈希表可以快速查找的特性,将单链表a存在哈希表中,同时遍历单链表b与哈希表中点元素进行比较,判断是否在哈希表中,若当前阶段存在,且后面节点也存在,则返回该节点。
2024-03-11 20:15:33
349
原创 在数组上加一并返回数组
1、首先我们要确认在数组中是否有9,若没有直接返回数组,在最后加1。3、若全是9,则返回一个新的长度加以的数组将数组头置为1。你可以假设除了整数 0 之外,这个整数不会以零开头。最高位数字存放在数组的首位, 数组中每个元素只存储。2、若该位置是9,则置为0,并将前一个数置为+1。数组所表示的非负整数,在该数的基础上加一。有了思路以后我们来敲代码。
2024-03-08 16:16:40
660
1
原创 搜索插入位置 java
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。请必须使用时间复杂度为。
2024-03-06 16:31:14
389
1
原创 java语言解决移除元素问题
由于在数组中删除值为val的元素,因为数组在内存中是连续存储,所以不能只删除元素,而是在删除元素后还要使后边元素前移。给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。有两种解法1、快慢指针 2、两层for循环暴力删除。2、两层for循环暴力解法。下面用两个快慢指针来表示。
2024-03-04 20:40:53
585
1
原创 内蒙古大学2019年计算机专业复试题
/二维数组中a.length代表着a数组的长度(即行数),a[0].length代表着0行所代表的长度。//起到的是空格的作用。和print的作用区别是一个换行一个不换行。.println();//起到了换行的作用。.println("第一个数组:");.println("第二个数组:");.println("结果是:");
2023-03-02 09:22:34
267
java语言的快速排序算法类型转换出了问题!
2023-03-01
TA创建的收藏夹 TA关注的收藏夹
TA关注的人