1. equals与==的区别?
==:是值比较
equals是Objcet定义的方法。默认实现的就是==比较的
java中所有类都有equals,若不重写就是用==比较的,需要重写equals方法才能实现比较内容。
equals是比较两个对象的内容,但是需要重写equals方法。
== 用于比较两个变量值是否相等, 当比较引用变量时候,就比较引用中保存的地址值是否相等, 地址相等得到true, 否则false.
Java在Object定义了equals方法, 用于比较两个对象是否相等, 但是其默认实现就是利用 == 比较了两个对象的引用是否一样.默认规则不好, 建议使用使用者合理重写equals方法. Eclipse提供了自动化工具重写equals方法.
2 int 和Integer:
1:int:是java默认的整数类型、是基本类型、占4个字节
2:Integer:是int类型所对应的包装类,它的出现因为基本类型不能参加面向对象的开发问题,
所以基本类型以一个对象的形式表现出来,这样就具有的面向对象的相关特点:封装继承、多泰,这样就可与参加面向对象开发
提供了一个静态静态方法parseInt()可以把帮助把字符串节解析成基本类型,还提供了二个常量MAXVALUE 、MINVALUE分别表示了基本类型的取值范围最大值和最小值
3、线程的运行方式/线程是干什么的:(改变代码的执行方式)
线程:是帮我们改变了代码的执行方式,原来代码是串型操作(从上到下一行一行执行)、多线程帮我们把代码可以并发运行,多个代码感官上可以同时执行
并发:多个线程之间的运行,实际上是线程调度器在分配CPU时间片,让线程之间走走停停 、来回来去执行、基本上的感觉是齐头并进的感官上是同时运行,但是在微观上切换运行的,这种工作方式是并发。
线程的几中创建方式:
1:直接继承Thread重run方法
2:单独定义线程任务实现Runnable接口
这2种创建线程方式的优缺点:
1:直接继承线程:
优点:使用匿名内部类创建比较简便、
带来的缺点是:1.由于继承了线程,java是单继承的,若继承了线程就没有办法继承其 他的类重写方法,在实际开发中非常不便,必须在二者中选其一,就产生了继承冲突问题,2.直接继承线程重写run方法,那就相当与在实现线程的同时就直接把 任务定义在其中,就会出现线程与任务之间有必然的耦合关系,
这个线程只会做这一件事情,其他的事情不会做了,这样就会大大降低线程的储用性,为此有第二种创建线程的方式:
2:单独去定义线程任务:优点1:首先实现Runnable接口,实现接口不妨碍我们去实现其他的接口不存在继承冲突问题,
2:把线程与任务分开了,线程是线程任务是任务,没有必然的耦合关系,将来线程是可以重用的,(利用这种方式我们才有了线程池的应用,线程池直接给任务进去的)
4、线程并发安全问题/多线程的并发安全问题:
首先多线程并发安全问题产生的原因在于多个线程在并发操作同一临界资源由于线程切换时机不确定,导致代码的执行顺序未按照程序设计方式去执行,出现对临界资源访问时出现了混乱,导致后面出现了不可预知后果,严重的时候肯能出现系统瘫痪。
如何解决并发安全问题:把并发操作同一临界资源的事情变成同步执行,先后顺序的排队干,使用synchronized关键字,就是我们所谓的同步锁。同步锁有两种使用方式,第一种是直接在方法上加synchronized,这个时候此方法称为同步方法,同个线程是不能同时执行这个方法的,就不会出现并发安全问题。另一种是同步块,最大好处是让我们更加准确的去控制需要同步运行的代码片段,如果我们有效的缩小同步范围,是可以在我们并发安全的前提下,提高我们的并发效率。使用同步块的原则是,多个线程在调用同步块的时候,看到的同步监视器对象必须 是同一个,否则没有同步效果。
5、实际开发中哪个比较好?
没有绝对的好,视情况而定,如果发现整个方法里面的代码都需要排队执行的时候,最方便的就是在方法上加synchronized,如果方法中只有一小部分需要排队执行的时候,那我们就锁定这一段代码,使用同步块。
6、互斥锁是什么:
互斥锁仍然是利用synchronized实现,当synchronized锁了两段或者多段不同的代码,而这些synchronized的同步块只对应了同步监听器对象是相同的时候,这几段代码之间就是互斥的。意味着多个线程是不能在同时在这些互斥块中执行代码的。Synchronized锁定了多个代码片段,这些synchronized指定的同步监视器对象是同一个,这些代码之间就是互斥的。
7、死锁是什么:
各自拿着各自的锁,又等着对方先释放锁,就产生了死锁。在实际开发中,我们应当尽可能的去选择同步监视器对象,避免出现死锁问题。
8、什么是集合?
集合在java中我们有集合框架,集合框架提供了一个接口java.Util.collection,collection下的所有子类型都是集合。集合框架还有map。
Collection和Collections的区别:
Collection是所有集合的顶级接口,里面规定了集合所定义的相关的方法。比如添加、删减元素等。Collections是集合的工具类,里面提供了很多的静态的方法可以帮助我们便捷的去操作集合,比如排序sort。Collections还有一些方法,synchronized list
,synchronizedset,synchronizedmap可以帮助我们将现有的list、set、map集合转换成线程安全的。
Collection下常用的集合有哪些?
List、set。
区别:list集合是可重复集,set不可重复。List集合一定有序,set大部分是无序的。
List集合常用的实现类:
ArrayList和linkedList区别:
使用上方法功能都一样,实现的数据结构是不同的。ArrayList是数组实现的。LinkedList是链表实现的。因为实现的数据结构不同,导致他们的特性不相同,数组的特点是查的快,但是增删差。
LinkedList是链表,增删效率好,而且是收尾增删效率好。查询速度偏慢。以后工作中,增删用的多的就使用LinkedList,查询多的就使用ArrayList。
Map是什么:
查找表,他由key,Value对组成的结构,常用的实现类是hashMap。还知道TreeMap,使用二叉树实现的map。HashMap特点,是世界上查询速度最快的数据结构。
hashMap原理,用散列算法实现的。
hashTable与hashMap的区别:
hashTable在jdk4的时候被重构了一次,他也继承了map,在使用上与hashMap没区别。区别在于,hashTabe是并发安全的map,hashMap不是。在多线程的情况下,使用hashTable。HashMap的put,remove,get都没有加synchronized,所以在多线程下不应当用hashMap。hashTable的key和value 不允许存null值,hashMap可以。
9、Map的遍历方式:
三种:单独遍历key,遍历每一组键值对的entry,遍历value,
方法分别为:keyset entryset,values()
集合的遍历方式:迭代器iterator()
新循环:jdk5出的一个新特性
新循环遍历数组、集合:新循环是编译器认可的,并不是java虚拟机,编译器在编译代码的时候,如果发现我们使用新循环遍历数组,那么编译器会把代码改成使用传统for循环来遍历数组。那么如果编译器发现你在使用新循环遍历集合,她会改用迭代器遍历。遍历集合有一个注意事项。就是在遍历的过程中是不可以通过集合自身的方法增删元素的,,因为迭代器是快速失败原则。
如果想删除元素也可以,迭代器自身也提供了一个remove方法,允许我们在遍历过程中删掉元素
10、字符串的特性/点:字符串是不变对象,字符串对象一但创建,值是不可以改变的,要想改变就一定会创建新的对象。
字符串常量池:在现在的jdk版本中存在堆当中,java虚拟机会缓存我们每一个使用字面量形式创建的字符串对象,
当将来我们再次使用字面量形式创建同样字符串内容的时候,会重用常量池中的对象以减轻内存开销。
11、String str =new String(“hello”);总共创建几个对象:
创建过2个对象:首先有一个字面量虚拟机会创建一个字符串对象,并且把它缓存在常量池当中,再newString的时候只是引用了它而已,有自己new的对象和之前用字面量形式创建的对象。
编译器的特点:
编译器在编译代码的时候若是看到计算表达式参与的所有的值都是字面量的时候,那编译器在编译期间就会把结果算好,减少java虚拟机每次运行的时候再重新计算的问题。变相的提高性能。
StringBuilder:出现是为了解决字符串频繁修改带来的性能问题,因为字符串是不变对象每次修改都要创建新对象
,如果频繁修改内存中产生大量的垃圾对象出来,字符串的频繁拼接性能不高,因此java设计了一个类StringBuilder,它的内部维护着一个可变的字符数组,所有的修改操作都是在同一个字符数组中做操作的,扩容缩容都是用同一个,因此内存开销比较小,因此修改效率比较高,而且是专门为了编辑字符串产生的API,提供了很多便于我们修改字符串的方法,如:append、insert、remove、reverse
StringBuilder和StringBuffer是什么关系:
StringBuffer跟字符串一样是在jdk1.0的时候就推出的API,StringBuilder是在JDK5的时候推出的API,最大的区别
StringBuilder不是线程安全的,StringBuffer是线程安全的,由于在实际开发当中我们很少在多线程操作同一个字符串,因此我们使用StringBuilder可以更好的提高运算性能,但是在多线程情况下操作同一个字符串相当于并发操作同一个字符串时候,还是应当考虑使用StringBuffer。
做过webserver项目:
12、webserver是什么:是当时模拟Tomcat做的一个轻量级的web容器,底下基于TCP与HTTP协议,完成了浏览器与服务器之间的交互工作。
13、TCP与HTTP的关系:HTTP是应用层协议,TCP是底下的传输层协议,HTTP协议要求必须建立在可靠传输协议基础之上进行,通常HTTP底下使用的传输协议就是TCP协议。
HTTP协议是:由w3c(万维网)定义的一个协议,全称是超文本传输协议,它是现在常用的浏览器与服务器之间建立的应用层协议,
HTTP协议的部分:请求与响应,HTTP采取的模式要求客户端与服务器采取一问一答的模式,永远不允许服务端主动与客户端建立链接,并且发起响应,必须是由客户端建立TCP链接发送HTTP请求服务端处理以后予以响应。
HTTP里面请求的格式和响应的格式:
HTTP的请求是客户端发给服务端的东西,一个请求包含三部分分别是请求行、消息头和消息正文,请求行又由三部分构成:分别是请求的方式、请求的资源路径以及所使用的协议版本。还有消息头:客户端传递给服务端一些附加的内容,它可以指明客户端所使用浏览器的内核是什么、以及维持链接所使用的一些东西。格式是由名字: 值以CRLF结尾一行一行的构建,最后一个消息头发送完毕会单独发送一个CRLF,表示消息头部分发完。消息正文:是纯二进制数据,是客户端提交给服务器端用户实际上传的内容,可以是表单上传的数据,也可以是用户提交的一些附件的内容
14、请求常用的请求方式:get请求和post请求
get请求:地址栏请求,以form表单为例,get请求就是把用户输入的信息拼接到url中并以?隔开,后面的内容就是拼接的内容以地址栏的形式传递给服务端。
post请求:把提交上来的数据全部被包含在请求的消息正文中,提交上来的。当表单含有用户隐私信息或者有上传附件操作时,必须使用post请求。
响应也是有三部分组成分别是:状态行、响应头、响应正文
状态行也是由三部分构成:分别是协议版本、状态代码和状态描述。响应头跟请求的消息头格式一样、正文也是一样的。
状态代码:由3位数字构成分为5类分别是100类、200类、300类、400类、500类、
100类是保留部分,200类表示服务端正确处理了客户端请求、300类一般指的是重定向类
400类指的是客户端请求有问题,请求错误,客户端错误。500类服务端错误,常见的状态代码:200一切正常客户端请求正确处理并且予以响应,404就是客户端请求路径无效服务端无法正确处理的,更详细的可以翻阅HTTP协议文档。
15、webserver项目负责哪一块:这个项目做的是轻量级的webserver,架构没有tomcat那么复杂,从头到尾都是自己写的,从建立TCP链接,到利用线程处理请求,在请求当中去如何解析HTTP协议,如何处理完请求,如何发送HTTP响应,整个流程都做过,还模拟了servlet去处理业务。
完整阐述项目:流程图自己的话
完成项目中遇到的问题:
遇到空请求,于是查阅了HTTP协议文档,发现HTTP协议允许客户端发送空请求过来,所以以后解析请求发现空请求,这次请求忽略处理。
16、常见的头:Content-Type 、Content-Length 分在请求的消息头中还是在响应的消息头中,响应头中让服务器告知浏览器此次发送的响应是包含响应正文的,通过Content-Length告知浏览器此响应正文中总共多少个字节,再通过Content-Type告知浏览器这些字节表示的是什么类型的数据。
常见的Content-Type 的值:text/html 告诉浏览器发送的正文是html页面,img/png告诉这是一张图片
text/css样式文件 脚本 有1000多种,可以到tomcat安装目录下的conf包中web.xml中有所定义,并且我曾经拿xml的解析把整个的1000多种全部解析出来用到自己的项目当中,并且可以根据用户实际请求的资源可以自动分析并且能够给用户响应正确的头,这个当时也有做到在response中已经实现了。
17、RandomAccessFile是做什么的:简单说是读写文件的API、基于指针的随机读写形式、
RandomAccessFile和文件流的区别:最大的区别在于读写方式不同、RandomAccessFile是专门设计出来用来读取文件的API是基于指针的随机读写,可以对文件的任意位置或读或写。
文件流是基于java标准io的读写方式是处于顺序读写模式只能往后顺序的读或写,是不能回退的。灵活性上文件流不如RandomAccessFile
18、文件流的优势:文件流基于java标准io操作,我们可以利用流连接来连接上各种功能强劲的高级流,把一个复杂工作简单化。
19、流连接:就是串联若干的高级流最终连上低级流对某一个设备,进行复杂的读写操作,利用流水线似的工作,每一个高级流处理一个环节,最终把事情干完。因为io最大的特点就是流连接 把复杂问题简单化。
流连接做过什么:利用过缓冲流连接文件流对文件进行块读写操作来提高文件的读写效率。
连接过对象流对java对象进行过序列化与反序列化操作。
在websever读取客户端的请求用socket得到的流也是基于io进行读写数据交互,读写文件连上字符流
20、节点流和处理流:
节点流也称为低级流,特点是数据源明确,通过低级流是做真实的数据读写操作的,可以把数据写到目标去也可以从目标读数据回来。
处理流又叫高级流:他们不能独立存在必须连接在其他流上,目的就是当数据经过我的时候,我可以对你进行某些加工处理工作,我的这个流连接当中就是利用串联很多高级流,来最终串联低级流,来完成复杂读写的。