Java面试题

springboot start

不同的场景启动器。

nginx:

什么是正向代理?

正向代理主要作用是隐藏客户端的信息。比如我自己上网想访问国外的谷歌,但是因为众所周知的原因,我们国内的互联网是没办法直接访问谷歌的。那么我就可以搭建一台代理服务器,当我想访问谷歌的时候,我的浏览器先访问代理服务器,然后再由代理服务器再访问谷歌。谷歌接收到代理服务器的请求之后,把响应返还给代理服务器。代理服务器接收到谷歌的响应之后,再返还给我的客户端。

什么是反向代理?

反向代理主要的作用是屏蔽内部网络服务器的信息或者是做负载均衡的访问。

Docker

docker设置服务开机自动启动。 

# docker update 服务名 --restart=always

#比如设置nginx开启自动启动
docker update nginx --restart=always

监控docker资源占用情况 

docker stats 

linux编辑文件的时候,显示行数:

:set numer 

:set number

JVM

我们编写的Java文件。会被编译成.class文件,这个class文件呢,会被我们jvm的类装载器来装载到jvm里面。所有的数据都会保存在运行时数据区。优化的大部分都会在运行时数据区。大家很厉害的话,可以来写jvm的执行引擎。代码数据进行到运行时数据区,以后就会又执行引擎来进行执行。。

我们这个性能监控分析呢,我们主要是来监控我们be的整个工作,包括它的。用说一下渣的内存模型,而它里边的堆垃圾回收机制等这些问题,当然这些。

缓存:Redis为例

锁:

本地锁:(单体应用下)

加锁的方法:

1、可以将需要加锁的代码放入同步代码块中:(次方法在单体应用中可以,不适用与分布式环境)

synchronized (this){
   
}

2、使用同步方法,即在方法上加 synchronized 关键字:(次方法在单体应用中可以,不适用与分布式环境) 

    public synchronized String getRedisData(){
        
        return "";
    }

分布式锁:

采用Redisson框架来实现分布式锁:

 

读写锁

 闭锁

 信号量

加锁时,要注意锁的粒度 

 缓存的最终一致性,是指页面看到的数据和数据库保存的数据存在一定的延时。(写缓存会有一定的时间延迟)

多线程:

 常见的四种线程池:

在项目种使用异步编排技术:

1、创建自己的线程池类:通过

new ThreadPoolExecutor(
        int corePoolSize, //核心线程数
        int maximumPoolSize, //最大线程数
        long keepAliveTime, //空闲线程存活时间,(空闲的线程数大于核心线程数时,超过该时间空闲线程就会被释放)
        TimeUnit unit, //时间单位
        BlockingQueue<Runnable> workQueue, //阻塞队列,如果任务很多超过最大线程的处理能力,剩下的任务就会被放入该队列里面等待,
        ThreadFactory threadFactory, //线程池的创建工厂
        RejectedExecutionHandler handler //如果队列满了,按照该指定的拒绝策略拒绝执行任务
) 类来实现

* 工作顺序:
* 1)、线程池创建,准备好core数量的核心线程,准备接受任务
* 1.1、core满了,就将再进来的任务放入阻塞队列中。空闲的core就会自己去阻塞队列获取任务执行
* 1.2、阻塞队列满了,就直接开新线程执行,最大只能开到max指定的数量
* 1.3、max满了就用RejectedExecutionHandler拒绝任务
* 1.4、max都执行完成,有很多空闲.在指定的时间keepAliveTime以后,释放max-core这些线程
*
*      new LinkedBlockingDeque<>():默认是Integer的最大值。内存不够
*
* 一个线程池 core 7; max 20 ,queue:50,100并发进来怎么分配的;
* 7个会立即得到执行,50个会进入队列,再开13个进行执行。剩下的30个就使用拒绝策略。
* 如果不想抛弃还要执行。CallerRunsPolicy;
@Configuration
public class MyThreadConfig {

    @Bean
    public ThreadPoolExecutor threadPoolExecutor(ThreadPoolConfigProperties pool){
       return new ThreadPoolExecutor(pool.getCoreSize(),
                pool.getMaxSize(),pool.getKeepAliveTime(),
                TimeUnit.SECONDS,new LinkedBlockingDeque<>(100000),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());

    }
}

2、创建线程池配置类,以便创建线程池的参数可以在配置文件中配置。

@ConfigurationProperties(prefix = "可以使用项目名区分.thread") #配置文件中配置的前缀
@Component
@Data
public class ThreadPoolConfigProperties {
    //核心线程数
    private Integer coreSize;
    //最大线程数
    private Integer maxSize;
    //超时时间
    private Integer keepAliveTime;
}

3、在需要使用线程池的类中引入线程池:

