面试题--视频学习整理

redis

 

redis缓存 

缓存穿透

布隆过滤器主要是用于检索一个元素是否在一个集合中。我们当时使用的是 redisson实现的布隆过滤器。 它的底层主要是先去初始化一个比较大数组,里面存放的二进制0或1。在一 开始都是0,当一个key来了之后经过3次hash计算,模于数组长度找到数据 的下标然后把数组中原来的0改为1,这样的话,三个数组的位置就能标明一 个key的存在。查找的过程也是一样的。

当然是有缺点的,布隆过滤器有可能会产生一定的误判,我们一般可以设置 这个误判率,大概不会超过5%,其实这个误判是必然存在的,要不就得增 加数组的长度,其实已经算是很划分了,5%以内的误判率一般的项目也能 接受,不至于高并发下压倒数据库。

 缓存雪崩

双写一致 

 强一致性:读写锁

 异步通知:

数据持久化 

数据过期策略 

 redis的过期策略是惰性删除和定期删除配合使用

 

 数据淘汰策略

 

 分布式锁

 

 

 主从复制

 

主从复制原理 

 哨兵模式

redis是单线程快的原因 

 

 redis业务场景自我整理

spring

考察范围

spring框架中的单列bean是线程安全的码 

spring AOP详解 

 

 结果输出:

 

 spring事务失效的原因

只有代理的类才会被切入,我们在controller层调用service的方法的时候,是可以被切入的,但是如果我们在service层 A方法中,调用B方法,切点切的是B方法,那么这时候是不会切入的,解决办法就是如上所示,在A方法中使用((Service)AopContext.currentProxy()).B() 来调用B方法,这样一来,就能切入了!

 

描述时可以加上应用场景,什么时候出现过事务失效 

package com.hmdp.service.impl;

import com.hmdp.dto.Result;
import com.hmdp.entity.SeckillVoucher;
import com.hmdp.entity.VoucherOrder;
import com.hmdp.mapper.VoucherOrderMapper;
import com.hmdp.service.ISeckillVoucherService;
import com.hmdp.service.IVoucherOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmdp.utils.RedisIdWorker;
import com.hmdp.utils.UserHolder;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Collections;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 虎哥
 * @since 2021-12-22
 */
@Service
public class VoucherOrderServiceImpl extends ServiceImpl<VoucherOrderMapper, VoucherOrder> implements IVoucherOrderService {

    @Autowired
    private ISeckillVoucherService seckillVoucherService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    RedissonClient redissonClient;

    private static final DefaultRedisScript<Long> SECKILL_SCRIPT;

    static {
        SECKILL_SCRIPT = new DefaultRedisScript<>();
        SECKILL_SCRIPT.setLocation(new ClassPathResource("seckill.lua"));
        SECKILL_SCRIPT.setResultType(Long.class);
    }

    @Override
    public Result seckillVoucher(Long voucherId) {
//        //查询秒杀时间
//        SeckillVoucher seckillVoucher = seckillVoucherService.getById(voucherId);
//        if (seckillVoucher==null){
//            return Result.fail("秒杀商品不存在");
//        }
//        if (seckillVoucher.getBeginTime().isAfter(LocalDateTime.now())){
//            return Result.fail("秒杀未开始");
//        }
//        if (seckillVoucher.getEndTime().isBefore(LocalDateTime.now())){
//            return Result.fail("秒杀已结束");
//        }
//        if (seckillVoucher.getStock()<1){
//            return Result.fail("库存不足");
//        }
//        Long userId = UserHolder.getUser().getId();
//        //加锁:单机下使用synchronized
        synchronized (userId.toString().intern()) {
        RedisLock redisLock=new RedisLock("order:"+userId,stringRedisTemplate);
        redisClient.getL
//        RLock lock = redissonClient.getLock("order:" + userId);
//        boolean b = lock.tryLock();
//        if (!b){
//            return Result.fail("每个用户只能购买一次");
//        }
//        //交给spring后实现事务
//        try {
//            IVoucherOrderService proxy = (IVoucherOrderService)AopContext.currentProxy();
//            return proxy.createOrder(voucherId);
//        } finally {
//            lock.unlock();
//        }
        Long userId = UserHolder.getUser().getId();
        Long redult = stringRedisTemplate.execute(SECKILL_SCRIPT,
                Collections.emptyList(),
                voucherId.toString(), userId.toString());
        int r = redult.intValue();
        if (r != 0) {
            return Result.fail(r == 1 ? "库存不足" : "不能重复下单");
        }
        RedisIdWorker redisIdWorker = new RedisIdWorker(stringRedisTemplate);

        long orderId = redisIdWorker.nextId("order");

        return Result.ok(0);
    }

    @Transactional
    public Result createOrder(Long voucherId) {
        RedisIdWorker redisIdWorker = new RedisIdWorker(stringRedisTemplate);
        long orderId = redisIdWorker.nextId("order");
        Long userId = UserHolder.getUser().getId();
        //实现一人一单
        Integer count = query().eq("user_id", userId)
                .eq("voucher_id", voucherId).select().count();
        if (count > 0) {
            return Result.fail("用户已经购买过一次了");
        }
        //扣减库存
        boolean b = seckillVoucherService.update()
                .setSql("stock=stock-1")
                .eq("voucher_id", voucherId)
                .gt("stock", 0)
                .update();
        if (!b) {
            return Result.fail("秒杀失败");
        }
        //添加订单信息
        VoucherOrder voucherOrder = new VoucherOrder();
        voucherOrder.setUserId(userId);
        voucherOrder.setVoucherId(voucherId);
        voucherOrder.setId(orderId);
        save(voucherOrder);
        return Result.ok(orderId);
    }
}

