赞
踩
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家:人工智能学习网站
国内的互联网面试,恐怕是现存的、最接近科举考试的制度。而且,我国的八股文(基础知识、集合框架、多线程、线程的五种状态、虚拟机、MySQL、Spring相关、计算机网络、MQ系列等)确实是独树一帜。以美国为例,北美工程师面试比较重视算法(Coding),近几年也会加入Design轮(系统设计和面向对象设计OOD)和BQ轮(Behavioral question,行为面试问题),今天博主为大家熬断半头青丝捋一捋这现代八股文
需要完整图的小伙伴可联系博主
详情见博主此文:IO流知识体系详解
按照流的方向:输入流(inputStream)和输出流(outputStream).
按照实现功能分:节点流(可以从或向一个特定的地方(节点)读写数据。如 FileReader)和处理流(是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。如 BufferedReader。处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接)
按照处理数据的单位: 字节流和字符流。字节流继承于 InputStream 和 OutputStream,字符流继承于InputStreamReader 和 OutputStreamWriter。
字节流如何转为字符流
字节输入流转字符输入流通过 InputStreamReader 实现,该类的构造函数可以传入 InputStream 对象。
字节输出流转字符输出流通过 OutputStreamWriter 实现,该类的构造函数可以传入 OutputStream 对象
如何将一个 java 对象序列化到文件里
在 java 中能够被序列化的类必须先实现 Serializable 接口,该接口没有任何抽象方法只是起到一个标记作用
详情见博主此文:Lambda表达式详细讲解
&
:逻辑与(and
),运算符两边的表达式均为true
时,整个结果才为true
&&
:短路与,如果第一个表达式为false
时,第二个表达式就不会计算了
在循环语句外前面定义一个标号,然后在里层循环体的代码中使用带有标号的break语句,即可跳出循环。
比如:
ok:
for (int j = 0; j < 10; j++) {
break ok;
}
1.封装
作用:提高代码的安全性
1、将属性私有化,并提供对外界的接口(get/set
方法)。
2、用private
修饰的属性和方法,只能在本类中使用。
2.继承
作用:提高代码的复用性,减少重复代码
1、子类可以继承父类非私有的属性和方法,不能继承构造方法和私有的属性和方法。
2、可以综合子类的共同特征来去提炼父亲的类。
3、子类在继承父类的各种属性和方法时,也可以有自己的属性和方法。
4、一个子类只能有一个父类,java只能单继承,不能多继承,因为多个类中的方法名相同,方法体不同,不知使用哪个。
5、一个类继承最顶端叫做基类或者超类,所有的超类叫做object
。
6、在继承关系中,如果父类没有无参数的构造方法,如何解决?
1.子类中添加一个和父类构造方法参数列表相同的构造方法,通过super参数传递给父类的构造方法
2.如果父类允许修改的时候,可以在父类中创建一个无参的构造方法
7、在继承关系中,代码块的执行顺序:父静>子静>父构造代码块>父构造方法>子构造代码块>子构造方法
3.多态
1.分类
编译时多态:在编译过程中察觉的多态,重载,向上转型。
运行时多态:在运行过程中察觉的多态,向下转型。
2.向上转型、向下转型是在继承关系中,向下转型必须在向上转型的基之上。
3.在继承关系中,父类的对象可以指向子类的实例,父类引用实体方法的时候,是调用子类重写以后的方法。
4.向上转型
父类的引用指向子类的实体
父类类名对象名=new 子类类();
优点:减少重复代码,提高代码的复用性
缺点:父类的引用无法调用子类特有的属性和方法
解决方案:向下转型
5.向下转型:
子类对象的父类引用赋给子类
子类类名对象名=(子类类名)父类对象;
6. instanceof 判断左边的对象是否属于右边的类 对象名instanceof
类名(子类类名)
7.匿名对象
new
类名()只有堆空间,没有栈空间,只能属于一次,为了节省代码。
==:表示两个变量的值是否相等,比较两个基本数据类型的数据或者引用变量,用 ==
equals:用于比较两个独立对象的内容是否相同,字符串的比较也用equals
Math.ceil():表示向上取整;Math.ceil(11.3)=12;Math.ceil(-11.3)=-12。
Math.floor():表示向下取整;Math.floor(11.6)=11;Math.floor(-11.6)=-12。
Math.round():表示四舍五入;Math.round(11.5)=12;Math.round(-11.5)=-11;
Math.round(11.3)=11;Math.round(-11.3)=-11;
算术运算符:+ 、 - 、 * 、 / 、 % 、 ++ 、 -- 赋值运算符:= 、 += 、 -= 、 *= 、 /= 、 %= 关系运算符:> 、 < 、 >= 、 <= 、 == 、 != 逻辑运算符:! 、 & (只要有一个false 最终结果就是false) 、 | (但凡有一个true 最终结果就是true) 、 ^ (如果两边一样 最终结果为false 如果两边不同 最终结果为true)、 &&(如果第一个是false 那第二个不执行 最终结果是false)、 ||(如果第一个表达式的结果是true 那第二个表达式 就不去计算了 ,最终结果是true) 位运算符: ~ 、 >> 、 << 、 >>> 字符串连接运算符:+ 三目运算符:X ? Y : Z X为boolean类型表达式,先计算x的值,若为true,整个三目运算的结果为表达式Y的值,否则整个运算结果为表达式Z的值。
重载(
Overload
):函数名相同,参数不同。可以改变返回值类型,参数的个数和类型。
重写(Override
):和父类的的方法名称、参数完全相同
String
:字符串数值不可变;
StringBuffer
:字符串可修改,可以动态构造字符数据。StringBuffer
类是可以通过Append()
来修改值。线程安全。
StringBuilder
:线程不安全。
三者在执行速度方面的比较:StringBuilder > StringBuffer > String
对于三者使用的总结:
1.如果要操作少量的数据用 =String
2.单线程操作字符串缓冲区下操作大量数据 =StringBuilder
3.多线程操作字符串缓冲区下操作大量数据 =StringBuffer
第一种:继承Thread类。New Thread(){}.start():表示调用子类对象的run方法
第二种:实现Runable接口
第三种:线程池创建多线程
第四种:实现Callable接口,重写call函数
继承Thread类实现多线程,重写run方法时没有返回值也不能抛出异常,使用Callable接口就可以解决这个问题
Callable接口和Runnable接口的不同之处:
1.Callable
规定的方法是call,而Runnable
是run
2.call
方法可以抛出异常,但是run
方法不行
3.Callable
对象执行后可以有返回值,运行Callable
任务可以得到一个Future
对象,通过Future
对象可以了解任务执行情况,可以取消任务的执行,而Runnable
不可有返回值
用synchronized
关键字修饰同步方法。
反对使用stop()
,是因为它不安全。
suspend()
方法容易发生死锁。调用suspend()
的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源,除非被" 挂起"的线程恢复运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会造成死锁。所以不应该使用suspend()
,而应在自己的Thread
类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,便用wait()
命其进入等待状态。若标志指出线程应当恢复,则用一个notify()
重新启动线程。
sleep
是线程被调用时,占着cpu
休眠,其他线程不能占用cpu
,os
认为该线程正在工作,不会让出系统资源,wait
是进入等待池等待,让出系统资源,其他线程可以占用cpu
sleep()
和wait()
方法的区别可从两个角度阐述:
1.cpu的抢占权;2.锁旗标是否释放
两者都会释放cpu的抢占权;
wait()
方法执行完即可释放锁旗标,进入线程的等待队列;
sleep()
执行完,不会释放,进入等待队列;
1.for循环语句
for ([循环变量初始值设定]; [循环条件判断]; [改变循环变量的值]){
循环体
}
注意:1、表达式2一般不可以省略,否则死循环
2、表达式3可以省略,但是在循环体中必须有语句修改变量,以使表达式2在某一时刻为false结束循环。
3、若同时省略表达式1,表表达式3,则相当于while(表达式2)语句
4、三个表达式均省略 即for(;;)语句,此时相当于while(true)语句
5、表达式1、表达式3可以是逗号表达式,以使循环变量值在修改时可以对其它变量赋值
2.if…else… 判断语句
1、if(){}
2、if(){}else{}
3、if(){}else if(){}
4、if(){if(){}else()}
5、if()执行语句 esle 执行语句 注意:执行语句只有一条语句的时候.可以将if esle 的大括号省略
注意:()内是boolean类型表达式,{}是语句块
比较字符串用equals,比较内容。比较数值用==,比较地址。
基本数据类型:变量名、变量值在栈中。
引用数据类型:变量名在栈中,变量值在常量池中。
3.while 循环语句
while( 条件表达式语句){ 循环体语句; } //初始条件 do{ //循环体; //迭代 }while( 循环条件判断); 注意:1、当第一次执行时,若表达式=false时,则while语句不执行,而do/while语句执行一次后面的语句 2、一定要切记在switch循环中,如果没有break跳出语句,每一个case都要执行一遍,在计算最终结果。
4.switch 语句
switch(表达式expr){ case const1: statement1; break; … … case constN: statementN; break; [default: statement_dafault; break;] } 注意:1、表达式必须是int、byte、char、short、enmu、String类型 2、constN必须是常量或者finall变量,不能是范围 3、所有的case语句的值不能相同,否则编译会报错 4、default可要可不要 5、break用来执行完一个分支后使程序跳出switch语句块,否则会一直会执行下去。
5.if和switch的区别是什么
1、
if
可以判断范围,也可以判断一个值
switch
只能判断指定的值
2、若只判断指定的值,则使用switch
语句,效率快
if判断范围,对数据判断灵活,自身的格式也比较灵活
6.break和continue区别是什么
break
跳出某个循环
continue
跳过某个循环
注意:if外有循环可以用break
、continue
,单纯if不可以用。
1、static调用格式: 1、同一个类中: 静态的: 方法名 属性名 类名.方法名 类名.属性名 对象名.方法名 对象名.属性名 非静态的: 对象名.属性名 对象名.方法名 2、不同类中: 静态的: 对象名.方法名 对象名.属性名 类名.方法名 类名.属性名 非静态的: 对象名.属性名 类名.方法名 注意:1、static可以修饰属性、方法、代码块,不可以修饰类和构造方法。 2、静态方法随着类的加载而加载。 3、在静态方法区内的东西只有一份,所有的对象共享这一份空间,只要有一个对象对属性进行修改,所有的对象调用都是修改后的数据。 4、代码块的执行顺序:静态代码块(只被调用一次)&
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。