当前位置: 首页 > news >正文

Java,八股,cv,算法——双非研0四修之路day16

目录

 昨日总结

今日计划

算法——两个数组的交集

算法——两数之和

缓存穿透

常见解决方案

缓存雪崩

常见解决方案

缓存击穿

常见解决方案

栈溢出

堆溢出

功能接口式参数&泛型函数

​编辑


 昨日总结

  • 缓存问题完结(缓存穿透、雪崩、击穿),了解堆、栈溢出,功能接口式参数&泛型函数,完成点评缓存部分
  • cv(停滞中)
  • 背诵小林coding--Java并发面试篇(1/3)
  • 代码随想录——两个数组的交集,两数之和

今日计划

  • 跟进点评项目
  • cv(停滞中)
  • 背诵小林coding--Java并发面试篇(1/3)
  • 代码随想录——四数相加,三数之和

算法——两个数组的交集

给定两个数组 nums1 和 nums2 ,返回 它们的 交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。

示例 1:

输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]

示例 2:

输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]
解释:[4,9] 也是可通过的
class Solution {public int[] intersection(int[] nums1, int[] nums2) {Set<Integer> set = new HashSet<>();for(int num : nums1) {set.add(num);}Set<Integer> T = new HashSet<>();for(int num : nums2) {if(set.contains(num))T.add(num);}//通过 stream() 方法将 List 转换为流,mapToInt 方法将 Integer 类型的流//转换为 int 类型的流, 最后使用 toArray 方法将流转换为 int 数组。int[] t = T.stream().mapToInt(Integer::intValue).toArray();return t;}
}

算法——两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。

你可以按任意顺序返回答案。

示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

示例 2:

输入:nums = [3,2,4], target = 6
输出:[1,2]
class Solution {public int[] twoSum(int[] nums, int target) {Map<Integer,Integer> map = new HashMap<>();for(int i = 0; i< nums.length; i++) {int temp = target - nums[i];if(map.containsKey(temp))return new int[] {map.get(temp),i};map.put(nums[i],i);}return new int[0];}
}

缓存穿透

缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到数据库。
常见解决方案
  • 缓存空对象:当客户端访问redis未命中时,会访问数据库 ,若此时数据库也未命中,将会redis缓存一个null空对象
优点:实现简单,维护方便
缺点 :额外的内存消耗,可能造成 短期的不一致(针对此问题,1.可以为缓冲空数据设置一个TTL生存时间 2.可以每完成一次数据库的操作 ,便立即更新缓存 )
  • 布隆过滤
当客户端发出 请求 时 ,会首先经过布隆过滤器进行判断,是否 存在该数据 。若存在之后在经过redis或再经过数据库。
布隆过滤器原理 :用二进制位和哈希函数来存在 该数据是否存在
优点 :内存占用较小,没有多余key
缺点:实现 复杂 ,存在误判可能

缓存雪崩

缓存雪崩是指在同一时段大量的缓存key同时失效或者Redis服务宕机,导致大量请求到达数据库,带来巨大压力。
常见解决方案
  • 给不同的Key的TTL添加随机值
  • 利用Redis集群提高服务的可用性
  • 给缓存业务添加降级限流策略
  • 给业务添加多级缓存

缓存击穿

缓存击穿问题也叫热点Key问题,就是一个被高并发访问并且缓存重建业务较复杂的key突然失效了,无数的请求访问会在瞬间给数据库带来巨大的冲击。
常见解决方案
  • 互斥锁
优点:没有额外的内存消耗 ,保证 一致性,实现简单
缺点:县城 需要等待,性能受影响,可能会出现死锁风险
  • 逻辑过期
优点:线程无需等待 ,性能较好
缺点:不保证一致性,有额外的内存消耗,实现复杂。

栈溢出

在Java中,栈是线程私有的,主要用于存储局部变量和方法调用等。每个线程创建时都会分配一定大小的栈空间,当空间被分配完时,便会发出栈溢出。一般出现栈溢出的情况如下:
  • 陷入死循环的递归调用
如果递归方法没有正确的终止条件或者终止条件设置不合理,会导致方法不断地调用自身,栈帧不断入栈,最终耗尽栈空间。
  • 方法调用的层次过深
在一个嵌套很深的方法调用中,每个方法都会在栈上分配一定的空间,当调用层次过深时,栈空间就会被耗尽。
  • 局部变量占用的空间过大
如果在方法中定义了大量的局部变量,尤其是一些占用空间较大的数组或对象,会增加每个栈帧的大小,从而使栈空间更快地被耗尽。

堆溢出

在Java中,堆是线程共享的内存区域,主要存储对象的实例。当空间无法为新的对象分配内存时,就会发生堆溢出。一般出现堆溢出的情况如下:
  • 创建的大量对象没有及时回收
  • 内存泄漏
内存泄漏是指程序中某些对象不再使用,但由于存在引用关系,垃圾回收器无法回收这些对象,导致堆空间不断被占用。例如静态集合类中的对象不会被垃圾回收、某些资源的连接未关闭,造成资源泄漏
  • 分配的堆空间过小
如果Java虚拟机(JVM)的堆空间设置过小,无法满足程序运行时的内存需求。

功能接口式参数&泛型函数

函数传递功能参数通常指的是将行为(函数)作为参数传递给另一个方法。
在写工具类时,如果返回类型不确定,要 利用泛型来解决,让调用者去告诉具体的函数类型

例如:当在一个工具类中调用数据库函数时,需要通过函数自身传递的参数来传入,因此通过Lambda表达式传递功能

public <R, ID> R queryWithPassThrough(String keyPrefix, ID id , Class<R> type, Function<ID, R> dbFallback,Long time, TimeUnit unit) {String key = "cache:shop:" + id;//从redis查询商铺缓存String json = stringRedisTemplate.opsForValue().get(key);//判断缓存是否存在if (StrUtil.isNotBlank(json)) {//存在 直接返回return JSONUtil.toBean(json, type);}//判断命中的是否是空值if(json != null) {//返回一个错误信息return null;}//不存在,根据id查询数据库R r = dbFallback.apply(id);//数据库不存在返回错误if (r == null) {//将空值写入redisstringRedisTemplate.opsForValue().set(key,"",2L,TimeUnit.MINUTES);return null;}//数据库存在,写入redisthis.set(key,r,time,unit);//返回return r;
}

