6.29:1、说一下jdk和jre的区别?
- JRE是java运行时环境,包含了java虚拟机,java基础类库。是使用java语言编写的程序运行所需要的软件环境,是提供给想运行java程序的用户使用的。
- JDK是java开发工具包,是程序员使用java语言编写java程序所需的开发工具包,是提供给程序员使用的。JDK包含了JRE,同时还包含了编译java源码的编译器javac,还包含了很多java程序调试和分析的工具:jconsole,jvisualvm等工具软件,还包含了java程序编写所需的文档和demo例子程序。
- 如果你需要运行java程序,只需安装JRE就可以了。如果你需要编写java程序,需要安装JDK。
6-29日每日一练解答的核心点:
1.介绍jdk(开发环境)和jre(运行环境)的概念
2.JDK包含JRE
3.JDK中包含开发工具包,编译器,调试和分析工具等
3.在项目部署时只需要jre即可,项目开发期间安装jdk
6.30:2、java的跨平台原理
- java的跨平台是通过java虚拟机来实现的
- Java是解释执行的,编译为中间码的编译器与平台无关,编译生成的中间码也与平台无关(一次编译,到处运行),中间码再由解释器解释执行,解释器是与平台相关的,也就是不同的平台需要不同的解释器.
- Java 解释器实际上就是特定的平台下的一个应用程序。只要实现了特定平台下的解释器程序,Java字节码就能通过解释器程序在该平台下运行,这是Java跨平台的根本。
- 同一个.class文件在不同的虚拟机 会得到不同的机器指令(Windows和Linux的机器指令不同),但是最终执行的结果却是相同的
7.1:3、java的基本数据类型,占用内存,byte,short的取值范围
这是8中基本类型的内存中占用字节数(取值范围是2的(字节数X8-1)次方)
1.整型
- 类型 存储需求 bit数 取值范围
- byte 1字节 1*8 -128~127
- short 2字节 2*8 -32768~32767
- int 4字节 4*8 (-2的31次方到2的31次方-1)
- long 8字节 8*8 (-2的63次方到2的63次方-1)
2.浮点型
- 类型 存储需求 bit数 备注
- float 4字节 4*8 float类型的数值有一个后缀F(例如:3.14F)
- double 8字节 8*8 没有后缀F的浮点数值(如3.14)默认为double类型
3.char类型
- 类型 存储需求 bit数
- char 2字节 2*8
4.boolean类型
- 类型 存储需求 bit数 取值范围
- boolean 1字节 1*8 false、true
7.2:4、a++和++a的区别
- a++:先运算后自增1;++a:先自增1后运算
- --同理
5、&和&&的区别
- Java中&&和&都是表示与的逻辑运算符,都表示逻辑运输符and,当两边的表达式都为true的时候,整个运算结果才为true,否则为false。
- &&的短路功能,当第一个表达式的值为false的时候,则不再计算第二个表达式;&则两个表达式都执行。
- &可以用作位运算符,当&两边的表达式不是Boolean类型的时候,&表示按位操作。
7.3:6、对比if和switch
- 从使用表面看
- if的分支只有两个,如果情况多种就得多个if-else
- swith可以同时支持任意多个分支
- 从适用范围
- if 语句适用范围比较广,只要是 boolean 表达式都可以用 if 判断;
- 而 switch 只能对byte、short、int、char、String进行数值比较
- 从设计上看
- (区间判断)if就是用来根据真假真正做分支用的,分支执行非此即彼,如果多个分支就得多重判断,无论前面的条件是否成立都得判断一遍,直至找到真正的true,就找到这个程序的分支流程而走开了
- (等值判断)swith则是一种通道开关设计,它的条件跟真假无关,无需逐一判断,它寻找的是一个通道入口,给定一个值立即就按它对应的入口执行后续流程而不是彻底走开,若要彻底走开还得特意break或者return一下
7、对比三种循环
循环说明 | for | while | do while |
结构 | for(循环次数【数组的length或集合的size】){ if(条件【true或false】){ 循环体; } } | while(条件【true或false】){ 循环体; } | do{ 循环体; }while(条件【true或false】); |
特点 | 先判断后执行 | 先判断后执行 | 先执行后判断,至少会执行一次 |
作用 | 循环次数确定 | 不确定循环次数 | 不确定循环次数 |
7.6:8、什么是类,什么是对象,类和对象的关系
对象:对象是人们要进行研究的任何事物,它不仅能表示具体的事物,还能表示抽象的规则、计划或事件
类:具有相同特性(数据元素)和行为(功能)的对象的抽象就是类
类与对象的关系就如模具和铸件的关系,类的实力化的结果就是对象,而对对象的抽象就是类,类描述了一组有相同特性(属性)和相同行为的对象。
9、什么是构造方法,什么是方法重载
什么是构造方法?
当新对象被创建的时候,构造方法就会被调用。每一个类都有构造方法,如果程序员没有给类提供构造方法,Java编译器会为这个类创建一个默认的构造方法。
7.7:10、简述一下封装
- 封装,即隐藏对象的属性和实现细节,仅对外公开接口,控制程序中属性的读(get)和修改(set)的访问级别;将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成“类”,其中数据和函数都是类的成员。
11、简述static关键字的含义及用途,特点等
含义
- static表示“静态”的意思,可以用来修饰成员变量和成员方法(后续还会学习 静态代码块 和 静态内部类)。
用途
- static的主要作用在于创建独立于具体对象的域变量或者方法
特点:
- 被static关键字修饰的方法或者变量不需要依赖于对象来进行访问,只要类被加载了,就可以通过类名去进行访问。
- 静态成员 在类加载时加载并初始化。
- 无论一个类存在多少个对象 , 静态的属性, 永远在内存中只有一份( 可以理解为所有对象公用 )
- 在访问时: 静态不能访问非静态 , 非静态可以访问静态 !
- 静态修饰的方法被调用时有可能对象还未创建!
7-7日每日一练解答的核心点:
1.封装:将属性私有化,提供公有方法访问私有属性,提高了代码的安全性
2.static关键字,修改的属性或方法被提升到类级别的属性或方法,特点:可以直接通过类名.属性或类名.方法名调取
7.8:12、解释说明Java三大特性
封装、继承、多态
封装:就是把描述一个对象的属性和行为的代码封装在一个类中,有些属性是不希望公开的,或者说被其他对象访问的,所以我们使用private使其隐藏起来;类中提供了方法get、set等方法,可以操作这些被隐藏的属性,其他类可以通过调用这些方法,改变隐藏属性的值!
继承:在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,使用extends关键字实现继承;子类中可以加入若干新的内容,或修改原来的方法使之更适合特殊的需要,这就是继承。继承是子类自动共享父类数据和方法的机制,这是类之间的一种关系,提高了软件的可重用性和可扩展性。
多态:多态就是在声明时使用父类,在实现或调用时使用具体的子类,即父类引用指向子类对象;不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性,多态增强了软件的灵活性和扩展性。
13、抽象类和接口的区别
- 抽象类使用(extend)来被子类继承, 无法多继承。 接口使用(implements )来被子类实现, 可以多实现
- 抽象类中可以声明抽象方法,也可以写非抽象方法,接口只能声明抽象方法。
- 抽象类中的变量是普通变量,接口里定义的变量只能是公共的静态的常量。
- 抽象类中可以包含static方法 ,但是接口中不允许(静态方法不能被子类重写,因此接口中不能声明静态方法)
- 抽象类可以有构造方法,但是接口不能有
7.9:14、方法重写和方法重载的区别
区别点 | 方法重写 | 方法重载 |
范围 | 子类对父类 | 类本身 |
参数列表 | 一定不能修改 | 参数类型、个数或者顺序不同 |
返回类型 | 一定不能修改 | 可以修改 |
异常 | 可以减少或删除,一定不能跑出新的或者更广的异常 | 可以修改 |
访问 | 一定不能坐出更严格的限制(可以降低限制) | 可以修改 |
15、多态的表现形式有哪些
重载、重写、抽象类和接口。
7.10:16、介绍一下java中的异常处理机制
异常处理机制为:抛出异常,捕捉异常。
Java异常机制主要依赖于try、catch、finally、throw、throws五个关键字。
1.try:它里面放置可能引发异常的代码
2.catch:后面对应异常类型和一个代码块,用于表明该catch块用于处理这种类型的代码块,可以有多个catch块。如果异常发生在try语句,则会自动找到匹配的catch语句执行,如果没有在try语句中,则会将异 常抛出.
3.finally:在进行异常的处理之后,在异常的处理格式中还有一个finally语句,那么此语句将作为异常的统一出口,不管是否产生 了异常,最终都要执行此段代码。
4.throw:用于抛出一个实际的异常,可以单独作为语句使用,抛出一个具体的异常对象。
5.throws:用在方法签名中,用于声明该方法可能抛出的异常。
7月10日每日一练解答核心点:
1.什么是异常
2.异常的关键字
3.每个关键字的的含义以及作用
4.异常的分类
7.15:17、描述Java中的三大集合(接口,实现类,存值特点,存值原理等角度描述)
- Set集合。其主要实现类有HashSet、TreeSet。
- 存放对象的引用,不允许有重复对象。
- 1.HashSet(),调用对象的hashCode()方法,获得哈希码,然后再集合中计算存放对象的位置。通过比较哈希码与equals()方法来判别是否重复。所以,重载了equals()方法同时也要重载hashCode()方法。
- 2.TreeSet(),继承ShortedSet接口,能够对集合中对象排序。默认排序方式是自然排序,但该方式只能对实现了Comparable接口的对象排序,java中对Integer、Byte、Double、Character、String等数值型和字符型对象都实现了该接口。
- 如果有特殊排序,须重载该接口下的compareTo()方法或通过Comparator接口的实现类构造集合。
- List集合,其主要实现类有LinkedList、ArrayList,前者实现了链表结构,后者可代表大小可变的数组。
- List的特点是能够以线性方式储蓄对象,并允许存放重复对象。
- List能够利用Collections类的静态方法sort排序。
- sort(List list)自然排序;sort(List listm,Comparator codddmparator)客户化排序。
- List:线性集合接口,有序;ArrayList:动态数组[可变长度的动态数组];LinkedList:链表结构的集合
- Map集合,其主要实现类有
- HashMap、TreeMap。
- Map对值没有唯一性要求,对健要求唯一,如果加入已有的健,原有的值对象将被覆盖。
- HashMap类按照哈希算法来存取键对象,可以重载equals()、hashCode()方法来比较键,但是两者必须一致。
- TreeMap,可自然排序,也可通过传递Comparator的实现类构造TreeMap。
- Map:键值对存储结构的集合,无序
7月15日每日一练解答核心点:
1.集合类型:List,Set,Map
2.等级关系(Collection包含list,set,map独立)
3介绍三个集合的常用实现类,比如Arraylist,LinkedList
HashSet,HashMap等
4.存值特点:list-有序可重复,set-无序不可重复 ,map-key/value形式
5.数据结构:arrayList 顺序存储,Linkedlist 链表存储
6.底层实现:基于数组
7.面试常考:HashMap的实现原理
7.16:18、讲一下hashMap的实现原理
https://www.cnblogs.com/yuanblog/p/4441017.html
HashMap是基于哈希表的Map接口的非同步实现。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。
在java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用这两个基本结构来构造的,HashMap也不例外。HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。
总结:HashMap的实现原理:
- 利用key的hashCode重新hash计算出当前对象的元素在数组中的下标
- 存储时,如果出现hash值相同的key,此时有两种情况。(1)如果key相同,则覆盖原始值;(2)如果key不同(出现冲突),则将当前的key-value(键值对)放入链表中
- 获取时,直接找到hash值对应的下标,在进一步判断key是否相同,从而找到对应值。
- 理解了以上过程就不难明白HashMap是如何解决hash冲突的问题,核心就是使用了数组的存储方式,然后将冲突的key的对象放入链表中,一旦发现冲突就在链表中做进一步的对比。
初始容量为16,负载因子为0.75
7.17:19、Comparable和Comparator区别比较
- Comparable 是排序接口,仅仅只包括一个Comparable<T>函数x.compareTo(y) 来“比较x和y的大小”。若返回“负数”,意味着“x比y小”;返回“零”,意味着“x等于y”;返回“正数”,意味着“x大于y”。
- Comparator 是比较器接口。仅仅只包括两个个函数int compare(T o1, T o2); boolean equals(Object obj);
- Comparable是排序接口;若一个类实现了Comparable接口,就意味着“该类支持排序”。
而Comparator是比较器;我们若需要控制某个类的次序,可以建立一个“该类的比较器”来进行排序。
我们不难发现:Comparable相当于“内部比较器”,而Comparator相当于“外部比较器”。
20、HashMap和TreeMap的区别
- HashMap:基于哈希表实现,TreeMap:基于红黑树实现
- HashMap:适用于在Map中插入、删除和定位元素。
Treemap:适用于按自然顺序或自定义顺序遍历键(key)。
- HashMap不保证元素迭代顺序是按照插入时的顺序,Treemap会按照排序后的顺序迭代元素
7.20:21、说一下你了解的IO流体系
7.21:22、介绍一下序列化技术
序列化就是将对象状态转换为可保持或传输的格式的过程。与序列化相对的就是反序列化,他将流转换成对象。这两个过程结合起来,可以轻松地存储和传输数据。
要序列化的类,要实现Serializable接口,而这个接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个 ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。
7-21每日一练解答:
1.序列化反序列化的概念
2.实现方式和常用方法
3.不能序列化的情况:transient关键字修饰
7.22:23、介绍一下线程的生命周期
- Java线程具有五中基本状态
- 新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();
- 就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;
- 运行状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就 绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;
- 阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次被CPU调用以进入到运行状态。根据阻塞产生的原因不同,阻塞状态又可以分为三种:
- 1.等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;
- 2.同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;
- 3.其他阻塞 -- 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
- 死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
7.23:24、解释一下TCP协议的三次握手和四次挥手
理解及面试题链接:https://note.youdao.com/ynoteshare1/index.html?id=4b10010f9de5975d8689404a76286711&type=note
第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
●第一次挥手:客户端向服务器发送一个FIN报文段,将设置seq为100和ack为120, ;此时,客户端进入FIN_ WAIT_ 1状态,这表示客户端没有数据要发送服务器了,请求关闭连接;
●第二次挥手:服务器收到了客户端发送的FIN报文段,向客户端回一-个ACK报文段,ack设置为101, seq设置为120;服务器进入了CLOSE _WAIT状态,客户端收到服务器返回的ACK报文后,进入FIN_ WAIT_ 2状态;
●第三次挥手:服务器会观察自己是否还有数据没有发送给客户端,如果有,先把数据发送给客户端,再发送FIN报文;如果没有,那么服务器直接发送FIN报文给客户端。请求关闭连接,同时服务器进入LAST_ ACK状态;
●第四次挥手:客户端收到服务器发送的FIN报文段,向服务器发送ACK报文段,将seq设置101,
将ack设置为121,然后客户端进入TIME_ WAIT状态;服务器收到客户端的ACK报文段以后,就关闭连接;此时,客户端等待2MSL后依然没有收到回复,则证明Server端已正常关闭,客户端也可以关闭连接了。
7.24:25、说一下TCP和UDP的区别
TCP与UDP区别总结:
1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接
2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即UDP不保证可靠交付 3、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;
UDP是面向报文的UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等) 4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信 5、TCP首部开销20字节;UDP的首部开销小,只有8个字节
6、TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道
7.27:26、列举css选择器有哪些
https://www.cnblogs.com/isremya/p/12364741.html
1、元素选择器 标签名{ }
2、id选择器 #id属性值{ }
3、类选择器 ·class属性值{ }
4、选择器分组(并集选择器)语法:选择器1,选择器2,选择器n{ }
5、复合选择器(交集选择器)语法:选择器1 选择器2 选择器n{ }
6、通配选择器 语法:*{ }
7、后代元素选择器 语法:祖先元素 后代元素{ }
8、子元素选择器 语法:父元素>子元素
9、伪类选择器
- 伪类表示元素的一种特殊状态
- :hover 移入时元素的状态
- :visited 已被访问过后的元素的状态
- :active 被点击时元素的状态
10、 属性选择器 语法:
- [属性名]选取含有指定属性的元素
- [属性名=“属性值”]选取含指定属性值的元素
- [属性名^="属性值"] 选取属性值以指定内容开头的元素
- [属性名$="属性值"] 选取属性值以指定内容结尾的元素
- [属性名*="属性值"] 选取属性值包含指定内容的元素
11、兄弟元素选择器 语法:前一个+后一个(作用在后一个)
7.28:27、介绍一下反射(概念,工具类,使用场景等方向)
https://www.jianshu.com/p/9be58ee20dee
概念:
JAVA反射机制是在运行状态中,获取任意一个类的结构 , 创建对象 , 得到方法,执行方法 , 属性 !; 这种在运行状态动态获取信息以及动态调用对象方法的功能被称为java语言的反射机制。
工具类:Class,Constructor,Method,Field
getClass() 得到一个类的 类对象
forName(包名+类名): 得到一个类的 类对象
getConstructor(参数类型的class对象数组)获取指定的单个构造方法
newInstance(Object... para)把对应的对象创建出来
setAccessible(boolean flag)忽略访问权限检查
getMethod(String methodName , class.. clss)得一个方法
getField(String filedName)属性的名称, 获取一个属性对象
getAnnotation(注解类型.class)根据类型获取类/属性/方法的注解对象
每日一练回答要点:
1.反射概念:动态获取类中的信息,以及动态调用对象的方法的功能称为java的反射机制
2.反射的工具类:Class,Constructor,Method,Field
3.常用方法:如何获得Class,contructor如何创建对象,如何动态获取、调用方法。设置属性等
4.反射的使用场景:servlet,框架中应用较多,也可以自己基于反射来实现一些动态功能
7.30:28、解释一下线程通信模式
https://blog.csdn.net/zgz15515397650/article/details/78920305
说到线程之间通信方式:依据我的理解 主要是有两种吧
1.是通过共享变量,线程之间通过该变量进行协作通信;
2.通过队列(本质上也是线程间共享同一块内存)来实现消费者和生产者的模式来进行通信;
1.通过线程之间共享变量的方式
这个就有必要说下 wait(),notify(),以及notifyAll() 这三个方法
这三个方法都是属于Object的方法;所以所有类都可以继承这三方法;
wait()方法使得当前线程必须要等待,等到另外一个线程调用notify()或者notifyAll()方法。
notify()方法会唤醒一个等待当前对象的锁的线程。而notifyAll()顾名思义;就是唤醒所有在等待中的方法;
wait()和notify()方法要求在调用时线程已经获得了对象的锁,因此对这两个方法的调用需要放在synchronized方法或synchronized块中。
每日一练回答要点:
1.线程通信的概念(为了实现线程之间的信息交互)
2.通信的方式:wait(),notify(),notifyAll()三个方法实现
注意:这三个方法是Object的方法,而并非是Thread的
3.线程通信的经典模式:生产者消费者模式,大家下去以后一定要看一下,并能够表述生产者消费者模式
4.注意一点:这三个方法一定要在同步方法中实现
7.31:29、什么是值传递和引用传递
- 值传递传递是对基本数据类型而言的,传递的是该变量的一个副本,改变副本不影响原变量.
- 引用传递一般是对于对象型变量而言的,传递的是该对象地址的一个副本,并不是原对象的副本。 所以对引用对象进行操作会同时改变原对象. 一般认为,java内的传递都是值传递.
每日一练回答要点:
考的点是基本数据类型和引用数据类型的作为参数时,值传递问题。
如果参数是基本类型,传递的是基本类型的字面量值的拷贝。
如果参数是引用类型,传递的是该参量所引用的对象在堆中地址值的拷贝。
8.3:30、synchronized 和 Lock 有什么区别?
- 实现层面不一样。synchronized 是 Java 关键字,JVM层面 实现加锁和释放锁;Lock 是一个接口,在代码层面实现加锁和释放锁
- 是否自动释放锁。synchronized 在线程代码执行完或出现异常时自动释放锁;Lock 不会自动释放锁,需要再 finally {} 代码块显式地中释放锁
- 是否一直等待。synchronized 会导致线程拿不到锁一直等待;Lock 可以设置尝试获取锁或者获取锁失败一定时间超时
- 获取锁成功是否可知。synchronized 无法得知是否获取锁成功;Lock 可以通过 tryLock 获得加锁是否成功
- 功能复杂性。synchronized 加锁可重入、不可中断、非公平;Lock 可重入、可判断、可公平和不公平、细分读写锁提高效率
每日一练回答要点:
1.相同点:都是java中获取线程锁的方式
2.不同点:
2.1 定义不同,synchronized是关键字,lock是对象
2.2 获得锁的方式不同
2.3 控制的元素不同,synchronized控制代码块或方法,lock锁代码
2.4 加锁和解锁方式不同
2.5 获取锁失败时,处理方式不同
8.4:31、JVM如何加载字节码文件?
http://note.youdao.com/noteshare?id=b5744b3767585d08173facccf57248d4
每日一练答题核心点(8月4日)
1.类加载机制:虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可被虚拟机直接使用的Java类型
2.加载过程:
2.1 加载:通过类名进行加载,
2.2 链接(验证,准备,解析):文件格式验证,元数据验证,字节码验证,符号引用验证。为变量分配内存或初始值等
2.3 初始化:初始化用于执行Java类的构造方法
8.5:32、怎么防止死锁?
https://www.cnblogs.com/bopo/p/9228834.html
我们可以通过破坏死锁产生的4个必要条件来 预防死锁,由于资源互斥是资源使用的固有特性是无法改变的。
1.破坏“不可剥夺”条件:一个进程不能获得所需要的全部资源时便处于等待状态,等待期间他占有的资源将被隐式的释放重新加入到 系统的资源列表中,可以被其他的进程使用,而等待的进程只有重新获得自己原有的资源以及新申请的资源才可以重新启动,执行。
2.破坏”请求与保持条件“:第一种方法静态分配即每个进程在开始执行时就申请他所需要的全部资源。第二种是动态分配即每个进程在申请所需要的资源时他本身不占用系统资源。
3.破坏“循环等待”条件:采用资源有序分配。其基本思想是将系统中的所有资源顺序编号,将紧缺的,稀少的采用较大的编号,在申请资源时必须按照编号的顺序进行,一个进程只有获得较小编号的进程才能申请较大编号的进程。
每日一练答题核心点(8月5日):
1.说明死锁的条件:
1.1 互斥:所分配的资源不允许其他进程访问,其他线程等待
1.2 请求和保持条件:对其他请求阻塞,自身资源不释放
1.3 不可剥夺条件:未完成使用之前,不可以被剥夺
1.4 环路等待条件:发生死锁后,若干进程之间形成一种头尾相接的循环等待资源
2 .解决方案:针对死锁形成的原因,防止上诉四个条件的的发生,可以在系统设计,进程调度等方面注意如何防止四个条件成立,如何确定资源的合理分配算法,避免进程永久占据系统资源
8.6:33、Collection和Collections的区别
https://blog.csdn.net/sfhinsc/article/details/84060783
1、java.util.Collection 是一个集合框架的父接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。它的意义是为各种具体的集合提供了最大化的统一操作方式。
2、java.util.Collections 是一个包装类。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架。他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。
34、final, finally, finalize的区别
https://www.cnblogs.com/smart-hwt/p/8257330.html
https://www.cnblogs.com/ktao/p/8586966.html
1)final 是 java中的关键字,修饰符。用于声明变量、方法和类,分别表示变量只能赋值一次不可变、方法不可覆盖、类不可被继承(不能再派生出新的子类)
2)finally作为异常处理的一部分,它只能用在try/catch语句中,并且附带着一个语句块,表示这段语句最终一定被执行,经常被用在需要释放资源的情况下。
3)finalize是Object类中的一个方法,在垃圾收集器执行的时候会调用被回收对象的finalize()方法,可以覆盖此方法来实现对其他资源的回收,例如关闭文件等。需要注意的是,一旦垃圾回收器准备好释放对象占用的空间,将首先调用其finalize()方法,并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存。
每日一练核心点(8月6日):
1.collections是集合的工具类,collection是list,set的父接口,两者没有直接关系,只是长得像。
2.final 关键字,修饰的变量是常量,修饰的方法不能被重写,修饰的类不能被继承。
finally 异常处理的关键字,修饰的代码块表示无论是否有异常都要执行
finalize是gc机制中的一个方法,用来对对象回收的最后确认
8.7:35、斐波那契数列 递归实现斐波那契
思维题::
有一对兔子,从出生后第3个月起每个月都生- -对兔子,小兔子长到第三个月后每个又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?
要求:用代码的方式解决上述问题
我的答案:java递归实现,没找到规律,效率极低
public class Demo {
public static void main(String[] args) {
int x = 5;//x个月>3
int sum = 1;// 起始一对兔子
//出生第三个月起每个月生一对兔子,即每满两个月生一对兔子
// 第一对兔子 第3月开始生 共生了 x-2对 即(x-2)*2 只
// 第二对兔子 第5月开始生 共生了 x-2-2对
// 第三对兔子 第6月开始生 共生了 x-2-2-1对
sum = life(x,sum);
System.out.println("第"+x+"月一共有"+sum+"对兔子");
}
/**
*
* @param x 该兔子出生后的第几月
* @param sum 该兔子出生后的兔子总对数
* @return 每个月该兔子本身及后代总对数
*/
static public int life(int x,int sum){
if(x>=3 && sum >0){//第三个月开始生
for(int i=1;i<=x-2;i++){
sum++;
System.out.println("第"+sum+"对兔子");
sum = life(x-2-i+1,sum);//小兔子开始生育
}
}
return sum;
}
标答:递归实现斐波那契
public class demo {
public static void main(String args[]) {
System.out.println(rabbit(Integer.parseInt(new Scanner(System.in).next())));
}
private static int rabbit(int n) {
if (n == 1 || n == 2) {
return 1;
} else {
return rabbit(n - 1) + rabbit(n - 2);
}
}
}
其余答案:数组实现
8.10:36、jq和js的区别和联系
https://www.cnblogs.com/wangtaobiu/p/10241344.html
JavaScript 是通过标签插入到HTML页面,可由所有的现代浏览器执行的一种轻量级的编程语言。
而jQuery是一个基于js编写的框架,实质上还是js,封装了我们开发过程中常用的文档遍历和操作,事件处理,动画和Ajax,方便我们调用,提高开发效率。
1.jQuery 是一个 JavaScript 库;
2.jQuery 极大地简化了 JavaScript 编程;
3.jQuery 使JavaScript更好用;
4.jquery就是要用更少的代码,漂亮的完成更多的功能
37、介绍一种你学过的前端框架,并进行描述
Bootstrap 是一个用于快速开发 Web 应用程序和网站的前端框架。Bootstrap 是基于 HTML、CSS、JAVASCRIPT 的。
https://www.runoob.com/bootstrap/bootstrap-intro.html
https://www.cnblogs.com/zhaopanpan/articles/8939635.html特点;
移动设备优先:自 Bootstrap 3 起,框架包含了贯穿于整个库的移动设备优先的样式。
浏览器支持:所有的主流浏览器都支持 Bootstrap。
容易上手:只要您具备 HTML 和 CSS 的基础知识,您就可以开始学习 Bootstrap。
响应式设计:Bootstrap 的响应式 CSS 能够自适应于台式机、平板电脑和手机。更多有关响应式设计的内容详见 Bootstrap 响应式设计。它为开发人员创建接口提供了一个简洁统一的解决方案。
它包含了功能强大的内置组件,易于定制。
它还提供了基于 Web 的定制。
它是开源的。
Bootstrap 包的内容:
基本结构:Bootstrap 提供了一个带有网格系统、链接样式、背景的基本结构。这将在 Bootstrap 基本结构 部分详细讲解。
CSS:Bootstrap 自带以下特性:全局的 CSS 设置、定义基本的 HTML 元素样式、可扩展的class,以及一个先进的网格系统。这将在 Bootstrap CSS 部分详细讲解。
组件:Bootstrap 包含了十几个可重用的组件,用于创建图像、下拉菜单、导航、警告框、弹出框等等。这将在 布局组件部分详细讲解。
JavaScript 插件:Bootstrap 包含了十几个自定义的 jQuery 插件。您可以直接包含所有的插件,也可以逐个包含这些插件。这将在 Bootstrap 插件 部分详细讲解。
定制:您可以定制 Bootstrap 的组件、LESS 变量和 jQuery 插件来得到您自己的版本。
8.11:38、SQL语法规则
1.增加:insert into 表名(列名) values (列值)
- 修改: update 表名 set 列名=列值,列名2=列值2 where 限定条件
- 删除: delete from 表名 where 限定条件
2.两表内联:
- (1)select 列名 from 表1 inner join 表2 on 表1.列名=表2.列名
- (2)select 列名 from 表1,表2 where 表1.列名=表2.列名
3.查询:
select 列名 from 表名 where 限定条件 group by 分组列名 having 分组后的限定条件 order by 排序的列名 asc/desc limit 开始位置,显示条数
8.12:39、JDBC连接数据库的步骤
状态通道:
1.导入jar包
2.加载驱动:Class.forname("com.mysql.jdbc.Driver");
3.通过驱动管理获得连接:Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/数据库名?useUnicode=true&characterEncoding=utf-8","数据库账号","数据库密码");
4.通过连接创建Sql对象
Statement state = conn.creatStatement();
5.执行SQL语句
state.execute("sql语句");
6.关闭连接
state.close();
conn.close();预状态通道
1.导入jar包
2.加载驱动:Class.forname("com.mysql.jdbc.Driver");
3.通过驱动管理获取连接:Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/数据库名称?useUnicode=true&characterEcoding=utf-8","数据库账号","数据库密码");
4.通过连接创建SQL对象并预编译sql语句:PraperStatement state=conn.creatPraperStatement("sql语句");
5.执行SQL:int i = state.excuteUpdate();|| ResultSet rs = state.excuteQuery();
6.关闭连接
rs.close();state.close();conn.close();
8.13:40、有1、2、3、4个数字,能组成多少个互不相同且无重复的三位数,分别是多少?
public class Demo {
public static void main(String[] args) {
int sum = 0;//三位数个数
int count = 0;//计数器
for (int i = 1; i <=4 ; i++) {
for (int j = 1; j <=4; j++) {
if(j != i){
for (int k = 1; k <= 4; k++) {
if(k != i && k != j){
System.out.println(i*100+j*10+k);
sum++;
}
count++;
}
}else{
count++;
}
}
}
System.out.println("总共"+sum+"个三位数");
System.out.println("运行"+count+"圈");
}
}
8.14:41、有两根不均匀分布的香,每根香烧完的时间是一个小时,你能用什么方法来确定一段15分钟的时间?
答:把两根香同时点起来,第一支香两头点着,另一支香只烧一头,等第一支香烧完花了半个小时,第二支香还剩半个小时,把第二支香另一头点燃,另一头从燃起到熄灭的时间就是15分!
8.17:42、一架飞机绕地球半圈需要一桶油,一架只能装一桶油,飞机之间可以互相加油,现在要保证一架飞机能绕地球一圈,至少需要多少驾飞机?要求其它飞机不能降落,要保证能返航,速度可以不考虑,在加油的过程可以瞬间加满油,可以返航加油
答案:3架。
8.18:43、说一下servlet生命周期
https://www.runoob.com/servlet/servlet-life-cycle.html
Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程:
- Servlet 通过调用init () 方法进行初始化。
- Servlet 调用service() 方法来处理客户端的请求。
- Servlet 通过调用destroy() 方法终止(结束)。
- 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。
8.19:44、猴子吃桃问题
8.20:45、介绍一下JSP的九大内置对象以及常用方法
JSP中一共预先定义了9个这样的对象,分别为:request、response、session、application、out、
pagecontext、config、page、exception
8.21:46、驴吃萝卜问题
想要商人卖得最多du,就等于是让驴吃最少,而要驴吃最少,就等于驴走了最短的路程。
不管驴驮多驮少,每走1公里都是吃1根胡萝卜,所以,尽量让驴背上的胡萝卜保持最多,最后剩下的胡萝卜也就最多;而让驴驮最多就需要每段出发时驴背上都满载(1000根),这就要求每个分段的胡萝卜数量都必须是1000的整倍数——胡萝卜3000根,一次背1000根,3000除以1000等于3,因此需要把路分成3段,中间有两个停靠点。
总路程是1000公里,总共3000根,让驴每次都驮最大值,那就是1000根。需要先将3000根放在1000公里的某个临时点,假定这个临时点位A,驴到A的位置,每次驮1000根,来回要五次。5*距离=1000根。得出A的位置是200公里处。此时还剩2000根。同理,将2000根移动到A和终点之间的一个位置,假定这个位置是B。A到B的位置来回走三次即可移动。3*距离=1000根。距离≈333。到B位置时剩余1000根,行走了200+333=533公里,剩余距离一趟走完,1000-533=467公里,走完467公里后,剩余533根胡萝卜
9月2日:47、volatile干什么的?原理是什么?
推荐:https://note.youdao.com/ynoteshare1/index.html?id=4f2e05fe5d6b2598c5d0c672872f0c2b&type=note
volatile作用:
volatile 是一个类型修饰符。volatile 的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略
volatile原理:
Java语言提供了一种稍弱的同步机制,即volatile变量,用来确保将变量的更新操作通知到其他线程。当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会将该变量上的操作与其他内存操作一起重排序。volatile变量不会被缓存在寄存器或者对其他处理器不可见的地方,因此在读取volatile类型的变量时总会返回最新写入的值。
在访问volatile变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量是一种比sychronized关键字更轻量级的同步机制。
当对非 volatile 变量进行读写的时候,每个线程先从内存拷贝变量到CPU缓存中。如果计算机有多个CPU,每个线程可能在不同的CPU上被处理,这意味着每个线程可以拷贝到不同的 CPU cache 中。
而声明变量是 volatile 的,JVM 保证了每次读变量都从内存中读,跳过 CPU cache 这一步。
volatile 性能:
volatile 的读性能消耗与普通变量几乎相同,但是写操作稍慢,因为它需要在本地代码中插入许多内存屏障指令来保证处理器不发生乱序执行。
当一个变量定义为 volatile 之后,将具备两种特性:
1.保证此变量对所有的线程的可见性,这里的“可见性”,如本文开头所述,当一个线程修改了这个变量的值,volatile 保证了新值能立即同步到主内存,以及每次使用前立即从主内存刷新。但普通变量做不到这点,普通变量的值在线程间传递均需要通过主内存(详见:Java内存模型)来完成。2.禁止指令重排序优化。有volatile修饰的变量,赋值后多执行了一个“load addl $0x0, (%esp)”操作,这个操作相当于一个内存屏障(指令重排序时不能把后面的指令重排序到内存屏障之前的位置),只有一个CPU访问内存时,并不需要内存屏障;(什么是指令重排序:是指CPU采用了允许将多条指令不按程序规定的顺序分开发送给各相应电路单元处理)。
9月3日:48、SQL语句优化有哪些方法?
9月4日:49、http和https的区别?
参考网址:https://blog.csdn.net/qq_38289815/article/details/80969419
1、HTTPS 协议需要到 CA (Certificate Authority,证书颁发机构)申请证书,一般免费证书较少,因而需要一定费用。(以前网易官网是http,而网易邮箱是 https。)
2、HTTP 是超文本传输协议,信息是明文传输,HTTPS 则是具有安全性的 SSL 加密传输协议。
3、HTTP 和 HTTPS 使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
4、HTTP 的连接很简单,是无状态的。HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 HTTP 协议安全。(无状态的意思是其数据包的发送、传输和接收都是相互独立的。无连接的意思是指通信双方都不长久的维持对方的任何信息。)
9月7日:50、sql语句中count(*),count(1),count(id)区别详解
9.14-9.19周测题:
1.JVM内存分哪几个区,每个区的作用是什么
java 虚拟机主要分为以下五个区:
方法区:
- 有时候也称为永久代,在该区内很少发生垃圾回收,但是并不代表不发生 GC,在这里进行的 GC 主要是对方法区里的常量池和对类型的卸载
- 方法区主要用来存储已被虚拟机加载的类的信息、常量、静态变量和即时编译器编译后的代码等数据。
- 该区域是被线程共享的。
- 方法区里有一个运行时常量池,用于存放静态编译产生的字面量和符号引用。该常量池具有动态性,也就是说常量并不一定是编译时确定,运行时生成的常量也会存在这个常量池中。
虚拟机栈:
- 虚拟机栈也就是我们平常所称的栈内存,它为 java 方法服务,每个方法在执行的时候都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接和方法出口等信息。
- 虚拟机栈是线程私有的,它的生命周期与线程相同。
- 局部变量表里存储的是基本数据类型、returnAddress 类型(指向一条字节码指令的地址)和对象引用,这个对象引用有可能是指向对象起始地址的一个指针,也有可能是代表对象的句柄或者与对象相关联的位置。局部变量所需的内存空间在编译器间确定
- 操作数栈的作用主要用来存储运算结果以及运算的操作数,它不同于局部变量表通过索引来访问,而是压栈和出栈的方式
- 每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程中的动态连接.动态链接就是将常量池中的符号引用在运行期转化为直接引用。
本地方法栈
- 本地方法栈和虚拟机栈类似,只不过本地方法栈为 Native 方法服务。
堆
- java 堆是所有线程所共享的一块内存,在虚拟机启动时创建,几乎所有的对象实例都在这里创建,因此该区域经常发生垃圾回收操作。
程序计数器
- 内存空间小,字节码解释器工作时通过改变这个计数值可以选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理和线程恢复等功能都需要依赖这个计数器完成。该内存区域是唯一一个 java 虚拟机规范没有规定任何 OOM 情况的区域。
2.创建线程有哪几种方式?分别有什么不同?
参考网址:https://www.cnblogs.com/felixzh/p/6036074.html
Java多线程实现方式主要有四种:
- 继承Thread类实现
- 实现Runnable接口
- 实现Callable接口通过FutureTask包装器来创建Thread线程
- 使用ExecutorService、Callable、Future实现有返回结果的多线程。
注:一般推荐采用实现接口的方式来创建多线程
区别:
- 继承Thread类不能再继承其它的父类,由java单继承特性决定,而实现Runnable接口和实现Callable接口避免多继承局限
- 继承Thread类和实现Runnable接口无返回值,而实现Callable接口和使用ExecutorService、Callable、Future实现的多线程有返回值
- 通过Executor 的工具类可以创建三种类型的普通线程池
- 实现Runnable()可以更好的体现共享的概念
3.说一下设计模式的六大原则,分别代表什么?
参考网址:https://www.cnblogs.com/toutou/p/4870926.html#_label6
- 开闭原则(Open Closed Principle,OCP)
- 一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。模块应尽量在不修改原(是“原”,指原来的代码)代码的情况下进行扩展。
- 里氏代换原则(Liskov Substitution Principle,LSP)
- 派生类(子类)对象能够替换其基类(父类)对象被调用
- 依赖倒转原则(Dependency Inversion Principle,DIP)
- 是程序要依赖于抽象接口,不要依赖于具体实现。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。
- 接口隔离原则(Interface Segregation Principle,ISP)
- 客户端不应该依赖它不需要的接口,类间的依赖关系应该建立在最小的接口上
- 合成/聚合复用原则(Composite/Aggregate Reuse Principle,CARP)
- 经常又叫做合成复用原则。就是在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分;新的对象通过向这些对象的委派达到复用已有功能的目的。它的设计原则是:要尽量使用合成/聚合,尽量不要使用继承。
- 最小知识原则(Principle of Least Knowledge,PLK,也叫迪米特法则)
- 一个软件实体应当尽可能少的与其他实体发生相互作用。每一个软件单位对其他的单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位。迪米特法则的初衷在于降低类之间的耦合。由于每个类尽量减少对其他类的依赖,因此,很容易使得系统的功能模块功能独立,相互之间不存在(或很少有)依赖关系。迪米特法则不希望类之间建立直接的联系。如果真的有需要建立联系,也希望能通过它的友元类来转达。因此,应用迪米特法则有可能造成的一个后果就是:系统中存在大量的中介类,这些类之所以存在完全是为了传递类之间的相互调用关系—