- 1. String、StringBuffer、StringBuilder的区别
- ==和equals的区别
- 接口和抽象类的区别
- java中的工具容器类List,Map
- IO
- 多线程
- 设计模式
- http get和post的区别
- servlet
- session和cookie
- sql 使用
- try{}catch{}finally{}内return的执行顺序
- 关键字final和static
- 考察static修饰后,代码的执行顺序
1. String、StringBuffer、StringBuilder的区别
String内部是不可变数组,在String定义的时候就确定了;而StringBuilder和StringBuffer都是继承了AbstractStringBuilder抽象类,内部使用动态的数组实现;StringBuffer是支持线程同步的,操作效率低一些;String、StringBuffer、StringBuilder都是final修饰的,都实现了Serializable接口。
String内部源码解析:/** The value is used for character storage. *//** 内部使用char数据来存储,使用final修饰,意味着这是一个不可变的字符数组 */private final char value[];StringBuilder的内部源码解析:abstract class AbstractStringBuilder implements Appendable, CharSequence {/*** The value is used for character storage.*/char[] value;}StringBuilder的父类中,使用了一个动态数组;public StringBuilder() {super(16);}public StringBuilder(int capacity) {super(capacity);}public StringBuffer(String str) {super(str.length() + 16);append(str);}在StringBuilder中的构造器,初始化赋值时,默认给动态数据赋值为16;StringBuffer与StringBuilder的内部原理类似,但StringBuffer的方法添加了同步功能,是线程安全的。
==和equals的区别
超父类Object中有equals的方法
public boolean equals(Object obj) {return (this == obj);}
==基本数据类型比较的是值,引用数据类型比较的是两个对象的地址,若定义的类,没有重写equals方法,那么==和equals方法的功能是相同的;在String中,重写了equals方法
public boolean equals(Object anObject) {if (this == anObject) {return true;}if (anObject instanceof String) {String anotherString = (String)anObject;int n = value.length;if (n == anotherString.value.length) {char v1[] = value;char v2[] = anotherString.value;int i = 0;while (n-- != 0) {if (v1[i] != v2[i])return false;i++;}return true;}}return false;}
接口和抽象类的区别
java中的工具容器类List,Map
Java中的集合分为value,key—vale(Conllection Map)两种。
存储值有分为List 和Set.
List是有序的,可以重复的。
Set是无序的,不可以重复的。根据equals和hashcode判断,也就是如果
一个对象要存储在Set中,必须重写equals和hashCode方法。
存储key-value的为map.
List常用的ArrayList和LinkedList。区别和使用场景?
ArrayList底层使用时数组。LinkedList使用的是链表。
数组查询具有所有查询特定元素比较快。而插入和删除和修改比较慢(数组在内存中是一块连续的内存,如果插入或删除是需要移动内存)。
链表不要求内存是连续的,在当前元素中存放下一个或上一个元素的地址。查询时需要从头部开始,一个一个的找。所以查询效率低。插入时不需要移动内存,只需改变引用指向即可。所以插入或者删除的效率高。
ArrayList使用在查询比较多,但是插入和删除比较少的情况,而LinkedList使用在查询比较少而插入和删除比较多的情况。
HashMap哈HashTable的区别?HashTable和ConcurrentHashMap的区别?
相同点:HashMap和HasheTalbe都可以使用来存储key—value的数据。
区别:
1、HashMap是可以把null作为key或者value的,而HashTable是不可以的。
2、HashMap是线程不安全的,效率较高。而HashTalbe是线程安全的,效率较低。
?我想线程安全但是我又想效率高?
通过把整个Map分为N个Segment(类似HashTable),可以提供相同的线程安全,但是效率提升N倍,默认提升16倍。
IO
实现一个拷贝文件的工具类使用字节流还是字符流?
我们拷贝的文件不确定是只包含字符流,有可以能有字节流(图片、声音、图像等),为考虑到通用性,要使用字节流。
多线程
讲一下线程的几种实现方式?启动方式?区分方式?
①实现方式
1、通过继承Thread类实现一个线程
2、通过实现Runnable接口实现一个线程
继承扩展性不强,java总只支持单继承,如果一个类继承Thread就不能继承其他的类了。
②怎么启动?
Thread thread = new Thread(继承了Thread的对象/实现了Runnable的对象)
thread.setName(“设置一个线程名称”);
thread.start();
启动线程使用start方法,而启动了以后执行的是run方法。
③怎么区分线程?
在一个系统中有很多线程,每个线程都会打印日志,我想区分是哪个线程打印的怎么办?
thread.setName(“设置一个线程名称”); 这是一种规范,在创建线程完成后,都需要设置名称。
有没有使用过线程并发库?
简单了解过?
JDK5中增加了Doug Lea的并发库,这一引进给Java线程的管理和使用提供了强大的便利性。 java.util.current包中提供了对线程优化、管理的各项操作,使得线程的使用变得的心应手。该包提供了线程的运行,线程池的创建,线程生命周期的控制.
Java通过Executors提供四个静态方法创建四种线程池,分别为:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行
线程池的作用?
1、限定线程的个数,不会导致由于线程过多导致系统运行缓慢或崩溃
2、线程池不需要每次都去创建或销毁,节约了资源、
3、线程池不需要每次都去创建,响应时间更快。
连接池也是一样?
设计模式
设计模式就是经过前人无数次的实践总结出的,设计过程中可以反复使用的、可以解决特定问题的设计方法。
单例(饱汉模式、饥汉模式)
1、构造方法私有化,让出了自己类中能创建外其他地方都不能创建
2、在自己的类中创建一个单实例(饱汉模式是一出来就创建创建单实例,而饥汉模式需要的时候才创建)
3、提供一个方法获取该实例对象(创建时需要进行方法同步)
工厂模式:Spring IOC就是使用了工厂模式.
对象的创建交给一个工厂去创建。
代理模式:Spring AOP就是使用的动态代理。
http get和post的区别
GET和POST请求都是http的请求方式,用户通过不同的http的请求方式完成对资源(url)的不同操作。GET,POST,PUT,DELETE就对应着对这个资源的查 ,改 ,增 ,删 4个操作,具体点来讲GET一般用于获取/查询资源信息,而POST一般用于更新资源信息
1、Get请求提交的数据会在地址栏显示出来,而post请求不会再地址栏显示出来.
GET提交,请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),以?分割URL和传输数据,多个参数用&连接;POST提交:把提交的数据放置在是HTTP包的包体中。 因此,GET提交的数据会在地址栏中显示出来,而POST提交,地址栏不会改变
2、传输数据的大小
http Get请求由于浏览器对地址长度的限制而导致传输的数据有限制。而POST请求不会因为地址长度限制而导致传输数据限制。
3、安全性,POST的安全性要比GET的安全性高。
由于数据是会在地址中呈现,所以可以通过历史记录找到密码等关键信息。
servlet
Servlet(Server Applet),全称Java Servlet, 是用Java编写的服务器端程序。而这些Sevlet都要实现Servlet这个借口。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。Servlet运行于支持Java的应用服务器中。
HttpServlet 重写doGet和doPost方法或者你也可以重写service方法完成对get和post请求的响应
简单说一下servlet的生命周期?
servlet有良好的生存期的定义,包括加载和实例化、初始化、处理请求以及服务结束。这个生存期由javax.servlet.Servlet接口的init,service和destroy方法表达。
加载Servlet的class——>实例化Servlet——->调用Servlet的init完成初始化——>响应请求(Servlet的service方法)——->Servlet容器关闭时(Servlet的destory方法)
Servlet启动时,开始加载servlet生命周期开始。Servlet被服务器实例化后,容器运行其init方法,请求到达时运行其service方法,service方法自动派遣运行与请求对应的doXXX方法(doGet,doPost)等,当服务器决定将实例销毁的时候(服务器关闭)调用其destroy方法。
Servlet API中forward() 与redirect()的区别?
1、forward是服务器端的转向而redirect是客户端的跳转。
2、使用forward浏览器的地址不会发生改变。而redirect会发生改变。
3、Forward是一次请求中完成。而redirect是重新发起请求。
4、Forward是在服务器端完成,而不用客户端重新发起请求,效率较高。
session和cookie
Session和cookie都是会话(Seesion)跟踪技术。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。但是Session的实现依赖于Cookie,sessionId(session的唯一标识需要存放在客户端).
cookie 和session 的区别:
1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
考虑到安全应当使用session。
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用COOKIE。
4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
5、所以个人建议:
将登陆信息等重要信息存放为SESSION
其他信息如果需要保留,可以放在COOKIE中,比如购物车
购物车最好使用cookie,但是cookie是可以在客户端禁用的,这时候我们要使用cookie+数据库的方式实现,当从cookie中不能取出数据时,就从数据库获取。
sql 使用
Mysql是使用关键字limit来进行分页的 limit offset,size 表示从多少索引去多少位.
String sql ="select * from students order by id limit " + pageSize*(pageNumber-1) + "," + pageSize;
try{}catch{}finally{}内return的执行顺序
public class MainTest {public static String func(String flag){try {if("exception".equals(flag)){throw new Exception();}return "try块内的返回值";} catch (Exception e) {e.printStackTrace();return "catch块内的返回值";} finally {System.out.println("finally块内的逻辑");return "finally块内的返回值";}}@Testpublic void test(){System.out.println(func("normal"));System.out.println("++++++++++++++++++");System.out.println(func("exception"));}}
关键字final和static
考察static修饰后,代码的执行顺序
题一
public class Children extends Parent{static{System.out.println("Children static");}public Children(){System.out.println("Children constructor");}}class Parent{static{System.out.println("Parent static");}public Parent(){System.out.println("Parent constructor");}}@Testpublic void test(){new Children();}//👇代码执行顺序Parent staticChildren staticParent constructorChildren constructor
题二
public class Person{static{System.out.println("Person static");}public Person(String str) {System.out.println("person "+str);}}class Parent {Person person = new Person("Test");static{System.out.println("Parent static");}public Parent() {System.out.println("Parent constructor");}}class Children extends Parent {Person person = new Person("Children");static{System.out.println("Children static");}public Children() {System.out.println("Children constructor");}}@Testpublic void test(){new Children();}//👇输出结果Parent staticChildren staticPerson staticPerson Constructor ParentParent constructorPerson Constructor ChildrenChildren constructor
题三
public class Test {static{System.out.println("test static 1");}public static void main(String[] args) {}static{System.out.println("test static 2");}}//👇执行结果test static 1test static 2