 this::getById 是一个实例方法引用,它等价于Lambda表达式:id -> this.getById(id);

public Result queryById(Long id) {Shop shop = cacheClient.queryWithPassThrough(CACHE_SHOP_KEY,id, Shop.class,this::getById,CACHE_SHOP_TTL,TimeUnit.MINUTES);return Result.ok(shop);
}

http://www.xdnf.cn/news/1190773.html

相关文章:

  • PYTHON从入门到实践-16数据视图化展示
  • Docker的简单使用
  • 【C++】定义常量
  • 图片查重从设计到实现(5)Milvus可视化工具
  • 嵌入式硬件篇---zigbee无线串口通信问题
  • Python - 100天从新手到大师 - Day6
  • 【Redis】Linux 配置Redis
  • 从零开始的云计算生活——第三十六天,山雨欲来,Ansible入门
  • [Python 基础课程]注释
  • Flowable 实战落地核心:选型决策与坑点破解
  • uniapp 自定义tab栏切换
  • 全球化2.0 | 云轴科技ZStack亮相阿里云印尼国有企业CXO专家活动
  • 数据结构预备知识
  • JavaWeb01——基础标签及样式(黑马视频笔记)
  • 伟淼科技李志伟:破解二代接班传承困局,系统性方案破除三代魔咒
  • mysql查找数据库表中某几个连续的编号中中断的编号
  • 如何实现打印功能
  • Kafka——Java消费者是如何管理TCP连接的?
  • 两个USB-CAN-A收发测试
  • pytorch学习笔记-自定义卷积
  • 在C#中判断两个列表数据是否相同
  • Day04–链表–24. 两两交换链表中的节点,19. 删除链表的倒数第 N 个结点,面试题 02.07. 链表相交,142. 环形链表 II
  • # JsSIP 从入门到实战:构建你的第一个 Web 电话
  • VTK交互——ImageRegion
  • kali [DNS劫持] 实验(详细步骤)
  • python I 本地 html 文件读取方法及编码报错问题详解
  • Android 蓝牙学习
  • 在python3.8和pytorch1.8.1的基础上安装tensorflow
  • 对比JS“上下文”与“作用域”
  • kafka中生产者的数据分发策略