首先本人自己是一名Java开发,去过朗致集团面试,无聊之余,整理下他们公司的面试题,希望可以帮到别人。当然有些部分是自己查的,也有一部分题目没有写,大家也可以帮我补充,或者更改。
注:如有侵权,请联系本人删除文章,谢谢。
一、如此定义,short s=1;是否有误,定义 long v=99999999;是否有误;
答:short s =1 没问问题,需要注意的是,short和int之间会有一个类型转换的过程;
也就是说,byte,short,int,long,类型由大转成小的时候,会有隐式的转换;
隐式转换也叫作自动类型转换, 由系统自动完成.从存储范围小的类型到存储范围大的类型.
byte->short(char)->int->long->float->double
显示类型转换也叫作强制类型转换, 是从存储范围大的类型到存储范围小的类型.当我们需要将数值范围较大的数值类型赋给数值范围较小的数值类型变量时,由于此时可能会丢失精度(1讲到的从int到k型的隐式转换除外),因此,需要人为进行转换。我们称之为强制类型转换。
double→float→long→int→short(char)→byte
long 类型定义 数值后面必须加l;
二、math.round(-5.5)的结果是什么?
-5
ceil的英文意义是天花板,该方法就表示向上取整,Math.ceil(11.3)的结果为12,Math.ceil(-11.6)的结果为-11;
floor的英文是地板,该方法就表示向下取整,Math.floor(11.6)的结果是11,Math.floor(-11.4)的结果-12;
最难掌握的是round方法:他表示“四舍五入”,算法为Math.floor(x+0.5),即将原来的数字加上0.5后再向下取整,
所以,Math.round(11.5)的结果是12,Math.round(-11.5)的结果为-11.Math.round( )符合这样的规律:小数点后大于5正数和负数全部加1,等于5正数加1,小于5正数和负数全不加1。
三、abstractmethod 是否可以同时static?为什么?
答:不能放在一起的修饰符:final和abstract,private和abstract,static和abstract,因为abstract修饰的方法是必须在其子类中实现(覆盖),才能以多态方式调用,以上修饰符在修饰方法时期子类都覆盖不了这个方法,final是不可以覆盖,private是不能够继承到子类,所以也就不能覆盖,static是可以覆盖的,但是在调用时会调用编译时类型的方法,因为调用的是父类的方法,而父类的方法又是抽象的方法,又不能够调用,所以上的修饰符不能放在一起。
四、一个需要对key排序的Map,您一般选择哪个?HashMap,LinkedHashMap 为什么?
java为数据结构中的映射定义了一个接口java.util.Map;它有四个实现类,分别是HashMap Hashtable LinkedHashMap 和TreeMap.
HashMap是一个最常用的Map,它根据键的hashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。HashMap最多只允许一条记录的键为NULL,允许多条记录的值为NULL。
HashMap不支持线程同步,即任一时刻可以有多个线程同时写HashMap,可能会导致数据的不一致性。如果需要同步,可以用Collections的synchronizedMap方法使HashMap具有同步的能力。
Hashtable与HashMap类似,不同的是:它不允许记录的键或者值为空;它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了Hashtable在写入时会比较慢。
LinkedHashMap保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的。
在遍历的时候会比HashMap慢TreeMap能够把它保存的记录根据键排序,默认是按升序排序,也可以指定排序的比较器。当用Iterator遍历TreeMap时,得到的记录是排过序的
五、如何定义一个线程安全的List?
一:使用synchronized关键字,这个大家应该都很熟悉了,不解释了;
二:使用Collections.synchronizedList();使用方法如下:
假如你创建的代码如下:List<Map<String,Object>>data=new ArayList<Map<String,Object>>();
那么为了解决这个线程安全问题你可以这么使用Collections.synchronizedList(),如:
List<Map<String,Object>> data=Collections.synchronizedList(new ArrayList<Map<String,Object>>());
其他的都没变,使用的方法也几乎与ArrayList一样,大家可以参考下api文档;
额外说下 ArrayList与LinkedList;这两个都是接口List下的一个实现,用法都一样,但用的场所的有点不同,ArrayList适合于进行大量的随机访问的情况下使用,LinkedList适合在表中进行插入、删除时使用,二者都是非线程安全,解决方法同上(为了避免线程安全,以上采取的方法,特别是第二种,其实是非常损耗性能的)。
六、Override,Overload区别,Overloaded的方法是否可以使用不同的返回值类型?
Override 的特点
1、覆盖的方法的标志必须要和被覆盖的方法的标志完全匹配,才能达到覆盖的效果;
2、覆盖的方法的返回值必须和被覆盖的方法的返回一致;
3、覆盖的方法所抛出的异常必须和被覆盖方法的所抛出的异常一致,或者是其子类;
4、被覆盖的方法不能为private,否则在其子类中只是新定义了一个方法,并没有对其进行覆盖。
overload对我们来说可能比较熟悉,可以翻译为重载,它是指我们可以定义一些名称相同的方法,通过定义不同的输入参数来区分这些方法,然后再调用时,VM就会根据不同的参数样式,来选择合适的方法执行。在使用重载要注意以下的几点:
Overload 的特点
1、在使用重载时只能通过不同的参数样式。例如,不同的参数类型,不同的参数个数,不同的参数顺序(当然,同一方法内的几个参数类型必须不一样,例如可以是fun(int,float),但是不能为fun(int,int));
2、不能通过访问权限、返回类型、抛出的异常进行重载;
3、方法的异常类型和数目不会对重载造成影响;
4、对于继承来说,如果某一方法在父类中是访问权限是priavte,那么就不能在子类对其进行重载,如果定义的话,也只是定义了一个新方法,而不会达到重载的效果。
七、单例类如何控制线程安全?
第一种:饿汉模式(线程安全)
public class Single2 {
private static Single2 instance = new Single2();
private Single2(){
System.out.println("Single2: " + System.nanoTime());
}
public static Single2 getInstance(){
return instance;
}
}
第二种:懒汉模式 (如果方法没有synchronized,则线程不安全)
public class Single3 {
private static Single3 instance = null;
private Single3(){
System.out.println("Single3: " + System.nanoTime());
}
public static synchronized Single3 getInstance(){
if(instance == null){
instance = new Single3();
}
return instance;
}
}
第三种:懒汉模式改良版(线程安全,使用了double-check,即check-加锁-check,目的是为了减少同步的开销)
public class Single4 {
private volatile static Single4 instance = null;
private Single4(){
System.out.println("Single4: " + System.nanoTime());
}
public static Single4 getInstance(){
if(instance == null){
synchronized (Single4.class) {
if(instance == null){
instance = new Single4();
}
}
}
return instance;
}
}
第四种:利用私有的内部工厂类(线程安全,内部类也可以换成内部接口,不过工厂类变量的作用域要改为public了。)
public class Singleton {
private Singleton(){
System.out.println("Singleton: " + System.nanoTime());
}
public static Singleton getInstance(){
return SingletonFactory.singletonInstance;
}
private static class SingletonFactory{
private static Singleton singletonInstance = new Singleton();
}
}
八、泛型中<Object>和<?>有什么区别?
List<?> list 可以赋值任何类型,但是不能添加具体的类型
List<Object> list 只能赋值List<Object>,但是可以添加任何类型 这个也可以更改其他类型 就可以看出具体区别
List<? extends Object> list 与 List<?> list没区别
九、yield和join的用法?
yield()方法
理论上,yield意味着放手,放弃,投降。一个调用yield()方法的线程告诉虚拟机它乐意让其他线程占用自己的位置。这表明该线程没有在做一些紧急的事情。注意,这仅是一个暗示,并不能保证不会产生任何影响。
Yield是一个静态的原生(native)方法
Yield告诉当前正在执行的线程把运行机会交给线程池中拥有相同优先级的线程。
Yield不能保证使得当前正在运行的线程迅速转换到可运行的状态
它仅能使一个线程从运行状态转到可运行状态,而不是等待或阻塞状态
join()方法
线程实例的方法join()方法可以使得一个线程在另一个线程结束后再执行。如果join()方法在一个线程实例上调用,当前运行着的线程将阻塞直到这个线程实例完成了执行。
十、final如何使用?
1. 修饰基础数据成员的final。被修饰的成员变量不可改变;
2. 修饰类或对象的引用的final
3. 修饰方法的final
4. 修饰类的final
当一个类被修饰为final时,它的含义很明确,就是不允许该类被继承,也就是说,该类“绝后”了,任何继承它的操作都会以编译错误告终。这也凸显出Java用final而不用const作为标识符的理由。
十一、 final、finally、finalize的区别?
final—修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为abstract的,又被声明为final的。将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为final的方法也同样只能使用,不能重载。
finally—再异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话)。
finalize—方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。
十二、 Java中byte占多少字节?
类型 存储要求 范围(包含) 默认值 包装类
整 int 4字节(32位) -231~ 231-1 0 Integer
数 short 2字节(16位) -215~215-1 0 Short
类 long 8字节(64位) -263~263-1 0 Long
型 byte 1字节(8位) -27~27-1 0 Byte
浮点 float 4字节(32位) -3.4e+38 ~ 3.4e+38 0.0f Float
类型 double 8字节(64位) -1.7e+308 ~ 1.7e+308 0 Double
字符 char 2字节(16位) u0000~uFFFF(‘’~‘?’) ‘0’ Character
(0~216-1(65535))
布尔 boolean 1/8字节(1位) true, false FALSE Boolean
十三、OutOfmemoryErrror;permGen space.是指的Jvm内存的那块不足?设置-xmx是否可以有效解决问题,如果不行,您觉得应该怎么设置?
1. java.lang.OutOfMemoryError: Javaheap space —-JVM Heap(堆)溢出
JVM在启动的时候会自动设置JVM Heap的值,其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)不可超过物理内存。
可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置。Heap的大小是Young Generation 和Tenured Generaion 之和。
在JVM中如果98%的时间是用于GC,且可用的Heapsize 不足2%的时候将抛出此异常信息。
解决方法:手动设置JVM Heap(堆)的大小。
2. java.lang.OutOfMemoryError:PermGen space —- PermGen space溢出。
PermGen space的全称是Permanent Generation space,是指内存的永久保存区域。
为什么会内存溢出,这是由于这块内存主要是被JVM存放Class和Meta信息的,Class在被Load的时候被放入PermGen space区域,它和存放Instance的Heap区域不同,sun的 GC不会在主程序运行期对PermGen space进行清理,所以如果你的APP会载入很多CLASS的话,就很可能出现PermGen space溢出。
解决方法: 手动设置MaxPermSize大小如果要在myeclipse中启动tomcat,上述的修改就不起作用了,可如下设置:
Myeclipse->preferences->myeclipse->servers->tomcat->tomcat×.×->JDK面板中的
Optional Java VM arguments中添加:-Xms256m -Xmx512m -XX:PermSize=64M-XX:MaxPermSize=128m
3. java.lang.StackOverflowError —- 栈溢出
栈溢出了,JVM依然是采用栈式的虚拟机,这个和C和Pascal都是一样的。函数的调用过程都体现在堆栈和退栈上了。
调用构造函数的 “层”太多了,以致于把栈区溢出了。
通常来讲,一般栈区远远小于堆区的,因为函数调用过程往往不会多于上千层,而即便每个函数调用需要 1K的空间(这个大约相当于在一个C函数内声明了256个int类型的变量),那么栈区也不过是需要1MB的空间。通常栈的大小是1-2MB的。
通常递归也不要递归的层次过多,很容易溢出。
解决方法:修改程序。
十四、举例您常用的JVM内存调优的工具,聊聊您对内存调优,GC等方面的想法和感悟。
CPU调优
不要存在一直运行的线程(无限while循环),可以使用sleep休眠一段时间。这种情况普遍存在于一些pull方式消费数据的场景下,当一次pull没有拿到数据的时候建议sleep一下,再做下一次pull。
轮询的时候可以使用wait/notify机制
避免循环、正则表达式匹配、计算过多,包括使用String的format、split、replace方法(可以使用apache的commons-lang里的StringUtils对应的方法),使用正则去判断邮箱格式(有时候会造成死循环)、序列/反序列化等。
结合jvm和代码,避免产生频繁的gc,尤其是full GC
内存调优
内存的调优主要就是对jvm的调优。
合理设置各个代的大小。避免新生代设置过小(不够用,经常minor gc并进入老年代)以及过大(会产生碎片),同样也要避免Survivor设置过大和过小。
选择合适的GC策略。需要根据不同的场景选择合适的gc策略。这里需要说的是,cms并非全能的。除非特别需要再设置,毕竟cms的新生代回收策略parnew并非最快的,且cms会产生碎片。此外,G1直到jdk8的出现也并没有得到广泛应用,并不建议使用。
jvm启动参数配置-XX:+PrintGCDetails-XX:+PrintGCDateStamps -Xloggc:[log_path],以记录gc日志,便于排查问题。
IO调优
文件IO上需要注意:
考虑使用异步写入代替同步写入,可以借鉴redis的aof机制。
利用缓存,减少随机读
尽量批量写入,减少io次数和寻址
使用数据库代替文件存储
网络IO上需要注意:
和文件IO类似,使用异步IO、多路复用IO/事件驱动IO代替同步阻塞IO
批量进行网络IO,减少IO次数
使用缓存,减少对网络数据的读取
使用协程: Quasar
十五、JVM运行时分区结构?静态函数在什么区?
运行时数据区通常包括这几个部分:程序计数器(ProgramCounter Register)、Java栈(VMStack)、本地方法栈(Native Method Stack)、方法区(Method Area)、堆(Heap)。
十六,在JAVA中是否存在内存泄漏?为什么?
在Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点,首先,这些对象是可达的,即在有向图中,存在通路可以与其相连;其次,这些对象是无用的,即程序以后不会再使用这些对象。如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。
JAVA框架问题:
一、简述spring中的factorybean和beanfactory的区别?
1、 BeanFactory
BeanFactory定义了IOC容器的最基本形式,并提供了IOC容器应遵守的的最基本的接口,也就是Spring IOC所遵守的最底层和最基本的编程规范。在Spring代码中,BeanFactory只是个接口,并不是IOC容器的具体实现,但是Spring容器给出了很多种实现,如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等,都是附加了某种功能的实现。
2、FactoryBean
一般情况下,Spring通过反射机制利用<bean>的class属性指定实现类实例化Bean,在某些情况下,实例化Bean过程比较复杂,如果按照传统的方式,则需要在<bean>中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。Spring为此提供了一个org.springframework.bean.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化Bean的逻辑。
FactoryBean接口对于Spring框架来说占用重要的地位,Spring自身就提供了70多个FactoryBean的实现。它们隐藏了实例化一些复杂Bean的细节,给上层应用带来了便利。从Spring3.0开始,FactoryBean开始支持泛型,即接口声明改为FactoryBean<T>的形式
3、区别
BeanFactory是个Factory,也就是IOC容器或对象工厂,FactoryBean是个Bean。在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的。但对FactoryBean而言,这个Bean不是简单的Bean,而是一个能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似。
二、简述SpringIOC的理解;
就是由IOC容器来创建对象,不需要我们去创建,我们只要告诉ioc容器我们需求什么样的对象就可以了。
AOP都有哪几种实现方式?切面类时采用的是什么方式?
1.经典的基于代理的AOP
2.@AspectJ注解驱动的切面
3.纯POJO切面
4.注入式AspectJ切面
三、spring的单例和普通的有何区别?
四、说说mybatis和hibernate的使用场合
1 Hibernate : 标准的ORM(对象关系映射) 框架;
不要用写sql, sql 自动语句生成;
使用Hibernate对sql 进行优化,修改比较困难、
应用场景: 试用需求,变化固定中小型项目;ERP,ORM,OA
2 mybatis: 程序员自己编写sql, sql 修改,优化比较自由。
mybatis 是一个不完全的ORM 框架(部分), mybatis 存在
映射关系(输入,输出映射)
应用场景: 除了hibernate 的场景,主要应用需求项目较多的场景,
互联网项目; 敏捷开发。
希望对象的持久化对应用程序完全透明是,不适合使用mybatis
据库有移植需求或需要支持多种数据库时,不适合使用mybatis
四、用过哪些网络框架?有何体会?
HttpClient
特点
高效稳定,但是维护成本高昂,故android开发团队不愿意在维护该库而是转投更为轻便的HttpUrlConnection
五、用过哪些xml解析工具,了解他们的实现吗?
Dom4j
六、如何使用hibernate和jdbc在同一个事务中使用
七、web service如何处理事务。
WEB问题:
一、https默认端口是?
HTTPS(securelytransferring web pages)服务器,默认的端口号为443/tcp 443/udp;
二、cookie和session的区别?在客户端禁用了cookie的情况下,如何维护session
cookie 和session 的区别:
a、cookie数据存放在客户的浏览器上,session数据放在服务器上。
b、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
考虑到安全应当使用session。
c、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
考虑到减轻服务器性能方面,应当使用COOKIE。
d、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
e、所以个人建议:
将登陆信息等重要信息存放为SESSION
其他信息如果需要保留,可以放在COOKIE中
Cookie与 Session,一般认为是两个独立的东西,Session采用的是在服务器端保持状态的方案,而Cookie采用的是在客户端保持状态的方案。但为什么禁用Cookie就不能得到Session呢?因为Session是用Session ID来确定当前对话所对应的服务器Session,而Session ID是通过Cookie来传递的,禁用Cookie相当于失去了Session ID,也就得不到Session了。
假定用户关闭Cookie的情况下使用Session,其实现途径有以下几种:
1》 设置php.ini配置文件中的“session.use_trans_sid = 1”,或者编译时打开打开了“–enable-trans-sid”选项,让PHP自动跨页传递Session ID。
2》 手动通过URL传值、隐藏表单传递Session ID。
3》 用文件、数据库等形式保存Session ID,在跨页过程中手动调用。
三、常见的http的状态码,及其含义。
- 1XX Informational(信息性状态码)
- 2XX Success(成功状态码)
- 3XX Redirection(重定向状态码)
- 4XX Client Error(客户端错误状态码)
- 5XX Server Error(服务器错误状态码)
数据库知识:
oracle数据库如何清理重复数据
oracle的事务隔离级别都有哪些,和Mysql有什么区别,分别如何实现序列化?
如何对tcp服务器压力测试?
Linux命令:
ps -ef grep httpd wc -l
单元测试有哪些?有什么体会
Junit。体会就是自己新建一个测试类,可以测试部分写完的代码,不用启动服务器
设计一个程序,完成100000000个随机数的排序?
字符串 “12345678”表示为asc16进制如何表示?
逻辑题:
一家珠宝店的珠宝被盗,经查可以肯定是甲、乙、丙、丁中的某一个人所为
审讯中,甲说:“我不是罪犯。”乙说:“丁是罪犯。”丙说:“乙是罪犯。”丁说:“我不是罪犯。”经调查证实四人中只有一个人说的是真话。
根据已知条件,下列哪个判断为真?
假设甲说的是真的,那么甲不是罪犯。乙说的就是假的,他说丁是罪犯,则丁不是罪犯,而丁说的也应该是假的,丁说他不是罪犯,则他是罪犯,互相矛盾,假设不成立。假设乙说的是真的,那么丁是罪犯,甲说的应该是假的,他说我不是罪犯,则甲是罪犯,矛盾,假设不成立。假设丙说的是真的,则乙是罪犯,甲说的应该是假的,他说我不是罪犯,则甲是罪犯,矛盾,假设不成立。假设丁说的是真的,则丁不是罪犯,其他三人说的都是假的,甲说不是罪犯,则甲是罪犯,符合,乙说丁是罪犯,丁不是罪犯,符合,丙说乙是罪犯,乙不是罪犯,符合。