精华内容
下载资源
问答
  • 单位整体网络安全提升方案.pdf
  • 安全文明施工提升方案.doc
  • 餐饮质量安全提升实施方案.pdf
  • 某地产安全文明施工品质提升方案.pptx
  • 物料提升机搭拆安全施工方案.docx
  • 基于量子保密通信的综合能源业务数据安全提升解决方案.docx
  • 提升行为安全指数实施方案.doc
  • 事故水塔水柜预制提升安全专项施工方案.docx
  • 项目工程质量安全三年提升行动方案及对策.doc
  • 公园提升改造工程项目深基坑施工安全专项方案培训资料.docx
  • 深基坑施工安全专项方案渭南市渭清公园提升改造项目.docx
  • XX项目电梯井整体提升搭设安全专项施工方案2021最新.doc
  • 农村饮水安全巩固提升集中供水工程实施方案编制指南.docx
  • 提升电力系统现有网络安全防御体系的解决方案.pdf
  • 农村饮水安全巩固提升水厂建设实施计划方案及对策.doc
  • 江西省农村饮水安全巩固提升集中供水工程实施方案编制指南.docx
  • 电信和互联网行业提升网络数据安全保护能力专项行动方案.pdf
  • XX项目电梯井整体提升架搭设安全专项施工方案编制要点、审核要点2021最新.doc
  • 电信和互联网行业提升网络数据安全保护能力专项行动方案 近年来随着国家大数据发展战略加快实施大数据技术创新与应用日趋活 跃产生和集聚了类型丰富多样应用价值不断提升的海量网络数据成为 数字经济发展的关键生产...
  • 电信和互联网行业提升网络数据安全保护能力专项行动方案 (1).pdf
  • 工业和信息化部办公厅关于印发 心(电信和互联网行业提升网络数据安全保护能力专项行8 动方案的通知解读 制作日期 2019年8月12日星期一 概述 电信和互联网行业提升网络数据安全保护能力专项 行动方案工信厅网安...
  • 建筑施工组织2021-茅台酒厂12#酒库工程物料提升机安装(拆卸)安全技术方案.doc
  • 从矿井提升机的改造技术背景、具体改造方案设计、提升机主要配置说明3个方面阐述了矿井提升机改造方案设计的全过程。方案设计中,根据实际技术参数需求,通过计算校核,设计出合理的改造方案。该改造方案完成后,全套...
  • 企业安全建设之矩阵式监控提升安全有效性实践 区块链 云安全 红蓝对抗 金融安全 安全方案与集成
  • 针对建井期间主、副斜井长距离进行提升,施工期间调度绞车无法满足能力需要的情况,结合原设计方案,提出二级提升设计方案设想,从经济上、技术上、安全上对方案优缺点进行对比分析,选取最佳的设计方案,并进行合理的施工...
  • 介绍了马脊梁矿在延伸改造工程新增副立井的提升系统设计时,采用落地式单层特制加宽罐笼+平衡锤提升方式和支架拖运...该方案在满足副立井提升系统的安全和功能要求的前提下,最大化地减少了井筒直径,进而节约了投资成本。
  • 淮阴区农村饮水安全巩固提升工程三期管网安装施工01标段南陈集镇工程施工设计方案.doc
  • 软件测试质量提升方案(初稿)

    千次阅读 2020-01-02 14:48:13
    软件测试质量提升方案(初稿) 提升软件质量的目的是使我们的产品满足用户需求,拥有可靠的质量和很好的用户体验,下面我将从测试流程优化、测试技能提升、测试经验累积三个方面谈下测试质量的提升方案。 一、测试...

    软件测试质量提升方案(初稿)

    提升软件质量的目的是使我们的产品满足用户需求,拥有可靠的质量和很好的用户体验,下面我将从测试流程优化、测试技能提升、测试经验累积三个方面谈下测试质量的提升方案。

    一、测试流程优化

    项目开始时,测试人员就应该介入,正确理解需求文档,对需求文档进行评审,进行需求分析,对不明确的需求项,需要产品人员进行沟通,要求需求反讲。要求产品人员按需求制定上线的验收标准。
    根据需求估算测试所需资源(人力、设备等)、所需时间、功能点划分、如何合理分配安排资源等,测试计划会影响测试执行,计划一旦制定就尽量的按照这个计划去执行。
    根据测试计划、任务分配、功能点划分,设计合理的测试用例,所有功能点和需求规则都要被覆盖,多考虑业务层面的测试用例,多考虑异常场景的测试,多考虑测试的结果检查,需要组织用例评审;有条件的话,可以安排多个人员对同一需求分开设计用例,然后再进行整合,使用例更全面。
    开发人员提测前,需要他们进行自测,把测试用例中优先级高的用例执行一遍,通过后再提测,然后我们至少进行一轮冒烟测试,一轮常规测试,一轮回归测试,总结针对每一个功能模块,用什么方式执行才是最全面有效的,不容易出现漏测问题,另外,还需要总结测试执行过程中需要参考的文档以及工具,让测试更加高效。
    测试执行完成后,及时编写测试报告,及时反馈测试情况与测试结果,提出全面的合理的风险与建议。SIT测试通过后,需要产品按照制定好的上线验收标准进行UAT测试,并输出结果。UAT测试通过后,版本发布上线,需要测试、开发、产品和现场人员共同进行上线功能验证,验证通过后方可对外开放。
    产品上线时,必要情况下需进行试点测试,测试与产品人员密切沟通,在试点环境下多进行在公司无法进行的场景模拟测试。

    二、测试技能提升

    工欲善其事必先利其器,测试人员在产品研发中需要做的工作有需求评审,风险评估,选取测试工具,撰写测试计划,搭建测试环境,准备测试数据,设计测试用例,执行测试用例,输出测试报告,分析总结测试活动经验。其中每个环节都对测试人员有相应的技能要求,熟练的技能能更高效,更顺利的开展测试活动,发现更多更有效的缺陷,更好的帮助开发人员定位问题,帮助产品设计人员完善产品的功能,从而提升产品的质量。
    需要不断提升自己的文档编写能力,测试过程中,高质量的测试方案、测试计划和测试用例,对整个产品的质量把控起很重要的作用,测试人员应该多思考、多结合实际场景、多考虑异常场景去编写测试文档。
    需要加强静态测试能力,对项目各阶段的文档进行评审,对软件开发活动进行审查,对程序源代码进行测试,审查每个阶段的输入和输出是否规范,要记录所有不符合规范的事件。
    提升自己执行测试的能力,多掌握专项测试的技能,包括接口测试、APP测试、兼容性测试、界面测试、易用性测试、压力测试、负载测试、确认测试、容错性测试、稳定性测试、可靠性测试、风险测试、网络测试、异常测试、性能测试、自动化测试、安全测试。
    提升自己的沟通能力,多与产品及开发人员进行沟通,遇到问题或者风险时都要及时反馈,与产品和开发一起思考讨论分析,及时把问题解决,不能搁置不管,测试人员还需担任项目的督促者,遇到一些悬而未决的问题时,一定要及时跟进。

    三、测试经验累积

    测试流程中输出的文档及时归档,测试完成每一轮后,都及时输出还轮的测试小结,整个测试完成后,输出测试总结。
    测试过程中及时记录自己遇到的问题及解决办法,多积累多思考,养成经验总结的好习惯。
    项目上线后,需要实时跟进生产反馈的问题,针对生产反馈的问题,首先进行验证并跟进解决进度,然后总结问题的原因,及时更新测试用例、测试方案,以此来规避再次发生此问题。
    项目测试完成上线后,需要做项目总结,总结项目测试过程中做的好和不好的地方,发扬优点,改进缺点。

    展开全文
  • 为了确保煤矿提升机安全运行,分析了提升机齿轮箱故障、齿轮箱振动故障机理、煤矿提升机电机故障以及煤矿提升机滚筒故障。设计了提升机故障诊断系统方案,根据煤矿提升机的技术参数...研究为矿井安全提升提供了理论支持。
  • 同步锁-线程安全问题解决方案

    万次阅读 多人点赞 2021-03-21 15:12:05
    经过前面多线程编程的学习,我们遇到了线程安全的相关问题,比如多线程售票情景下的超卖/重卖现象. 上节笔记点这里-进程与线程笔记 我们如何判断程序有没有可能出现线程安全问题,主要有以下三个条件: 在多线程程序中 +...

    1 同步锁

    1.1 前言

    经过前面多线程编程的学习,我们遇到了线程安全的相关问题,比如多线程售票情景下的超卖/重卖现象.
    上节笔记点这里-进程与线程笔记

    我们如何判断程序有没有可能出现线程安全问题,主要有以下三个条件:

    在多线程程序中 + 有共享数据 + 多条语句操作共享数据

    多线程的场景和共享数据的条件是改变不了的(就像4个窗口一起卖100张票,这个是业务)
    所以思路可以从第3点"多条语句操作共享数据"入手,既然是在这多条语句操作数据过程中出现了问题
    那我们可以把有可能出现问题的代码都包裹起来,一次只让一个线程来执行

    1.2 同步与异步

    那怎么"把有可能出现问题的代码都包裹起来"呢?我们可以使用synchronized关键字来实现同步效果
    也就是说,当多个对象操作共享数据时,可以使用同步锁解决线程安全问题,被锁住的代码就是同步的

    接下来介绍下同步与异步的概念:
    同步:体现了排队的效果,同一时刻只能有一个线程独占资源,其他没有权利的线程排队。
    坏处就是效率会降低,不过保证了安全。
    异步:体现了多线程抢占资源的效果,线程间互相不等待,互相抢占资源。
    坏处就是有安全隐患,效率要高一些。

    1.3 synchronized同步关键字

    1.3.1 写法

    synchronized (锁对象){
    需要同步的代码(也就是可能出现问题的操作共享数据的多条语句);
    }

    1.3.2 前提

    同步效果的使用有两个前提:

    • 前提1:同步需要两个或者两个以上的线程(单线程无需考虑多线程安全问题)
    • 前提2:多个线程间必须使用同一个锁(我上锁后其他人也能看到这个锁,不然我的锁锁不住其他人,就没有了上锁的效果)

    1.3.3 特点

    1. synchronized同步关键字可以用来修饰代码块,称为同步代码块,使用的锁对象类型任意,但注意:必须唯一!
    2. synchronized同步关键字可以用来修饰方法,称为同步方法
    3. 同步的缺点是会降低程序的执行效率,但我们为了保证线程的安全,有些性能是必须要牺牲的
    4. 但是为了性能,加锁的范围需要控制好,比如我们不需要给整个商场加锁,试衣间加锁就可以了

    为什么同步代码块的锁对象可以是任意的同一个对象,但是同步方法使用的是this呢?
    因为同步代码块可以保证同一个时刻只有一个线程进入
    但同步方法不可以保证同一时刻只能有一个线程调用,所以使用本类代指对象this来确保同步

    同步与异步

    1.4.1练习-改造售票案例

    创建包: cn.tedu.tickets
    创建类:TestRunnableV2.java

    package cn.tedu.tickets;
    
    /*本类用于改造多线程售票案例,解决数据安全问题*/
    public class TestRunnableV2 {
        public static void main(String[] args) {
            //5.创建目标业务类对象
            TicketR2 target = new TicketR2();
            //6.创建线程对象
            Thread t1 = new Thread(target);
            Thread t2 = new Thread(target);
            Thread t3 = new Thread(target);
            Thread t4 = new Thread(target);
            //7.以多线程的方式运行
            t1.start();
            t2.start();
            t3.start();
            t4.start();
        }
    }
    
    /*1.多线程中出现数据安全问题的原因:多线程程序+共享数据+多条语句操作共享数据*/
    /*2.同步锁:相当于给容易出现问题的代码加了一把锁,包裹了所有可能会出现数据安全问题的代码
     * 加锁之后,就有了同步(排队)的效果,但是加锁的话,需要考虑:
     * 锁的范围:不能太大,太大,干啥都得排队,也不能太小,太小,锁不住,还是会有安全隐患*/
    //1.创建自定义多线程类
    class TicketR2 implements Runnable {
        //3.定义成员变量,保存票数
        int tickets = 100;
        //创建锁对象
        Object o = new Object();
    
        //2.实现接口中未实现的方法,run()中放着的是我们的业务
        @Override
        public void run() {
            //4.通过循环结构完成业务
            while (true) {
                /*3.同步代码块:synchronized(锁对象){会出现安全隐患的所有代码}
                 * 同步代码块在同一时刻,同一资源只会被一个线程独享*/
                /*这种写法不对,相当于每个线程进来的时候都会new一个锁对象,线程间使用的并不是同一把锁*/
                //synchronized (new Object()){
                //修改同步代码块的锁对象为成员变量o,因为锁对象必须唯一
                synchronized (o) {//同步代码块解决的是重卖的问题
                    //如果票数>0就卖票
                    if (tickets > 0) {
                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        //4.1打印当前正在售票的线程名以及票数-1
                        System.out.println(Thread.currentThread().getName() + "=" + tickets--);
                    }
                    //4.2退出死循环--没票的时候就结束
                    if (tickets <= 0) break;
                }
            }
        }
    }
    

    1.4.2 练习-改造售票案例

    创建包: cn.tedu.tickets
    创建类:TestThreadV2.java

    package cn.tedu.tickets;
    
    /*本类用于改造多线程售票案例,解决数据安全问题*/
    public class TestThreadV2 {
        public static void main(String[] args) {
            //5.创建多个线程对象并以多线程的方式运行
            TickectT2 t1 = new TickectT2();
            TickectT2 t2 = new TickectT2();
            TickectT2 t3 = new TickectT2();
            TickectT2 t4 = new TickectT2();
            t1.start();
            t2.start();
            t3.start();
            t4.start();
        }
    }
    
    //1.自定义多线程类
    class TickectT2 extends Thread {
        //3.新增成员变量用来保存票数
        static int tickets = 100;
        //static Object o = new Object();
    
        //2.添加重写的run()来完成业务
        @Override
        public void run() {
            //3.创建循环结构用来卖票
            while (true) {
                //Ctrl+Alt+L调整代码缩进
                //7.添加同步代码块,解决数据安全问题
                //synchronized (new Object()) {
                /*static的Object的对象o这种写法也可以*/
                //synchronized (o) {
                /*我们每通过class关键字创建一个类,就会在工作空间中生成一个唯一对应的类名.class字节码文件
                * 这个类名.class对应的对象我们称之为这个类的字节码对象
                * 字节码对象极其重要,是反射技术的基石,字节码对象中包含了当前类所有的关键信息
                * 所以,用这样一个唯一且明确的对象作为同步代码块的锁对象,再合适不过了*/
                synchronized (TickectT2.class) {/*比较标准的写法*/
                    if(tickets > 0){
                        //6.添加线程休眠,暴露问题
                        try {
                            Thread.sleep(10);//让线程休眠,增加线程状态切换的频率
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        //4.1打印当前正在售票的线程名与票数-1
                        System.out.println(getName() + "=" + tickets--);
                    }
                    //4.2给程序设置一个出口,没有票的时候就停止卖票
                    if (tickets <= 0) break;
                }
            }
        }
    }
    

    注意:如果是继承的方式的话,锁对象最好用"类名.class",否则创建自定义线程类多个对象时,无法保证锁的唯一

    1.5 之前遇到过的同步例子

    StringBuffer JDK1.0
    加了synchronized ,性能相对较低(要排队,同步),安全性高
    StringBuilder JDK1.5
    去掉了synchronized,性能更高(不排队,异步),存在安全隐患
    其他同步异步的例子

    快速查找某个类的快捷键:Ctrl+Shift+T

    2 线程创建的其他方式

    2.1 ExecutorService/Executors

    ExecutorService:用来存储线程的池子,把新建线程/启动线程/关闭线程的任务都交给池来管理

    • execute(Runnable任务对象) 把任务丢到线程池

    Executors 辅助创建线程池的工具类

    • newFixedThreadPool(int nThreads) 最多n个线程的线程池
    • newCachedThreadPool() 足够多的线程,使任务不必等待
    • newSingleThreadExecutor() 只有一个线程的线程池

    2.2 练习:线程的其他创建方式

    创建包: cn.tedu.tickets
    创建类: TestThreadPool.java

    package cn.tedu.tickets;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    /*本类用于测试线程池*/
    public class TestThreadPool {
        public static void main(String[] args) {
            //5.创建接口实现类TicketR3类的对象作为目标业务对象
            TicketR3 target = new TicketR3();
            /*Executors是用来辅助创建线程池的工具类对象
            * 常用方法是newFixedThreadPool(int)这个方法可以创建指定数目的线程池对象
            * 创建出来的线程池对象是ExecutorService:用来存储线程的池子,负责:新建/启动/关闭线程*/
            //6.使用Executors工具创建一个最多有5个线程的线程池对象ExecutorService池对象
            ExecutorService pool = Executors.newFixedThreadPool(5);
            for (int i = 0; i < 5; i++) {
                /*execute()让线程池中的线程来执行业务,每次调用都会将一个线程加入到就绪队列*/
                pool.execute(target);/*本方法的参数就是你要执行的业务,也就是目标业务类对象*/
            }
        }
    }
    //同步锁问题解决方案笔记:1.4.1从26行复制到58行,TicketR2改成TicketR3
    //1.创建自定义多线程类
    class TicketR3 implements Runnable {
        //3.定义成员变量,保存票数
        int tickets = 100;
        //创建锁对象
        Object o = new Object();
    
        //2.实现接口中未实现的方法,run()中放着的是我们的业务
        @Override
        public void run() {
            //4.通过循环结构完成业务
            while (true) {
                /*3.同步代码块:synchronized(锁对象){会出现安全隐患的所有代码}
                 * 同步代码块在同一时刻,同一资源只会被一个线程独享*/
                /*这种写法不对,相当于每个线程进来的时候都会new一个锁对象,线程间使用的并不是同一把锁*/
                //synchronized (new Object()){
                //修改同步代码块的锁对象为成员变量o,因为锁对象必须唯一
                synchronized (o) {//同步代码块解决的是重卖的问题
                    //如果票数>0就卖票
                    if (tickets > 0) {
                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        //4.1打印当前正在售票的线程名以及票数-1
                        System.out.println(Thread.currentThread().getName() + "=" + tickets--);
                    }
                    //4.2退出死循环--没票的时候就结束
                    if (tickets <= 0) break;
                }
            }
        }
    }
    

    3 拓展:线程锁

    3.1 悲观锁和乐观锁

    悲观锁:像它的名字一样,对于并发间操作产生的线程安全问题持悲观状态.
    悲观锁认为竞争总是会发生,因此每次对某资源进行操作时,都会持有一个独占的锁,就像synchronized,不管三七二十一,直接上了锁就操作资源了。

    乐观锁:还是像它的名字一样,对于并发间操作产生的线程安全问题持乐观状态.
    乐观锁认为竞争不总是会发生,因此它不需要持有锁,将”比较-替换”这两个动作作为一个原子操作尝试去修改内存中的变量,如果失败则表示发生冲突,那么就应该有相应的重试逻辑。

    3.2 两种常见的锁

    synchronized 互斥锁(悲观锁,有罪假设)

    采用synchronized修饰符实现的同步机制叫做互斥锁机制,它所获得的锁叫做互斥锁。
    每个对象都有一个monitor(锁标记),当线程拥有这个锁标记时才能访问这个资源,没有锁标记便进入锁池。任何一个对象系统都会为其创建一个互斥锁,这个锁是为了分配给线程的,防止打断原子操作。每个对象的锁只能分配给一个线程,因此叫做互斥锁。

    ReentrantLock 排他锁(悲观锁,有罪假设)

    ReentrantLock是排他锁,排他锁在同一时刻仅有一个线程可以进行访问,实际上独占锁是一种相对比较保守的锁策略,在这种情况下任何“读/读”、“读/写”、“写/写”操作都不能同时发生,这在一定程度上降低了吞吐量。然而读操作之间不存在数据竞争问题,如果”读/读”操作能够以共享锁的方式进行,那会进一步提升性能。

    ReentrantReadWriteLock 读写锁(乐观锁,无罪假设)

    因此引入了ReentrantReadWriteLock,顾名思义,ReentrantReadWriteLock是Reentrant(可重入)Read(读)Write(写)Lock(锁),我们下面称它为读写锁。
    读写锁内部又分为读锁和写锁,读锁可以在没有写锁的时候被多个线程同时持有,写锁是独占的。
    读锁和写锁分离从而提升程序性能,读写锁主要应用于读多写少的场景。

    3.3 尝试用读写锁改造售票案例

    package cn.tedu.thread;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    /**
     * 本类用于改造售票案例,使用可重入读写锁
     * ReentrantReadWriteLock
     * */
    public class TestSaleTicketsV3 {
    	public static void main(String[] args) {
    		SaleTicketsV3 target = new SaleTicketsV3();
    		Thread t1 = new Thread(target);
    		Thread t2 = new Thread(target);
    		Thread t3 = new Thread(target);
    		Thread t4 = new Thread(target);
    		t1.start();
    		t2.start();
    		t3.start();
    		t4.start();
    	}
    }
    class SaleTicketsV3 implements Runnable{
    	static int tickets = 100;
    	//1.定义可重入读写锁对象,静态保证全局唯一
    	static ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
    	@Override
    	public void run() {
    		while(true) {
    			//2.在操作共享资源前上锁
    			lock.writeLock().lock();
    			try {
    				if(tickets > 0) {
    					try {
    						Thread.sleep(10);
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    					System.out.println(Thread.currentThread().getName() + "=" + tickets--);
    				}
    				if(tickets <= 0) break;
    			} catch (Exception e) {
    				e.printStackTrace();
    			}finally {
    				//3.finally{}中释放锁,注意一定要手动释放,防止死锁,否则就独占报错了
    				lock.writeLock().unlock();
    			}
    		}
    	}
    } 
    

    3.4 两种方式的区别

    需要注意的是,用sychronized修饰的方法或者语句块在代码执行完之后锁会自动释放,而是用Lock需要我们手动释放锁,所以为了保证锁最终被释放(发生异常情况),要把互斥区放在try内,释放锁放在finally内!
    与互斥锁相比,读-写锁允许对共享数据进行更高级别的并发访问。虽然一次只有一个线程(writer 线程)可以修改共享数据,但在许多情况下,任何数量的线程可以同时读取共享数据(reader 线程)从理论上讲,与互斥锁定相比,使用读-写锁允许的并发性增强将带来更大的性能提高。

    恭喜你,线程与线程锁的学习可以暂时告一段落啦,接着我们可以继续学习别的内容

    下一节 设计模式 点这里

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 226,366
精华内容 90,546
关键字:

安全提升方案