从2月春招启动,到3月两场笔试筛选之后,目前由我内推的同学中已有近300人进入面试流程。为了大家面试更加顺利,我将当初自己实习、校招时的所有试题以及当时整理的所有题目答案写了出来,方便大家做一下参考。
面试题目是我在每一场面试之后整理的,试题答案一部分是我面试时的回答,一部分是面试结束、查阅相关资料后的补充。当初做下笔记是为了在校招、实习的时候更好地准备下一场面试,当时对我知识面的回顾、复习确实有比较大的作用,也希望能够帮助到大家。
还没有进百度笔面试交流群的同学,可以加最下方的微信账号,邀你进群~
通过反射获取类有3种方式
Class c1=Class.forName("csdn.Student");
//2、第二种方式-->先创建对象,再用对象调用getClass()方法,即实例对象.getClass().返回运行时类。
//任何一个java对象都有getClass()方法
Student s=new Student();
Class c2 = s.getClass();
//3、第三种方式-->类名.class。返回Class的对象。(每个类都有class属性)
Class c3=Student.class
其他获取:
getConstructor获取构造方法
对象通过.属性或方法获取类相应的属性或方法
优点:使用了代理模式
静态代理:代理类与被代理类都实现同一个接口,代理类将被代理类组合为自己的属性。在调用接口方法时,添加额外的功能
优点:可以做到在不修改目标对象的功能前提下,对目标功能扩展.
缺点:每个代理类只能代理一个被代理类。如果开发中存在上千个类需要代理,这种方式就不适合
动态代理可以动态创建一个类的代理类,并且代理任一类型的类(如可以通过JDK动态生成代理类,也可以采用字节码操作动态创建代理类)
动态代理核心是Proxy和InvocationHandler类,底层通过生成代理字节码文件实现代理
toString()返回该对象的字符串表示
equals(Object obj)指示某个其他对象是否与此对象“相等”。
wait()导致当前的线程等待
notifyAll()唤醒在此对象监视器上等待的所有线程
notify()唤醒在此对象监视器上等待的单个线程
hashCode()返回该对象的哈希码值
getClass()返回一个对象的运行时类
finalize()当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。(子类重写该方法,可以配置资源或执行清除操作)
clone()创建并返回此对象的一个副本(可以克隆自定义类型)
浅拷贝是按位拷贝对象,它会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值;如果属性是内存地址(引用类型),拷贝的就是内存地址,因此如果其中一个对象改变了这个地址,就会影响到另一个对象。
==号是运算符,equals是object对象的方法;
对于==来说,如果比较的是基本数据类型,那么==号比较的就是值;如果是引用类型,比较的就是地址。
代码更加简洁
原子性:提供互斥访问,同一时刻只能有一个线程对数据进行操作,(atomic,synchronized);
可见性:一个线程对主内存的修改可以及时地被其他线程看到,(synchronized,volatile);
有序性:程序执行的顺序按照代码的先后顺序执行(一个线程观察其他线程中的指令执行顺序,由于指令重排序,该观察结果一般杂乱无序)
synchronize修饰方法、修饰代码块、volatile修饰变量、使用Lock类(调用其lock、unlock方法)
synchronized具有同步功能,(是一种互斥锁,锁的是对象,)。
(synchronized可以用来修饰代码块和方法。
synchronized可以保证原子性,有序性,可见性。)
(修饰静态方法时,锁对象是字节码文件对象(.class文件))
区别1:synchronized修饰静态方法,结果是同步的。因为当修饰静态方法时,锁对象是class字节码文件对象,而两个对象是同一个class文件,所以使用的是一个锁。
synchronized修饰普通方法时,锁对象是this对象。
底层实现不同。
synchronized修饰实例方法或静态方法都是通过标识ACC_SYNCHRONIZED实现同步。而同步代码块是是采用monitorenter、monitorexit两个指令来实现同步。
synchronized修饰方法
synchronized修饰方法,同步是隐式的。当某个线程要访问某个方法的时候,会检查是否有ACC_SYNCHRONIZED,如有,则需要先获取监视器锁,然后才开始执行方法。方法执行之后再释放监视器锁。在线程执行方法的时候,有另外线程也来请求执行该方***因为无法获取监视器锁而被阻断。
同步代码块
同步代码块是是采用monitorenter、monitorexit两个指令来实现同步。在执行monitorenter指令时,首先要尝试获取对象的锁。如果这个对象没被锁定,或者当前线程已经拥有了那个对象的锁,把锁的计数器加1,相应的,在执行monitorexit指令时会将锁计数器减1,当计数器为0的时候,锁就会被释放。如果获取对象锁失败,那当前线程就要阻塞等待。直到对象锁被另外一个线程释放为止。
monitorenter、monitorexit这两个字节码指令都需要一个reference类型的参数来明确要锁定和解锁的对象。上例中使用了synchronized (this)。
百度APP技术中台部门打电话过来面试的时候,我已经拿到了AIG地图部门的offer,面试官问了我下面几个比较基础的问题后,问我愿不愿意到他们团队,我选择留在了地图部门。
问:java 六大原则
单一原则:一个类只做一件事,实现高内聚
依赖倒置原则:高层组件应该依赖于抽象而不是具体,即面向接口编程
里式替换原则:凡是使用父类的地方,都可以使用子类替换,并且原功能没有发生改变
迪米特原则:一个类应该尽量封装自己(private)
接口隔离原则:一个接口尽可能地功能单一化,不要承担太多的责任
基本数据类型及其字节数、占用位数、数值长度(范围)
类型 | 字节 | 占用位数 | 数值长度 |
byte | 1 | 8 | (-2的7次方到2的7次方-1) |
short | 2 | 16 | (-2的15次方到2的15次方-1) |
int | 4 | 32 | (-2的31次方到2的31次方-1) |
long | 8 | 64 | (-2的63次方到2的63次方-1) |
float | 4 | 32 | (2的-149次方 ~ 2的128次方-1) |
double | 8 | 64 | (4.9000000e-324 ~ 1.797693e+308 )(2的-1074次方 , 2的1024次方-1) |
char | 2 | 16 | |
boolean | 1 | 8 | |
为什么int的最大范围要减一?
符号位占一。
例如:0111 1111 1111 1111
这个数就是最大数(有符号位):
1+2^1+2^2+...+2^14
异常分为哪些类型?
error:程序无法处理的错误,表示运行应用程序中较严重问题。比如:OutOfMemoryError
Integer是int的包装类,int则是java的一种基本数据类型
Integer的默认值是null,int的默认值是0
Integer变量必须实例化后才能使用,而int变量不需要
Java反射就是在运行状态中,对于任意一个类,通过getclass或forname,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。
广播的注册有两种形式,一种是在应用程序的代码上注册,
注册:registerReceiver(receiver,filter)
取消注册:unregisterReceiver(receiver)
另一种形式则是在注册表androidmanifest.xml当中注册,
<receiver>
<intent-filter>
<action android:name = "android.intent.action.PICK"/>
</intent-filter>
</receiver>
两种注册广播形式的区别/优缺点主要是,
①前一种为非常驻型注册,跟随生命周期变化,及Activity不可见时取消注册。不过当BroadcastReceiver(receiver)需要更新UI的时候,一般会采用该注册广播的方法;
实现异步操作的库;
好处:随着程序逻辑变得越来越复杂,它依然能够保持简洁(支持函数式编程,把函数作为参数)
基于观察者模式(将观察者和被观察者分离开,例子:假设A是连载小说,B是读者,读者订阅了连载小说,当小说出现了新的连载的时候,会推送给读者。读者不用时刻盯着小说连载,而小说有了新的连载会主动推送给读者。这就是观察者模式)
步骤:
-
创建被观察者对象,二、创建观察者对象,三创建订阅关系
全部评论
(1) 回帖