先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新软件测试全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip1024b (备注软件测试)
正文
进程正在被创建,尚未转到就绪状态。创建进程通常需要多个步骤:首先申请一个空白的PCB,并向PCB中填写一些控制和管理进程的信息。然后由系统为该进程分配运行时所需的资源。最后把该进程转入到就绪状态。
5)结束状态
进程正从系统中消失,可能是进程正常结束或其他原因中断退出运行。当进程需要结束运行时,系统首先必须置该进程为结束状态,然后再进一步处理资源释放和回收等工作。
区别就绪状态和等待状态:
就绪状态是指进程仅仅缺少处理机,只要获得处理机资源就能立即执行。等待状态是指进程需要其他资源(除了处理机)或等待某一事件。
之所以把处理机和其他资源划分开,是因为在分时系统的时间片轮转机制中,每个进程分到的时间片是若干毫秒。也就是说,进程得到处理机的时间很短且非常频繁,进程在运行过程中实际上是频繁的转换到就绪状态的。而其他资源(外设等)的使用和分配或者某一事件的发生(如I/O操作)对应的时间相对来说很长,进程转换到等待状态的次数也相对较少。所以,就绪状态和等待状态是进程生命周期中两个完全不同的状态,需要加以区分。
进程的相互转换
1)就绪状态->运行状态
处于就绪状态的进程被调度后,获得处理机资源(分派处理机时间片),于是进程由就绪状态转换为运行状态。
2)运行状态->就绪状态
处于运行状态的进程在时间片用完后,不得不让出处理机,从而进程由运行状态转换为就绪状态。此外,在可剥夺的操作系统当中,当有更高优先级的进程处于就绪状态时:调度程序将正在执行的进程转换为就绪状态,让更高优先级的进程执行。
3)运行状态->阻塞状态
当进程请求某一资源(如外设)的使用和分配或等待某一事件的发生时,它就从运行状态转换为阻塞状态。进程以系统调用的形式请求操作系统提供服务,这是一种特殊的、由运行用户态程序调用操作系统内核过程的形式。
4)阻塞状态->就绪状态
当进程请求的资源可用(被其他进程释放)或者等待的事件到来时,中断处理程序将相应的进程由阻塞状态转换为就绪状态。
进程的调度算法
1)先来先服务调度算法(FCFS,first come first served)
谁第一个进入队列,谁就被先执行,在它被指向的过程中,不会中断;
2)短作业优先调度算法(SJF,shorest job first)
对预计执行时间短的进程优先分配CPU,通常后来的短进程不会抢占正在执行的进程;这种方式对长进程非常不利,可能长时间得不到执行;
3)最高响应比优先调度算法(HRRN,highest response radio next)
这种方法是对于FCFS和SJF的平衡,FCFS方式只考虑每个作业的等待时间而未考虑作业可能执行时间的长短,而SJF只考虑了执行时间而未考虑等待时间的长短,因此两种算法在某种极端情况下会带来很多问题。
HRRN通过综合这两种情况算出响应比R,根据响应比完成调度。
最高响应比优先算法的优点在于长作业也有机会投入运行,但是缺点在于其每次调度前还需要额外计算响应比。
4)时间片轮转法(RR, Round-Robin)
采用剥夺方式,每个进程被分配一个时间段,按照在队列中的顺序交替进行;其使得每个作业都有机会运行,但是这种方式不利于处理紧急作
3.进程间通信方式,并说出优缺点
通信方式
1)管道
管道分为有名管道和无名管道。无名管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用.进程的亲缘关系一般指的是父子关系。无明管道一般用于两个不同进程之间的通信。当一个进程创建了一个管道,并调用fork创建自己的一个子进程后,父进程关闭读管道端,子进程关闭写管道端,这样提供了两个进程之间数据流动的一种方式。有名管道也是一种半双工的通信方式,但是它允许无亲缘关系进程间的通信。
2)信号量
信号量是一个计数器,可以用来控制多个线程对共享资源的访问,它不是用于交换大批数据,而用于多线程之间的同步.它常作为一种锁机制,防止某进程在访问资源时其它进程也访问该资源.因此,主要作为进程间以及同一个进程内不同线程之间的同步手段。
3)信号
信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
4)消息队列
消息队列是消息的链表,存放在内核中并由消息队列标识符标识.消息队列克服了信号传递信息少,管道只能承载无格式字节流以及缓冲区大小受限等特点.消息队列是UNIX下不同进程之间可实现共享资源的一种机制,UNIX允许不同进程将格式化的数据流以消息队列形式发送给任意进程.对消息队列具有操作权限的进程都可以使用msget完成对消息队列的操作控制.通过使用消息类型,进程可以按任何顺序读信息,或为消息安排优先级顺序。
5)共享内存
共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问.共享内存是最快的IPC(进程间通信)方式,它是针对其它进程间通信方式运行效率低而专门设计的.它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步与通信.
6)套接字:
可用于不同及其间的进程通信
优缺点:
如果用户传递的信息较少或是需要通过信号来触发某些行为信号机制不失为一种简捷有效的进程间通信方式。
若是进程间要求传递的信息量比较大或者进程间存在交换数据的要求,那就需要考虑别的通信方式了。
无名管道简单方便,但局限于单向通信的工作方式,并且只能在创建它的进程及其子孙进程之间实现管道的共享。
有名管道虽然可以提供给任意关系的进程使用,但是由于其长期存在于系统之中,使用不当容易出错,所以普通用户一般不建议使用。
消息缓冲可以不再局限于父子进程,而允许任意进程通过共享消息队列来实现进程间通信。并由系统调用函数来实现消息发送和接收之间的同步。从而使得用户在使用消息缓冲进行通信时不再需要考虑同步问题,使用方便,但是消息队列中信息的复制需要额外消耗CPU的时间。不适宜于信息量大或操作频繁的场合。
共享内存针对消息缓冲的缺点改而利用内存缓冲区直接交换信息,无须复制,快捷、信息量大是其优点,但是共享内存的通信方式是通过将共享的内存缓冲区直接附加到进程的虚拟地址空间中来实现的。因此,这些进程之间的读写操作的同步问题操作系统无法实现,必须由各进程利用其他同步工具解决。另外,由于内存实体存在于计算机系统中,所以只能由处于同一个计算机系统中的诸进程共享,不方便网络通信 。
不同的进程通信方式有不同的优点和缺点。因此,对于不同的应用问题,要根据问题本身的情况来选择进程间的通信方式。
4.线程有几种状态,其中处于线程暂停执行的有sleep()和wait(),两者有什么区别?
1)新建状态(New):新创建了一个线程对象。
2)就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于“可运行线程池”中,变得可运行,只等待获取CPU的使用权。即在就绪状态的进程除CPU之外,其它的运行所需资源都已全部获得。
3)运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。
4)阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。
阻塞的情况分三种:
(1)等待阻塞:运行的线程执行wait()方法,该线程会释放占用的所有资源,JVM会把该线程放入“等待池”中。进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒。
(2)同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入“锁池”中。
(3)其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
5)死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
5.多线程如何保证数据同步
java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查),将会导致数据不准确,相互之间产生冲突,因此加入同步锁以避免在该线程没有完成操作之前,被其他线程的调用,从而保证了该变量的唯一性和准确性。
同步方法
即有synchronized关键字修饰的方法。由于java的每个对象都有一个内置锁,当用此关键字修饰方法时,内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。
代码如:
public synchronized void save(){}
注: synchronized关键字也可以修饰静态方法,此时如果调用该静态方法,将会锁住整个类。
同步代码块
即有synchronized关键字修饰的语句块。被该关键字修饰的语句块会自动被加上内置锁,从而实现同步
代码如:
synchronized(object){
}
注:同步是一种高开销的操作,因此应该尽量减少同步的内容。通常没有必要同步整个方法,使用synchronized代码块同步关键代码即可。
使用重入锁实现线程同步
在JavaSE5.0中新增了一个java.util.concurrent包来支持同步。ReentrantLock类是可重入、互斥、实现了Lock接口的锁,它与使用synchronized方法和块具有相同的基本行为和语义,并且扩展了其能力。
ReentrantLock类的常用方法有:
ReentrantLock() : 创建一个ReentrantLock实例,lock() : 获得锁,unlock() : 释放锁。
注:ReentrantLock()还有一个可以创建公平锁的构造方法,但由于能大幅度降低程序运行效率,不推荐使用
使用特殊域变量(volatile)实现线程同步
a.volatile关键字为域变量的访问提供了一种免锁机制,
b.使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新,
c.因此每次使用该域就要重新计算,而不是使用寄存器中的值
d.volatile不会提供任何原子操作,它也不能用来修饰final类型的变量
使用局部变量实现线程同步
如果使用ThreadLocal管理变量,则每一个使用该变量的线程都获得该变量的副本。副本之间相互独立,这样每一个线程都可以随意修改自己的变量副本,而不会对其他线程产生影响。变量局部化。
java.lang
类 ThreadLocal
java.lang.Object
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注软件测试)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
dLocal
java.lang.Object
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注软件测试)
[外链图片转存中…(img-YfxFmRYo-1713623698184)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!