• [算法之美笔记02] 栈模拟网页的前进后退 ; 阻塞队列与并发队列


    本系列是对王争大佬的《数据结构和算法之美》学习笔记

    为了在今后的学习途中, 也要持续巩固自己的数据结构与算法基础

    没想到基于数组元素的删除这种我之前不屑于仔细斟酌的点, 竟然可以引申出一些底层的垃圾回收原理

    没想到链表的增删可以拿来实现缓存机制

    ..

    好吧..实在是太多了

    后序会补上一些代码实现的
    ————————————————

    目录

    浏览器的前进后退

    为什么函数调用要用“栈”来保存临时变量呢?用其他数据结构不行吗?

    阻塞队列与并发队列


    浏览器的前进后退

    特点:我依次在同一个网页中打开了 A    B    C    D,此刻我在D, 我可以回退到C B A,

    但是加入我回退到B 的时候,又点开了一个新的页面E,此刻我在D, 我可以回退到B A,但我再也无法通过回退/前进到C 和D 了

    (再也回不去了) 

    实现思路:

    用两个栈a,b

    a用来放置新打开的页面或者前进的页面,

    b用来放置后退时弹出的页面,以便后退完后仍可以前进

    当a,b中均有页面时,若打开了其他的新页面,就将它们压进栈a,同时清空b(无法再回退到这些页面, 因而需要清空)

    为什么函数调用要用“栈”来保存临时变量呢?用其他数据结构不行吗?


    其实,我们不一定非要用栈来保存临时变量,只不过如果这个函数调用符合后进先出的特性,用栈这种数据结构来实现,是最顺理成章的选择。

    从调用函数进入被调用函数,对于数据来说,变化的是什么呢?是作用域。所以根本上,只要能保证每进入一个新的函数,都是一个新的作用域就可以。而要实现这个,用栈就非常方便。在进入被调用函数的时候,分配一段栈空间给这个函数的变量,在函数结束的时候,将栈顶复位,正好回到调用函数的作用域内。

    阻塞队列与并发队列

    1.阻塞队列

    • 在队列的基础上增加阻塞操作,就成了阻塞队列。
    • 阻塞队列就是在队列为空的时候,从队头取数据会被阻塞,因为此时还没有数据可取,直到队列中有了数据才能返回;如果队列已经满了,那么插入数据的操作就会被阻塞,直到队列中有空闲位置后再插入数据,然后在返回。
    • 从上面的定义可以看出这就是一个“生产者-消费者模型”。这种基于阻塞队列实现的“生产者-消费者模型”可以有效地协调生产和消费的速度。当“生产者”生产数据的速度过快,“消费者”来不及消费时,存储数据的队列很快就会满了,这时生产者就阻塞等待,直到“消费者”消费了数据,“生产者”才会被唤醒继续生产。不仅如此,基于阻塞队列,我们还可以通过协调“生产者”和“消费者”的个数,来提高数据处理效率,比如配置几个消费者,来应对一个生产者。

    2.并发队列

    • 在多线程的情况下,会有多个线程同时操作队列,这时就会存在线程安全问题。能够有效解决线程安全问题的队列就称为并发队列。
    • 并发队列简单的实现就是在入队enqueue()、出队dequeue()方法上加锁,但是锁粒度大并发度会比较低,同一时刻仅允许一个存或取操作
    • 实际上,基于数组的循环队列利用CAS原子操作,可以实现非常高效的并发队列。这也是循环队列比链式队列应用更加广泛的原因。

    循环队列的长度设定需要对并发数据有一定的预测,否则会丢失太多请求.

    CAS原子操作暂不会去做深入了解, 收藏了一篇讲解

    原子操作CAS及其实现类 - 简书 (jianshu.com)icon-default.png?t=LA92https://www.jianshu.com/p/5ee20d1128da

    3.线程池资源枯竭是的处理
    在资源有限的场景,当没有空闲资源时,基本上都可以通过“队列”这种数据结构来实现请求排队。

  • 相关阅读:
    冒泡排序算法。
    深入浅出UML类图(一)转
    树形结构的处理—组合模式(五)
    树形结构的处理—组合模式(四)
    树形结构的处理—组合模式(三)
    树形结构的处理—组合模式(二)
    树形结构的处理—组合模式(一)
    如何成为优秀的软件模型设计者? 转
    软件架构与架构师 转
    深入浅出外观模式(三)
  • 原文地址:https://www.cnblogs.com/Knight02/p/15799014.html
Copyright © 2020-2023  润新知