@Service("skuInfoService")
public class SkuInfoServiceImpl extends ServiceImpl<SkuInfoDao, SkuInfoEntity> implements SkuInfoService {

    @Autowired
    ThreadPoolExecutor executor;

4、在需要多线程业务场景的方法中使用 CompletableFuture (异步编排)类提供的方法来实现异步业务代码的编写:

CompletableFuture infoFuture = CompletableFuture.supplyAsync(() -> {
    //TODO 编写需要异步执行的代码, 并返回业务结果。
    
    return null;
}, executor);

5、需要等异步任务执行完在执行的业务代码前需要调用阻塞方法:

CompletableFuture.allOF(infoFuture).get();

加密算法---BCryptPasswordEncoder的使用及原理:

一 介绍
spring security中的BCryptPasswordEncoder方法采用SHA-256 +随机盐+密钥对密码进行加密。SHA系列是Hash算法,不是加密算法,使用加密算法意味着可以解密(这个与编码/解码一样),但是采用Hash处理,其过程是不可逆的。
(不可逆加密SHA:
        基本原理:加密过程中不需要使用密钥,输入明文后由系统直接经过加密算法处理成密文,这种加密后的数据是无法被解密的,无法根据密文推算出明文。
RSA算法历史:底层-欧拉函数)

1)加密(encode):注册用户时,使用SHA-256+随机盐+密钥把用户输入的密码进行hash处理,得到密码的hash值,然后将其存入数据库中。

2)密码匹配(matches):用户登录时,密码匹配阶段并没有进行密码解密(因为密码经过Hash处理,是不可逆的),而是使用相同的算法把用户输入的密码进行hash处理,得到密码的hash值,然后将其与从数据库中查询到的密码hash值进行比较。如果两者相同,说明用户输入的密码正确。

二 使用

BCryptPasswordEncoder是由spring security的提供的,所以使用前需要引入spring security的依赖

 2.1引入依赖:
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-core</artifactId>
    <version>5.7.6</version>
</dependency>
2.2 添加配置

为了防止有人能根据密文推测出salt,我们需要在使用BCryptPasswordEncoder时配置随即密钥,可以创建一个PasswordConfig配置类,注册BCryptPasswordEncoder对象:

@Data
@Configuration
@ConfigurationProperties(prefix = "encoder.crypt")
public class PasswordConfig {
    /**
     * 加密强度
     */
    private int strength;
    /**
     * 干扰因子
     */
    private String secret;

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {  
        //对干扰因子加密
        SecureRandom secureRandom = new SecureRandom(secret.getBytes());
        //对密码加密
        return new BCryptPasswordEncoder(strength, secureRandom);
    }
}
 2.3 在application.yml 配置文件中添加配置
encoder:
  crypt:
    secret: ${random.uuid} # 随机的密钥,使用uuid
    strength: 6 # 加密强度4~31,决定盐加密时的运算强度,超过10以后加密耗时会显著增加
2.4 单元测试 
@SpringBootTest
class ApplicationTests {
    final static private String password = "123456";
    @Autowired
    private BCryptPasswordEncoder encoder;

    @Test
    void savePassword() {
        // encode():对明文字符串进行加密
        //注册用户时,使用SHA-256+随机盐+密钥把用户输入的密码进行hash处理,得到密码的hash值,然后将其存入数据库中。
        String encode1 = encoder.encode(password);
        System.out.println("encode1:" + encode1);
        String encode2 = encoder.encode(password);
        System.out.println("encode2:" + encode2);

        // matches():对加密前和加密后是否匹配进行验证
        //用户登录时,密码匹配阶段并没有进行密码解密(因为密码经过Hash处理,是不可逆的),
        // 而是使用相同的算法把用户输入的密码进行hash处理,得到密码的hash值,然后将其与从数据库中查询到的密码hash值进行比较。
        // 如果两者相同,说明用户输入的密码正确。
        boolean matches1 = encoder.matches(password, encode1);
        System.out.println("matches1:" + matches1);
        boolean matches2 = encoder.matches(password, encode2);
        System.out.println("matches2:" + matches2);

    }
}

 2.5 结果

RabbitMQ消息队列:

docker run -d --name rabbitmq -p 5671:5671 -p 5672:5672 -p 4369:4369 -p  25672:25672 -p 15671:15671 -p 15672:15672 rabbitmq:management

docker update rabbitmq --restart=always

访问rabbitMQ的web管理界面:http://192.168.3.26:15672/

默认账号核密码都是: guest

Windows查询端口占用:

1、控制台Cmd使用: netstat -ano 命令查看所有端口占用的情况。

2、使用 :netstat -ano|findstr 9000 命令查看9000端口的占用情况。

3、使用:tasklist  列出系统的所用进程。

4、使用:tasklist |findstr 16874 命令查看16874号进程id的应用名是什么。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值