IT面试笔记整理
1.数据类型?
答:表示一组值的取值范围以及在这组值上的相关操作,数据类型分为由系统定义的数据类型,又称原始数据类型和用户自定义的数据类型。
2.传递方式?
答:按值传递和按引用(地址)传递,对于Java来说,其实都是按值传递,对于基本的数据类型,它传递的是其值,对于引用类型,它传递的值是对象的地址值。
3.绑定?
答:从宏观的角度,就是把名称和其包含的内容关联起来的过程,例如把变量的名称和它包含的值关联起来,绑定时间则是指这种关联关系发生在什么时候;根据绑定的时间又可以分为动态绑定和静态绑定:绑定的时间又可以细分很多阶段:例如设计,编译,连接,加载,运行;静态绑定指的是:运行之前的绑定:例如 C语言中的值和常量之间的绑定;动态绑定指的是:发生在运行期间的绑定,例如:指针变量与内存位置之间的绑定。
4.存储类型?
答:指的是分配给变量或对象的存储空间究竟位于内存的哪一部分,又决定了该空间的有效期,还决定变量名在程序中的哪个范围里可见,或者在哪个范围里访问到该变量;C语言分为4中,默认为auto,还有extern,static,register。
5.浅拷贝和深拷贝
答:C++的浅拷贝和深拷贝:
浅拷贝:把原对象中每一个成员字段的值都拷贝到新对象里,对于普通类型来说没有问题,但是对于指针,引用类型来说,引用类型的字段未必成立,因为指针所指向的那些内存都是动态分配的,并不会自动得到拷贝,这导致原来的对象和新对象中的字段,指向同一块动态分配内存,会让两个对象之间的修改产生关联;
深拷贝:不仅拷贝原对象中的每一个字段,而且还将动态分配给该字段的内存内容也一起拷贝过来,因此必须拷贝构造函数,并重载赋值运算符,否则还会是浅拷贝那样;
浅拷贝:只拷贝主对象中的基本类型的变量,对于变量中的引用对象,不会拷贝其具体的内容,而是拷贝其引用地址,让新的拷贝对象中的引用对象还是指向原来的地址;
深拷贝:深拷贝会拷贝对象的所有属性,并拷贝属性指向的动态分配内存,即当对象和它所引用的对象一起拷贝的时候即发生深拷贝,深拷贝比浅拷贝花费的时间多;
6.抽象类和接口
答:抽象类是不能实例化的类,为包含一个或多个纯虚函数的类;纯虚函数是指由具体的派生类来覆盖的函数,接口是进一步提升了抽象的程度,只能在类中声明方法,而不能为其编写代码,这些代码要留给实现本接口的类去写,接口中所有的方法都是抽象的;区别:抽象类里面可以提供默认的实现代码,也可以有变量,接口中的方法只能实现类实现,但是java8提供了默认的实现;接口里声明的变量默认都是final,抽象类则可以包含非final的变量;接口中的成员默认的权限修饰符为public,抽象类中的权限修饰符可以是private,protected成员;接口需要使用implements关键字实现,抽象类必须使用extends关键字;一个类可以实现多个接口,只能继承一个类。
7.Java的性能分析?
答:Java是由JVM进行运行,一次编写,多次运行,JVM虚拟机屏蔽了低层的不同;Java去掉指针的现实操作;Java效率低下的问题:所有的对象都必须分配在堆上;不能访问低层的细节信息,即当编译器无法进行优化的时候,开发者也无法进行优化;
8.Java中的HashMap的运作方式?
答:HashMap的存储是通过一个数组,数组的每个元素(bucket)又是一个链表,而数组的位置通过Hash来确定。HashMap是通过哈希码来运作的,put和get方法进行操作时,都要计算其哈希码;在进行put操作时,hashMap会根据key的值调用hashCode()方法,并根据计算出的哈希码及自身的哈希函数,来确定对应的bucket位置,以保存值对象, 注意的是HashMap是把键和值同时保存在bucket里面,而非只保存值,不保存键。
如果两个不同的对象具有相同的哈希码?
答:在Java语言中equals()和hashCode()方法所做的约定,两个不同的对象,可以由相同的哈希码,HashMap在同一个bucket里面采用链表来存储各项数据,因此,新来的键和值会接在那些节点后面;
如果两个不同的对象具有相同的哈希码,怎么获取,以及区分?
答:当确定了bucket(桶)位置后,通过将其key与这个桶的链表的所有key进行比较,找到键值相同的,并将该对象关联的值返回给调用方;
如果HashMap的存储量超过了载荷因此规定的量?
9.HashMap和Hashtable的区别?
答:hashMap的键和值,都可以是Null,也不是同步的;hashtable是同步的,不允许有空键;hashMap的Iterator是一种fail-fast型的迭代器,当出现错误时,会尽快出错;HashTable的Enumeration则不是;
10.Java的同步机制?
答:Java使用Synchronized和volatile关键字实现同步;
同步最多用到访问共享数据上,当多个方法访问了一个临界资源,为了是有序的使用临界资源,同步机制解决问题;Java中的synchronized关键字,可以用来实现同步,他可以修饰方法,代码块,不能修饰变量,同时Java的每个对象都有一个锁,当线程访问该对象的时候,必须获取这个对象的锁,然后访问资源,如果有其他线程想要访问临界资源,则会阻塞,同时加入到该对象的等待队列中,直到拥有锁的对象访问完临界资源,释放锁后,系统会从等待队列中随机选出一个对象访问临界资源;
对于变量的同步,可以使用volatile关键字,volatile关键字可以保证线程的可见性,当有线程在访问该变量的时候,该变量的改动在其他线程中可见,JVM线程遇到这种变量时,会直接从内存里面读取其值,而不会把它缓存起来;注意:当synchronized关键字修饰的是静态方法,则对应的锁就会加载代表那个类的class对象上,若修饰的是非静态方法,则会加在当前对象上;
11.String和StringBuffer区别?
答:String用来操作内容不变的字符串,StringBuffer可以用来修改字符串;即String相当于创建一个字符常量,当对字符进行添加,修改的时候,他会先在常量池中寻找对象,如果有的话,就直接指向,如果没有,则会创建一个新的字符串在常量池中,并指向他;Stringbuffer则常见一个可以修改的变量;
12.Java中的== 和equal() 区别?
答:对于基本类型,==比较两个对象是否相等;对于引用类型,==比较两个对象的在堆中的地址是否相同,即是否是同一个引用对象equal()方法比较取决于该方法所在的类是如何在定义equal()方法的,即可以判断对象是否是逻辑上的相等,如果没有覆盖equal()方法,则调用的实际上是继承自Object类的那个equal()方法,该方法还是进行简单的==运算;
何时用到equal()方法进行比较?
答:例如: 比较两个字符串,String s1 = new String("123"); String s2 = new String("123");,如果使用==做比较,则两个对象绝对不相等,因为java在堆上创建了两个字符串对象,两个对象的地址绝对不同,只不过两个对象都指向同一个常量池中的字符串,但在栈中变量名指向的是堆上的对昂,因此使用==比较并不能达到我们的字符串比较的效果,必须进行重写;
13.序列化?
答:序列化是一种读取或写入对象的过程;它可以把对象的状态保存成一系列字节,根据这些字节,可以把对象重新构建出来,只需要实现Serializable接口,这个接口仅仅起到标记作用;transient 修饰的变量不参与序列化,凡是标记为transient的字段,都不会被序列化;
14.finaize方法?
答:finalize用于在GC发生前事先调用去回收JNI调用中申请的特殊内存,下次GC发生时候保证GC后所有该对象的内存都释放了。所谓的特殊内存指通过JNI用C/C++向系统申请的内存,这些内存如果不手动去清除就会一直占据在内存中。当系统进行GC的时候会先调用finalize方法,然后在下次才会回收对象的内存。因为native中申请的内存,GC没有办法回收所以finalize被用来做垃圾回前的重要清理工作:释放特殊内存。调用System.gc(),可以强制让gc发生来触发finalize方法!
15.Java的垃圾回收机制?
答:首先从Java运行内存的划分来说,Java将运行去换分为堆,本地方法栈,虚拟机栈,程序计数器,方法区;Java的垃圾回收主要集中在堆中,而堆又细分为 年轻代和老年代,年轻代主要存放新创建的对象,老年代用于存放声明周期比较长的对象,Java的年轻代有分为1个eden区和1对survivor区,survivor总存放的是至少经历了一次MinorGC,只有一块有对象,另一块基本是空的,新创建的对象在eden区,大对象直接放入到老年代,当发生MinGC的时候,将eden区存活的对象复制到空的survivor区域中,被占用的survivor里不够老的存活对象也被复制到未使用的survivor中,被占用的survivor中足够老的存活对象被提升到老年代,MinGC后,Eden区为空,survivor中仍然只使用一个,当MinGC中,survivior不能够容纳eden和被占用survivior中的存活的对象的时候,会将多余的对象提升到老年代,如果老年代都无法容纳更多的对象,则MinnorGC之后通常会进行FullGC,将导致遍历整个Java堆。
16.变量的声明和定义?
答:声明变量仅仅是提到变量的类型和名字,并不做初始化;定义变量:声明的同时,还做了初始化;
17.JDBC(JAVA DATABASE CONNECTION )介绍?
答:JDBC连通了用户和低层的数据库,他向用户提供了一个访问不同数据库的API,用户通过这个API访问数据库,向不同的数据库厂商提供公共的Driver接口,各个数据库实现JDBC Driver接口,通过JDBC Driver Manager来管理各个实现的Driver接口,用户便可以通过同一个接口访问不同的数据库;
简单的创建JDBC应用程序?
1)引入Jdbc的Jar包
2)注册Jdbc驱动: Class.forName("com.mysql.jdbc.Driver");
3) 开启数据库的连接: DriverManager.getConnection();
static final String user = "username";
static final String pass = "password";
conn = DriverManager.getConnection(DB_URL,user,pass);
4)执行查询
stat = conn.createStatement();
String sql = "select * from xx ;";
ResultSet rs = stat.executeQuery(sql);
5)提取数据
while(rs.next()){
int id = rs.getInt("id");
int age =rs.getInt("age");
String fristName= rs.getString("first");
6)关闭连接:
rs.close();
stat.close();
conn.close();
18.PATH 和classpath?
答:Path是用来帮助操作系统来确定可执行文件的位置,因此为了快速访问,我们在安装可执行文件的时候,会将其路径添加到PATH中;classPath:转为为Java应用来使用的,java用它来确定类文件的位置,运行java应用,通过classpath指定目录,jar文件等,以供Java系统在其中寻找相应的类。
19.static关键字?
答:static关键字可以用于修饰变量和方法,使得变量和方法随着类的加载而加载,在访问的时候可以不用实例化,通过类直接访问,静态方法只能访问静态变量。注意顶级类不能声明成static,但是内部类可以声明成static的内部类,又称静态嵌套类;
20.JSP介绍以及运行过程?
答:Java Server page: Java服务器语言,是一种支持动态语言的网页开发技术,编程者可以使用Java语言,将Java代码写入html语言。JSP原理如下:
1)浏览器给服务器发送一个HTTP请求;
2)如果发现请求的是一个Jsp页面,Web服务器将其转发给JSP引擎;
3)JSP引擎将Jsp页面加载进来,并将其转换成Servelt内容,即把文本转换为println()语句,并把JSP元素变为对应的Java代码;
4)JSP引擎会将Servlet编译成可执行的class,并把原始的请求转发给Servlet引擎,
5)Servlet引擎加载java代码,会产生HTML格式的输出信息,Sevlet引擎把这些信息放在HTTP响应消息里面,传给Web服务器;
6)Web服务器以静态HTML的形式将HTTP响应消息转发给浏览器
JSP的生命周期?
1) 编译:解析JSP,将JSP变为Servlet,编译Servlet;
2)初始化:调用jspInit()方法,然后开始处理请求,初始化只执行一次;
3)执行,调用JspServiece()方法,该方法有两个参数分别是 HttpServletRequest 及HttpServletResponse类型,没处理一次请求,都要执行一次_jspService()方法,以便生成针对该请求的应答。
4)清理:容器移除某个JSP方法的时候,JSP进入销毁阶段,jspDestory()方法会得到调用,相当于Servlet的destory()方法。
21.编译器和解释器?
答:编译器:自动将高级语言转换为计算机能够识别的二进制数,编译器也可以做多次编译,每一次都将其编译成更接近计算机识别的语言;解释器:可以把高级语言转换为中间形式,避免比较耗时的编译阶段。
区别:编译器会将整个程序编译成可机器语言,解释器则把高级指令转换成中间形式;
编译器只有把整个程序处理完,才能开始 执行这个程序;而解释器则可以翻译一行执行一行;
编译器可以创建出独立的可执行文件,而解释器交给解释器来执行,那每次运行的时候都必须用到解释器;
编译器在执行完编译过程后才列出错误的,解释器只有碰到错误,就不再往下翻译了;
22.设计模式的原则?
答:单一职责:即每个类,接口应该只负责一个功能,降低类之间的内聚性;
里式替换:建立在继承的基础上,能够使用子类的方法上都可以使用父类;
迪米特原则:一个软件实体,应当尽可能少于其他实体发生相互作用;
接口隔离原则:使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。
如有问题,敬请指出,谢谢,与君共勉。