 spring中Bean的生命周期

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

@Component
public class User implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean {

    public User() {
        System.out.println("User的构造方法执行了.........");
    }

    private String name ;

    @Value("张三")
    public void setName(String name) {
        System.out.println("setName方法执行了.........");
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("setBeanName方法执行了.........");
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("setBeanFactory方法执行了.........");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("setApplicationContext方法执行了........");
    }

    @PostConstruct
    public void init() {
        System.out.println("init方法执行了.................");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("afterPropertiesSet方法执行了........");
    }

    @PreDestroy
    public void destory() {
        System.out.println("destory方法执行了...............");
    }

}

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("user")) {
            System.out.println("postProcessBeforeInitialization方法执行了->user对象初始化方法前开始增强....");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("user")) {
            System.out.println("postProcessAfterInitialization->user对象初始化方法后开始增强....");
            //cglib代理对象
            Enhancer enhancer = new Enhancer();
            //设置需要增强的类
            enhancer.setSuperclass(bean.getClass());
            //执行回调方法,增强方法
            enhancer.setCallback(new InvocationHandler() {
                @Override
                public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                    //执行目标方法
                    return method.invoke(method,objects);
                }
            });
            //创建代理对象
            return enhancer.create();
        }
        return bean;
    }

}

 输出结果:

User的构造方法执行了.........
setName方法执行了.........
setBeanName方法执行了.........
setBeanFactory方法执行了.........
setApplicationContext方法执行了........
postProcessBeforeInitialization方法执行了->user对象初始化方法前开始增强....
init方法执行了.................
afterPropertiesSet方法执行了........
postProcessAfterInitialization->user对象初始化方法后开始增强....
User的构造方法执行了.........
public java.lang.String java.lang.Object.toString()

 spring循环依赖

 

 

 

 spring MVC请求

 

 springboot自动配置

 

 

spring常见的注解 

 

线程池

如何确定核心线程数 

线程池的种类 

为什么不建议使用Executors创建线程 

RabbitMQ 

RabbitMQ如何保证消息不丢失 

 

 

 

 RabbitMQ消息的重复消费问题如何解决

 死信交换机

 

 100万的数据堆积在MQ中如何解决

RabbitMQ高可用机制了解过嘛 

集合 

 数组

ArrayList底层实现原理

 

 数组转List和List转数组

 

 ArrayList和LinkedList的区别

 

 二叉树

红黑树 

 

散列冲突 

HashMap实现原理 

HashMap中Put方法执行流程 

Hashmap扩容机制 

 Hashmap寻址算法和数组长度为2的n次幂

JVM

程序计数器 

堆 

 

堆和栈的区别 

方法区 

什么是类加载器 

双亲委派  

类装载的过程 

什么是可以判定为垃圾 

 

 

 JVM中的回收算法

JVM中分代回收 

 垃圾回收器 

 

 强软弱虚引用的区别

 

 JVM调优的参数可以在哪里设置 

JVM的调优参数 

 

 

JVM调优工具 

 

JVM内存泄漏排查思路

 

JVM查看CPU飙高 

