面向对象
1、面向对象特征?
- 封装
封装是面向对象的特征之一,是对象和类概念的主要特性。封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。 - 继承
面向对象编程 (OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。。 - 多态
多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。
1.1、多态的实现方式
实现多态,有二种方式,覆盖,重载。
- 覆盖(重写),是指子类重新定义父类的虚函数的做法。
- 重载,是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)。
2、abstract class和interface有什么区别?
- 声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。
- 接口(interface)是抽象类的变体。在接口中,所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的,没有一个有程序体。接口只可以定义static final成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。然后,它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类,它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换,instanceof 运算符可以用来决定某对象的类是否实现了接口。
3、Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?
方法的重写Overriding和重载Overloading是Java多态性的不同表现。
重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。
如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被"屏蔽"了。
如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。
4、内部类的作用?
- 内部类可以用多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独立。
- 在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或者继承同一个类。
- 创建内部类对象的时刻并不依赖于外围类对象的创建。
- 内部类并没有令人迷惑的“is-a”关系,他就是一个独立的实体。
- 内部类提供了更好的封装,除了该外围类,其他类都不能访问
5、Java的四种引用的区别
- 强引用:如果一个对象具有强引用,它就不会被垃圾回收器回收。即使当前内存空间不足,JVM也不会回收它,而是抛出 OutOfMemoryError 错误,使程序异常终止。如果想中断强引用和某个对象之间的关联,可以显式地将引用赋值为null,这样一来的话,JVM在合适的时间就会回收该对象
- 软引用:在使用软引用时,如果内存的空间足够,软引用就能继续被使用,而不会被垃圾回收器回收,只有在内存不足时,软引用才会被垃圾回收器回收。
- 弱引用:具有弱引用的对象拥有的生命周期更短暂。因为当 JVM 进行垃圾回收,一旦发现弱引用对象,无论当前内存空间是否充足,都会将弱引用回收。不过由于垃圾回收器是一个优先级较低的线程,所以并不一定能迅速发现弱引用对象
- 虚引用:顾名思义,就是形同虚设,如果一个对象仅持有虚引用,那么它相当于没有引用,在任何时候都可能被垃圾回收器回收。
6、静态变量合实例变量的区别
- 语法:静态变量前要加static来修饰,而实例变量前则不加;
- 程序运行时的区别:
- 实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量;
- 静态变量不属于某个实例对象,而是属于类,所以也称为类变量,静态变量就会被分配空间,静态变量就可以被使用了。
7、什么是匿名内部类,在什么时候调用?
- 内部类:
内部类可以是static的或者非static的,static内部类只能包含静态方法和静态类变量,只能访问外部类的静态元素,内部类可以实例化,多次使用。 - 匿名内部类:它只能使用一次,不区分static和非static。如果用到外部类的变量的话,必须是类变量或者实例变量,就是必须是类定义的变量,或者final的局部变量。匿名内部类如果是继承某个类的话是可以重写那个类的方法的,这个和普通内部类一样。
实现事件监听器的时候,用匿名内部类编码非常简洁,也容易读懂,不重复利用时使用。
8、public,private,protect权限
- public在任何情况下都可用;
- protect可在当前类,同一个包中和子孙类中使用;
- default:可在当前类和同一个包中使用
- private只能在当前类中使用
集合
1、列举java的集合和继承关系
2、Collection 和 Collections的区别。
- Collection是集合类的上级接口,继承与他的接口主要有Set 和List.
- Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。
3、Java集合框架的优点?
- 使用核心集合类降低开发成本,而非实现我们自己的集合类。
- 随着使用经过严格测试的集合框架类,代码质量会得到提高。
- 通过使用JDK附带的集合类,可以降低代码维护成本。
- 具有更强的复用性和可操作性。
4、Collection和Map的区别?
二者没有必然联系;
- Collection存储的是一组对象;
- Map是以“键值对”的形式对对象进行的管理。
5、List和Set的
- List:元素有序可重复,查找元素效率高,插入删除效率低,因为会引起其他元素位置改变,实现类有ArrayList、LinkedList、Vector。List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。
- Set:元素无序不可重复,检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 ,实现类有HashSet、TreeSet。
6、List的实现类有哪些?各自有什么特点?
- ArrayList:轻量级,运行快,查询快
- LinkedList:增删操作快
- LinkedList比ArrayList消耗更多的内存,因为LinkedList中的每个节点存储了前后节点的引用
7、ArrayList和Vector有何异同点?
- ArrayList和Vector在很多时候都很类似。
- 两者都是基于索引的,内部由一个数组支持。
- 两者维护插入的顺序,我们可以根据插入顺序来获取元素。
- ArrayList和Vector的迭代器实现都是fail-fast的。
- ArrayList和Vector两者允许null值,也可以使用索引值对元素进行随机访问。
- 以下是ArrayList和Vector的不同点。
- Vector是同步的,而ArrayList不是。然而,如果你寻求在迭代的时候对列表进行改变,你应该使用CopyOnWriteArrayList。
- ArrayList比Vector快,它因为有同步,不会过载。
- ArrayList更加通用,因为我们可以使用Collections工具类轻易地获取同步列表和只读列表。
7、Map的实现类?
- HashMap 轻量级 线程不安全的,允许key或value为null JDK1.2
- HashTable 重量级 线程安全的 不允许key或value为null JDK1.0
8、List、Map、Set三个接口,存取元素时,各有什么特点?
- List 以特定次序来持有元素,可有重复元素。
- Set 无法拥有重复元素,内部排序。
- Map 保存key-value值,value可多值。
9、HashMap和 HashTable 的区别
- HashMap是非线程安全的,HashTable是线程安全的。
- HashMap的键和值都允许有null值存在,而HashTable则不行。
-
因为线程安全的问题,HashMap效率比HashTable的要高。
10、Iterater和ListIterator之间有什么区别?
- 我们可以使用Iterator来遍历Set和List集合,而ListIterator只能遍历List
- Iterator只可以向前遍历,而LIstIterator可以双向遍历。
- ListIterator从Iterator接口继承,然后添加了一些额外的功能,比如添加一个元素、替换一个元素、获取前面或后面元素的索引位置。
11、Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?
- 使用equals()区分。
- ==是用来判断两者是否是同一对象(同一事物),而equals是用来判断是否引用同一个对象。
- set里面存放的是对象的引用,所以当两个元素只要满足了equals()时就已经指向同一个对象,也就出现了重复元素。所以应该用equals()来判断。
12、集合和数组的区别
- 数组在定义时必须定义长度,而集合在定义时不必定义长度。
- 数组在定义时必须要声明数组的数据类型,而集合不必。但是一般情况下我们都是存储统一数据类型的数据,我们可以使用泛型的写法来限制集合里面的数据类型。
异常处理
1、try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?
会执行,在return前执行。
2、运行时异常与一般异常有何异同?
异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。
3、error和exception有什么区别?
- error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。
- exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。
基本语法
1、基本数据类型有哪些?String是最基本的数据类型吗?
- 基本数据类型包括byte、int、char、long、float、double、boolean和short。
- java.lang.String类是final类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer类
1.1、是否可以继承String类?
String类是final类故不可以继承。
2、int 和 Integer 有什么区别
- Java 提供两种不同的类型:引用类型和原始类型(或内置类型)。
- Int是java的原始数据类型,Integer是java为int提供的封装类。
- Java为每个原始类型提供了封装类。
3、&和&&的区别。
&是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and)。
4、数组有没有length()这个方法? String有没有length()这个方法?
数组没有length()这个方法,有length的属性。String有有length()这个方法。
5、equals与==的区别:
- ==是判断两个变量或实例是不是指向同一个内存空间
- equals是判断两个变量或实例所指向的内存空间的值是不是相同
6、swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?
switch(expr1)中,expr1是一个整数表达式。因此传递给 switch 和 case 语句的参数应该是 int、 short、 char 或者 byte。long,string 都不能作用于swtich。
7、编程题: 用最有效率的方法算出2乘以8等於几?
2 << 3
8、Hashcode的作用,与 equal 有什么区别
同样用于鉴定2个对象是否相等的,java集合中有 list 和 set 两类,其中set不允许元素重复实现,那个这个不允许重复实现的方法,如果用 equal 去比较的话,如果存在1000个元素,你 new一个新的元素出来,需要去调用1000次 equal 去逐个和他们比较是否是同一个对象,这样会大大降低效率。hashcode实际上是返回对象的存储地址,如果这个位置上没有元素,就把元素直接存储在上面,如果这个位置上已经存在元素,这个时候才去调用equal方法与新元素进行比较,相同的话就不存了,散列到其他地址上
9、final, finally, finalize的区别。
- final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
- finally是异常处理语句结构的一部分,表示总是执行。
- finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。
10、String StringBuffer StringBuilder 的区别
- 三者在执行速度方面的比较:StringBuilder > StringBuffer > String
- String 字符串常量,不可变
- StringBuffer 字符串变量(线程安全)
- StringBuilder 字符串变量(非线程安全)
线程相关问题
1、什么是线程?
线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。程序员可以通过它进行多处理器编程,你可以使用多线程对 运算密集型任务提速。比如,如果一个线程完成一个任务要100毫秒,那么用十个线程完成改任务只需10毫秒。
2、线程和进程的区别
- 进程是表示资源分配的基本单位,又是调度运行的基本单位。
- 线程是进程中执行运算的最小单位,亦即执行处理机调度的基本单位。
- 线程的优点:
- 易于调度。
- 提高并发性。通过线程可方便有效地实现并发性。进程可创建多个线程来执行同一程序的不同部分。
- 开销少。创建线程比创建进程要快,所需开销很少。。
- 利于充分发挥多处理器的功能。通过创建多线程进程(即一个进程可具有两个或更多个线程),每个线程在一个处理器上运行,从而实现应用程序的并发性,使每个处理器都得到充分运行。
- 进程和线程的关系:
- 一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。
- 资源分配给进程,同一进程的所有线程共享该进程的所有资源。
- 处理机分给线程,即真正在处理机上运行的是线程。
- 线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。
3、创建线程的方式
比较常见的一个问题了,一般就是两种:
- 继承Thread类
- 实现Runnable接口
- 通过 Callable 和 Future 创建线程
4、Thread和Runnable俩种创建线程的方式哪种更好?
实现Runnable接口相比继承Thread类有如下优势:
- 可以避免由于Java的单继承特性而带来的局限
- 增强程序的健壮性,代码能够被多个程序共享,代码与数据是独立的
- 适合多个相同程序代码的线程区处理同一资源的情况
- 实现接口的方式比继承类的方式更灵活,也能减少程序之间的耦合度,面向接口编程也是设计模式6大原则的核心。
5、线程的几种状态
- 新建状态(New):新创建了一个线程对象。
- 就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权,此时还没有真正执行线程。
- 运行状态(Running):就绪状态的线程获取了CPU,执行run()方法。
- 阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。
- 死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
5.1、阻塞的情况分三种:
- 等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。
- 同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
- 其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
6、什么会导致线程阻塞
线程被堵塞可能是由下述五方面的原因造成的:
- 调用sleep(毫秒数),使线程进入“睡眠”状态。在规定的时间内,这个线程是不会运行的。
- 用suspend()暂停了线程的执行。除非线程收到resume()消息,否则不会返回“可运行”状态。
- 用wait()暂停了线程的执行。除非线程收到nofify()或者notifyAll()消息,否则不会变成“可运行”。
- 线程正在等候一些IO(输入输出)操作完成。
- 线程试图调用另一个对象的“同步”方法,但那个对象处于锁定状态,暂时无法使用。
7、启动一个线程是用run()还是start()?
启动一个线程是调用start()方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM调度并执行。这并不意味着线程就会立即运行。run()方法可以产生必须退出的标志来停止一个线程。
8、当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
不能,一个对象的一个synchronized方法只能由一个线程访问。
9、start()方法和run()方法的区别
只有调用了start()方法,才会表现出多线程的特性,不同线程的run()方法里面的代码交替执行。如果只是调用run()方法,那么代码还是同步执行的,必须等待一个线程的run()方法里面的代码全部执行完毕之后,另外一个线程才可以执行其run()方法里面的代码。
10、sleep方法和wait方法有什么区别
这个问题常问,sleep方法和wait方法都可以用来放弃CPU一定的时间,不同点在于如果线程持有某个对象的监视器,sleep方法不会放弃这个对象的监视器,wait方法会放弃这个对象的监视器
11、为什么wait()方法和notify()/notifyAll()方法要在同步块中被调用
这是JDK强制的,wait()方法和notify()/notifyAll()方法在调用前都必须先获得对象的锁
12、为什么wait, notify 和 notifyAll这些方法不在thread类里面?
这是个设计相关的问题,它考察的是面试者对现有系统和一些普遍存在但看起来不合理的事物的看法。回答这些问题的时候,你要说明为什么把这些方法放在 Object类里是有意义的,还有不把它放在Thread类里的原因。一个很明显的原因是JAVA提供的锁是对象级的而不是线程级的,每个对象都有锁,通 过线程获得。如果线程需要等待某些锁那么调用对象中的wait()方法就有意义了。如果wait()方法定义在Thread类中,线程正在等待的是哪个锁 就不明显了。简单的说,由于wait,notify和notifyAll都是锁级别的操作,所以把他们定义在Object类中因为锁属于对象。
13、Thread类中的yield方法有什么作用?
Yield方法可以暂停当前正在执行的线程对象,让其它有相同优先级的线程执行。它是一个静态方法而且只保证当前线程放弃CPU占用而不能保证使其它线程一定能占用CPU,执行yield()的线程有可能在进入到暂停状态后马上又被执行。
14、怎么唤醒一个阻塞的线程
如果线程是因为调用了wait()、sleep()或者join()方法而导致的阻塞,可以中断线程,并且通过抛出InterruptedException来唤醒它;如果线程遇到了IO阻塞,无能为力,因为IO是操作系统实现的,Java代码并没有办法直接接触到操作系统。
15、请说出你所知道的线程同步的方法。
- wait():使一个线程处于等待状态,并且释放所持有的对象的lock。
- sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常。
- notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
- notityAll():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。
16、Java中如何停止一个线程?
Java提供了很丰富的API但没有为停止线程提供API。JDK 1.0本来有一些像stop(), suspend() 和 resume()的控制方法但是由于潜在的死锁威胁因此在后续的JDK版本中他们被弃用了,之后Java API的设计者就没有提供一个兼容且线程安全的方法来停止一个线程。当run() 或者 call() 方法执行完的时候线程会自动结束,如果要手动结束一个线程,你可以用volatile 布尔变量来退出run()方法的循环或者是取消任务来中断线程。
17、一个线程如果出现了运行时异常会怎么样
如果这个异常没有被捕获的话,这个线程就停止执行了。另外重要的一点是:如果这个线程持有某个某个对象的监视器,那么这个对象监视器会被立即释放
18、单例模式的线程安全性
老生常谈的问题了,首先要说的是单例模式的线程安全意味着:某个类的实例在多线程环境下只会被创建一次出来。单例模式有很多种的写法,我总结一下:
(1)饿汉式单例模式的写法:线程安全
(2)懒汉式单例模式的写法:非线程安全
(3)双检锁单例模式的写法:线程安全
19、Runnable接口和Callable接口的区别
- Runnable接口中的run()方法的返回值是void,它做的事情只是纯粹地去执行run()方法中的代码而已;
- Callable接口中的call()方法是有返回值的,是一个泛型,和Future、FutureTask配合可以用来获取异步执行的结果。这其实是很有用的一个特性,因为多线程相比单线程更难、更复杂的一个重要原因就是因为多线程充满着未知性,某条线程是否执行了?某条线程执行了多久?某条线程执行的时候我们期望的数据是否已经赋值完毕?无法得知,我们能做的只是等待这条多线程的任务执行完毕而已。而Callable+Future/FutureTask却可以获取多线程运行的结果,可以在等待时间太长没获取到需要的数据的情况下取消该线程的任务,真的是非常有用。
20、多线程有什么用?
- 发挥多核CPU的优势
随着工业的进步,现在的笔记本、台式机乃至商用的应用服务器至少也都是双核的,4核、8核甚至16核的也都不少见,如果是单线程的程序,那么在双核CPU上就浪费了50%,在4核CPU上就浪费了75%。单核CPU上所谓的"多线程"那是假的多线程,同一时间处理器只会处理一段逻辑,只不过线程之间切换得比较快,看着像多个线程"同时"运行罢了。多核CPU上的多线程才是真正的多线程,它能让你的多段逻辑同时工作,多线程,可以真正发挥出多核CPU的优势来,达到充分利用CPU的目的。 - 防止阻塞
从程序运行效率的角度来看,单核CPU不但不会发挥出多线程的优势,反而会因为在单核CPU上运行多线程导致线程上下文的切换,而降低程序整体的效率。但是单核CPU我们还是要应用多线程,就是为了防止阻塞。试想,如果单核CPU使用单线程,那么只要这个线程阻塞了,比方说远程读取某个数据吧,对端迟迟未返回又没有设置超时时间,那么你的整个程序在数据返回回来之前就停止运行了。多线程可以防止这个问题,多条线程同时运行,哪怕一条线程的代码执行读取数据阻塞,也不会影响其它任务的执行。 - 便于建模
这是另外一个没有这么明显的优点了。假设有一个大的任务A,单线程编程,那么就要考虑很多,建立整个程序模型比较麻烦。但是如果把这个大的任务A分解成几个小任务,任务B、任务C、任务D,分别建立程序模型,并通过多线程分别运行这几个任务,那就简单很多了。
21、为什么要使用线程池
避免频繁地创建和销毁线程,达到线程对象的重用。另外,使用线程池还可以根据项目灵活地控制并发的数目。
22、关于线程池可参考这篇
其他
1、GC是什么? 为什么要有GC?
GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。
2、GC内存泄露在什么情况下回出现?怎么解决?
- 查询数据库没有关闭游标
- 构造Adapter时,没有使用缓存的 convertView
- Bitmap对象不在使用时调用recycle()释放内存
- 不用的对象没有及时释放对象的引用
3、Dvm是什么
Android 运行环境主要指的虚拟机技术——Dalvik。Android中的所有Java程序都是运行在Dalvik VM上的。Android上的每个程序都有自己的线程,DVM只执行.dex的Dalvik executable 文件。每个Android应用在底层都对应有一个独立的DVM实例并在其解释下执行。
4、Serializable 和 Parcelable 的区别?
- 在使用内存的时候,Parcelable 类比 Serializable 性能高,所以推荐使用 Parcelable 类。
- Serializable 在序列化的时候会产生大量的临时变量,从而引起频繁的 GC。
- Parcelable 不能使用在要将数据存储在磁盘上的情况。尽管 Serializable 效率低点,但在这种情况下,还是建 议你用 Serializable 。
实现:
1 Serializable 的实现,只需要继承 Serializable 即可。这只是给对象打了一个标记,系统会自动将其序列化。
2 Parcelabel 的实现,需要在类中添加一个静态成员变量 CREATOR,这个变量需要继承 Parcelable.Creator 接 口。
4.1、Serializable序列化过程
1). 实现序列化 Serializable
2). 属性私有化,并提供get,set方法
3). 提供无参构造
4). 属性名必须与json串中属性名保持一致 (因为Gson解析json串底层用到了Java的反射原理)
5、说说java的反射机制原理以及应用场合?
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
类对象: 封装了类的描述信息的对象,类加载的产物,由jvm创建java.lang.Class
应用场景: Gson 序列化反序列化
获取类对象的方式:
1.类名.class 2. 类的对象.getClass() 3. Class.forName("包名.类名")
6、访问网络如何加密
- 对称加密(DES,AES)和非对称(RSA公钥与私钥)。(支付宝里的商户的公钥和私钥)
- MD5(算法)
- Base64
7、Http和Https有什么区别
- http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
- http的连接很简单,是无状态的,...
- HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议 要比http协议安全
8、GET和POST区别
- 参数:GET参数是直接放到URL上面,通过'?'和'&'链接参数。POST是将参数放到了body体中进行数据传输。这又证明了两点:一、GET请求没有body二、相对来说POST安全一些,只是针对用户而言。但是两者实际上都是不安全的,参数不加密的话随便的抓包软件都能轻松搞定。
- 数据量:GET有大小限制,传统IE中URL的最大可用长度为2048字节,其他浏览器对URL长度限制实现上有所不同。POST请求没有限制。
- GET使用Request.QueryString来取得变量的值。POST方式通过Request.Form来获取变量的值。(这个我不是很理解,望小伙伴给讲解)。
9、字符串“abcde”通过写一个函数不让调用第三方的字符串,实现一个字符串倒序,比如字符串“abcde” 变成“edcba”
String src = "ABCDEF ";
String dst = new StringBuffer(src).reverse().toString();
网友评论