备战秋招003(20230705)


前言

提示:这里为每天自己的学习内容心情总结;

Learn By Doing,Now or Never,Writing is organized thinking.


提示:以下是本篇文章正文内容

一、今天学习了什么?

  • 原子性;
  • CAS;
  • Java内存模型;
  • volatile
  • Redis;

二、关于问题的答案

1.原子性

Q:什么是原子性?

原子性指的是,这个操作或者这组操作不能被中断,必须一气呵成。

Q:处理器如何实现原子性?

处理器通过两种操作保证原子性:总线锁定、缓存锁定。

「总线锁定」,指的是一个处理器发射出 LOCK 信号,然后其它的处理器接收到这个信号后,不能和主存进行交互,保证了当前时刻只能有一个处理器独占内存。

「缓存锁定」,由于总线锁定是一个并发度低的操作,其它的处理器都不能和主存进行沟通交流。所以,引入「缓存锁定」。缓存锁定是,每次更新处理器缓存中的数据,由缓存一致性协议(MESI)保证缓存一致性。

Q:Java如何实现原子性?

Java中通过「锁」和「循环CAS」保证原子性。

2.CAS

Q:什么是CAS?

CAS 的全称是比较和交换,是乐观锁的思想,搭配「volatile」关键字可以实现无锁并发。

主要有三个变量:

  • 内存地址,v;
  • 当前值,A;
  • 更新值,B;

如果内存地址的值和A相同,则将内存地址的值更新为B。

Q:CAS的底层实现原理?

CAS 的底层实现原理,是通过 Unsafe 类的三个 native 方法,compareAndSwapXXXX;

这三个方法对应的是通过调用操作系统的一个原语实现的,CMPXCHG,由操作系统保证完成。

Q:CAS可能导致的三个问题?

「ABA」问题,如果某个线程将共享数据从A修改为B,最后又修改成A。这个修改过程,是无法被感知到的,因为CAS只是判断内存地址的数据结果。

针对这个问题,JDK 有两个实现类解决了,通过给共享数据加版本号的方式,这两个实现类是:AtomicStampedReference、AtomicMarkableReference;

加上版本号之后,不仅需要比较内存地址的数值,还需要比较版本号是否相同;

「CAS一直自旋带来的性能损耗」,如果使用CAS尝试获取锁资源一直没有成功,导致CPU一直处于自旋状态,会引起性能损耗。

「只适用于对一个变量的操作」,如果需要对多个变量保证原子性操作,建议使用锁。

3.Java内存模型

Q:什么是Java内存模型?

「Java 内存模型」是一种规范,为了保证线程操作共享资源时的可见性。

JMM 定义了所有的共享变量资源都存储在主存中,而每个线程都有属于自己的本地内存,线程不能访问其它线程的本地内存。

线程之间必须通过主存进行数据的沟通交流。

JMM 通过控制「主存」和「本地内存」完成线程之间的数据交互,实现线程之间的可见性。

4.volatile

Q:什么是volatile?

被「volatile」关键字修饰的变量有两层含义,有序性、可见性。

Q:volatile的底层实现原理?

volatile 的「底层实现原理」是通过操作系统的内存屏障实现的,对于volatile的「写」操作,会加入写屏障,对于volatile的「读」操作,会加入读屏障。

「写屏障」保证对volatile修饰的变量的写操作,会立马同步到主存,并且对其它线程可见,写操作之前的指令不会重排序到写操作之后。

「读屏障」保证对volatile修饰的变量的读操作,总是会从主存中读取最新的数值,都操作之前的指令不会重排序到读操作之后。

5.Redis

Q:什么是Redis?你可以简单的介绍一下你对Redis的了解吗?

Redis 是基于 C语言,一种基于内存的NoSQL型数据库,速度极快,常作用于:缓存、消息队列、分布式锁。

Q:Redis和Memcached的区别?为什么不用Memcached呢?

共同点:

  1. 都是基于内存的数据库;
  2. 性能高;
  3. 都有过期策略;

不同点:

  1. Redis有多种数据类型,而Memcached只有key-value类型;
  2. Redis可以数据持久化,即使发生宕机或者挂机、停机,可以恢复数据,而Memcached只要停机了数据是完全基于内存的,会丢失数据;
  3. Redis支持原生的集群模式,Memcached不支持;
  4. Redis还可以使用事务、lua脚本语言、发布订阅模型;Memcached不支持;

Q:为什么Redis可以用来做缓存呢?

「高性能」,Redis是基于内存的,如果每次查找数据都是从 MySQL 中查找,需要从硬盘中读取数据到性能很慢。

如果将部分数据缓存在内存Redis中,去内存中查找数据就会很快。

「高并发」,Redis的QPS是MySQL的10倍,单机Redis的QPS可以达到10w。

Q:Redis的数据类型及应用场景,你可以介绍一下吗?

五种基本数据类型:

  1. String,存储token、json串、图片地址;计数自增自减;分布式锁;
  2. List,存储文章列表;消息队列;
  3. Hash,个人信息、商品详情等;
  4. Set,共同关注、点赞;
  5. Zset,排行榜等;

四种独特的类型:

  1. Bitmaps,签到打卡;
  2. HyperLogLog,百万千万级,统计网站UV;
  3. Geo,地理信息,滴滴打车,附近的人;
  4. Stream,消息队列;

Q:Redis的SDS数据结构你可以介绍一下吗?为什么不使用C语言的字符串呢?

「C语言字符串的坏处」:

  1. 获取字符串的长度,时间复杂度为O(N);
  2. 无法存储二进制数据;
  3. 可能存在缓冲区溢出;

「SDS」数据结构,有四个关键的属性:

  • len,字符串长度;
  • alloc,字符串的内存大小;
  • flags,字符串类型;
  • buf[],字符串数组;

解决了C语言字符串的三个问题。


总结

提示:这里对文章进行总结:

今天总算学习状态稍微好了点,希望明天再接再厉,明天需要完成:

  • 组会汇报;
  • Redis数据结构;
  • 复习SE;
  • 刷算法题;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值