java面经查缺补漏之第五十天(基本类型和引用类型,秒杀大概思路,nginx限流,限流算法,unsafe类,多线程的通信方式,juc阻塞队列,死锁的解决方式)

前几天申请的博客专家失败了,原因是半年基本上说我都是在记录日常。难道我起的名字日常,内容就很日常了吗?我的名字就是一天一道编程题,查缺补漏第多少天。这半年都在专注于算法数据结构的学习,以及javaweb理论的研究,可能是觉得博客的深度不够吧,从今天起,本博客将不注重产量,而转而注重博客的深度,以及长文了,偶尔发一下这种查缺补漏的内容吧。加油!

1.java基本类型和引用类型的区别?

参考:https://www.cnblogs.com/maskwolf/p/9972982.html

8大基本数据类型,byte,boolean,char,int,short,long,float,double

引用类型,类,字符串等,除了基本,大概都是引用类型。

区别一 存储位置

基本数据类型作为非全局变量存储在栈当中。

引用类型具体内容很多都存储在堆中,然后栈中存储一个指针,指向这个内存地址。

2. 秒杀系统实现大概都要什么技术?

(1)从架构上说

分布式+集群,对服务器进行物理上的扩容

(2)从负载均衡上说

利用nginx实现负载均衡,并对某一个ip进行ip级别的限流

(3)将页面静态化

因为页面上的一些数据也会请求后端服务器,对服务器造成压力。

(4)加入缓存

加入redis缓存来提升性能。

(5)引入消息队列

用消息队列来进行削峰,也可以用于保证数据的一致性。

3. nginx如何限流?限流算法有哪些?

令牌桶算法:维护一个令牌桶,匀速往里面放令牌,请求来了之后,拿一个令牌才可以得到处理。如果令牌桶满了,则丢弃,如果没有了,则将多余的请求先缓存。

漏桶算法:一个装水的桶表示队列,漏出的水表示进行处理的,里面的水表示请求,溢出的请求可以直接丢弃,也可以用另一个东西缓存一点。

nginx使用的漏桶算法进行限流。

nginx主要有两个配置:

limit_req_zone 用来限制单位时间内的请求数。

limit_conn_zone限制单个IP的请求数。

(1)limit_req_zone

http {
    //$binary_remote_addr 表示通过remote_addr这个标识来做限制,“binary_”的目的是缩写内存占用量,是限制同一客户端ip地址。
    //zone=one:10m表示生成一个大小为10M,名字为one的内存区域,用来存储访问的频次信息。
    //rate=1r/s表示允许相同标识的客户端的访问频次,这里限制的是每秒1次
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
    server {
        //限制拦截的url
        //zone=one 设置使用哪个配置区域来做限制,与上面limit_req_zone 里的name对应。
        //设置一个大小为5的缓冲区当有大量请求(爆发)过来时,超过了访问频次限制的请求可以先放到这个缓冲区内。
        //设置,超过访问频次而且缓冲区也满了的时候就会直接返回503,如果没有设置,则所有请求会等待排队。
        location /search/ {
            limit_req zone=one burst=5 nodelay;
        }
} 

同时nginx也可以限制搜索引擎,打印日志,设置拒绝返回值。

(2)limit_conn_zone

limit_conn_zone $binary_remote_addr zone=addr:10m;

server {
    location /download/ {
        //一次只允许每个IP地址一个连接。
        limit_conn addr 1;
    }

4. java中的unsafe类?

unsafe类可以直接操作内存,不受jvm管理,也就意味着无法被GC,需要我们手动GC,稍有不慎就会出现内存泄漏。直接操作内存,也意味着其速度更快,在高并发的条件之下能够很好地提高效率。

里面比较重要的就是内存屏障和CAS的相关方法。

5. 多线程的通信方式?

synchronized的等待唤醒机制wait(),notify()。

reentrantlock的lock(),unlock(),condition的await(),signalAll()

6. juc阻塞队列?

什么是阻塞队列

一个线程从一个空的阻塞队列中取元素,此时线程会被阻塞直到阻塞队列中有了元素。当队列中有元素后,被阻塞的线程会自动被唤醒(不需要我们编写代码去唤醒)。这样提供了极大的方便性。

阻塞队列的主要种类

ArrayBlockingQueue:基于数组实现的阻塞队列,先进先出队列,有界队列。在创建时必须制定容量大小。并可以指定公平性与非公平性,默认情况下是非公平的,即不保证等待时间最长的队列最优先能够访问队列。

LinkedBlockingQueue:基于链表实现的阻塞队列,先进先出队列,有界队列。在创建时如果不指定容量大小,则默认大小为Integer.MAX_VALUE。

PriorityBlockingQueue:按照元素的优先级对元素进行排序,按照优先级顺序出队。并且该阻塞队列为无界阻塞队列,即容量没有上限(源码中它没有容器满的信号标志)。

DelayQueue:基于PriorityQueue的延时阻塞队列,无界队列。DelayQueue中的元素只有当其指定的延迟时间到了,才能够从队列中获取到该元素。因为DelayQueue是一个无界队列,所以往队列中插入数据的操作永远不会被阻塞,而只有获取数据的操作才会被阻塞。

阻塞队列的主要方法

put方法用来向队尾存入元素,如果队列满,则等待;

take方法用来从队首取元素,如果队列为空,则等待;

offer方法用来向队尾存入元素,如果队列满,则等待一定的时间,当时间期限达到时,如果还没有插入成功,则返回false;否则返回true;

poll方法用来从队首取元素,如果队列空,则等待一定的时间,当时间期限达到时,如果取到,则返回取得的元素;否则返回null。

7. 死锁的解决方式?

预防死锁,破坏四个必要条件,破坏其中的一个,死锁就不能产生。

避免死锁,加锁顺序,加锁时限

检测和解除,检测到了死锁可以采用回退的方式解决。

 

 

 

 

 关注微信公众号,你还有头发吗,获取更多java软件开发学习资源,覆盖java基础,android,网络编程,并发编程,mysql,linux,算法,以及C++和python书籍资源。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章