微服务

spring Cloud常用组件有哪些 

注册中心和服务中心 

Ribbon的负载均衡策略有哪些?如何自定义负载均衡策略 

 

服务雪崩是什么,怎末解决 

微服务是如何让监控的 

限流算法和如何实现限流 

 

 

CAP和BASE 

分布式事务Seata 

 

接口幂等性的实现方式 

分布式任务调度 

设计模式

工厂模式

创建对象和对象调用者解耦

 策略模式

 

责任链模式 

spring中的设计模式

Spring 中经典的 9 种设计模式,打死也要记住啊! - 知乎 (zhihu.com)

mysql

如何定位慢查询日志

SQL执行很慢,如何分析 

  

索引 

 

 

Mysql超大分页处理 

 索引创建的原则有哪些?

什么时候会索引失效 

 

SQL优化经验 

Mysql事务解决方案 

redo log和undo log的区别 

 

事务中的隔离性是如何保证的? 

主从复制同步原理 

Mybatis

Myabtis执行流程 

mybatis是否支持延迟加载 

 

mybatis缓存 

 

线程 

创建线程的方式

 

runnable和callable的区别

run()和start()方法的区别

线程包括那些状态 

新建3个线程如何保证他们顺序执行 

 

notify和notifyAll的区别 

 wait()和sleep方法的不同

正在执行的线程如何打断 

 使用推出标记代码

打断线程代码

synchronizatied锁升级 

JMM内存模型 

CAS 

Volatile 

AQS 

 

 synchronizatied和lock的区别

 

死锁的判断 

currentHashMap的底层数据结构 

并发程序中出现问题以及解决方案 

 场景问题

单点登录

 

权限认证是如何实现的 

 

 

你负责的项目中遇到过什么棘手的问题,如何解决 

 

公司日志是如何采集的 

 

查看日志的命令有哪些 

 

生产问题怎末排查 

 

系统遇到瓶颈怎末解决 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《2021测试面试题 - pdf》是一本面试题集合,以PDF格式呈现。这本书可能包含了各种不同类型的面试题,涵盖了不同领域和层级的职位。 阅读这本书可以提供一些关于面试准备的指导,帮助应聘者了解常见的面试问题,以及如何回答这些问题。它可以帮助应聘者熟悉面试过程,了解面试官的期望,并为他们的面试做好准备。 这本书可能包含常见的面试问题,例如个人背景介绍、职业发展规划、技术能力、解决问题的能力、团队合作等。通过阅读这些问题,应聘者可以思考如何回答,并准备一些典型的示例和故事来支持他们的回答。 这本书还可能提供一些面试技巧和建议,包括如何在面试中展示自己的能力和经验,如何有效地回答问题,如何展示个人的职业素养等。 总之,《2021测试面试题 - pdf》是一本面试题集合,旨在帮助应聘者准备面试,了解常见的面试问题,并提供一些面试技巧和建议。对于那些正在寻找工作或准备面试的人来说,这本书可能是一个有用的资源。 ### 回答2: 《2021测试面试题- pdf》是一本面试题集合,针对测试工程师岗位的招聘面试进行了整理和编写。这本题集包含了多种类型的测试题目,涵盖了软件测试的各个方面,旨在帮助招聘单位了解应聘者的测试知识和技能。 这本面试题集的内容包括但不限于测试基础知识、测试策略和方法、测试工具和框架、自动化测试、性能测试、安全测试等。这些题目有些是选择题,有些是简答题或编程题,都是经过精心设计的,可以帮助招聘单位全面地了解应聘者在测试领域的实际能力和经验。 对于应聘者而言,阅读和解答《2021测试面试题- pdf》可以帮助他们复习和巩固测试知识,并提前了解可能会在面试中遇到的问题和考察点。通过认真准备,应聘者可以在面试中更好地回答问题,展示自己的实际能力和经验,提高获得聘用的机会。 对于招聘单位而言,这本题集可以作为一个参考工具,用于筛选和评估应聘者。招聘单位可以根据《2021测试面试题- pdf》中的问题,结合自己的需求和要求,从中选取适合的问题进行面试,以衡量应聘者的能力和适应性。 综上所述,《2021测试面试题- pdf》是一本用于软件测试岗位招聘面试的题目集,旨在帮助招聘单位了解应聘者的测试知识和技能,同时也为应聘者提供了一个复习和准备面试的工具。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值