java synchronizee关键字为什么jdk1.5后效率提高了

java面试(2)
1、JDK和JRE的区别以及跨平台的原理
&&& JRE:java的原型环境,包括java虚拟机和java程序所需的核心类库,JVM+类库
&&& JDK:java的开发工具包,包含java的开发工具,编译工具、打包工具等
&&&&&&& JDK=JRE+Java的开发工具
&&& 跨平台的原理:实现跨平台需要依赖jva的虚拟机jVM,不同平台使用不同的java虚拟机,实现一次编译处处运行
2、java的关键字和标识符及其特点
&&& java关键字:被java语言赋予特定含义的单词
&&& 特点:组成关键字的字母全部小写,常见的代码编辑器对关键会有特殊的颜色标记
&&& 标识符:给类、方法、变量等起名字
&&& 特点:由字符、下划线、美元符$组成,不能以数字开头、不能是java的关键字
3、java的数据类型和分类
&&&&&&& 分类:
&&&&&&&&&&& 基本数据类型:四类八种
&&&&&&& &&& 引用数据类型:类、接口、数组
4、java的运算符种类
4.1、算术运算符
&&&&&&& 对常量和变量进行操作的运算符
&&&&&&& 字符参与运算:其实就是该字符对应的数值操作
&&& &&& 字符串和其它数据类型的数组做拼接,结果是字符串类型
4.2、赋值运算符
4.3、关系运算符
&&&&&&& 关系运算符的结果都是boolean性,要么是true要么是false
4.4、逻辑运算符
4.5、三元运算符
5、&&和&的区别以及|和||的区别:
&&和&的区别
&&&&&&& &&和&都是逻辑与运算,都是要求运算符两侧的表达式为true,结果才为true。&& 具有短路效果,当左侧的表达式结果为false时,右侧将不再执行。&是无论左侧是&&&& 否为false,将继续执行下去。&还可以用于按位与
|和||的区别
&&&&&&& 最终的结果是一样的,||具有短路效果,左侧为true,右边将不再执行,|是无论 左边是false还是true,右边都会执行
6、键盘录入的对象创建
&&& Scannersc = new Scanner(System.in);
&&& 再调用sc.nextInt()的等函数
&&& 数组是存储同一种数据类型多个元素的容器
两种初始化方式:
&&&&&&& 初始化:就是为数组中的数组元素分配内存空间,并为每个数组元素赋值
&&&&&&& 动态初始化:初始化时只指定数组长度、并有系统为数组分配初始化值
&&&&&&& 静态初始化:初始化指定每个数组元素的初始化值,有系统决定数组长度
8、JVM的内存划分
&&& 栈:存储局部变量
&&& 堆:存储new出来的东西
&&& 方法区:
&&& 本地方法区:与系统相关
&&& 寄存器:给CPU使用
9、方法重载和方法重写
&&& 方法重载:在同一个类中,允许多个同名方法,只要他们的参数个数或者参数类型不同即可,方法名相同,参数类型不同,分为参数个数不同,参数类型不同,与返回值无关
&&& 方法重写:存在于子父类之间,子类的方法的权限修饰符权限大于或等于父类的,方法名和参数类型完全相同,与返回值有关
10、方法中的参数传递
&&& 形参为基本数据类型:形参的改变不影响实际参数
&&& 形参为引用数据类型:形参的改变会影响实际参数
11、面向对象的特征
&&&&&&& 将客观事物封装成抽象的类,一个类就是一个封装了数据和操作的这些数据的代码&&&&&&& 的逻辑实体
&&&&&&& 可以让其他类型的得对象获得另一个类型的对象的属性的方法。它可以使用&&&&&&&&& 现有类的所有功能,并在无需重写原来类的情况下对这些功能进行扩展
&&&&&&& 父类或父接口引用指向的子类对象
12、面向对象的特点
&&& 更符合我们的思考方式,将事情将给其他人去做,将复杂事情简单化,我们从执行者变&&& 成了指挥者角色
13、类与对象的关系
&&& 类:是一组相关属性和行为的集合
&&& 对象:是该类事物的具体体现
14、String、StringBuffer、StringBuilder
&&& String:字符串常量,字符串长度不变,是被声明程final的,一次赋值不可改变
&&& StringBuffer:字符串变量,线程安全,如果需要频繁的对字符串内容进行修改,处于效率考虑最好使用StringBuffer。StringBuffer,在任意时间点上都包含特定的字符序列,但通过方法调用改变长度和内容
&&& StringBuilder:字符串变量,非线程安全。StringBuilder对象被当做一个包含字符序列的变长数组,是在JDK1.5后新增的,可用于字符串缓冲区被单线程使用时使用
15、String对象的两种创建方式
&&& 通过构造方法创建字符串对象是在堆内存
&&& 直接赋值方式创建对象是方法区的常量池
16、String是基本的数据类型
&&& String类是final类型,因此这个类不能被继承,不能修改。为了提高效率节省空间,使用StringBuilder类
17、GC是什么?为什么要用GC
&&& GC是垃圾回收的意思,内存处理是编程人员容易出现的问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,java提供的GC功能可以自动检测对象是否超过作用域从而达到自动回收的目的,java语言没有提供释放已分配内存的显示操作方法。
18、java中有几种类型的流
&&& 字节输入流:InputStream 字节输出流:OutputStream
&&& 字符输入流:Reader&&&&& 字符输出流:Writer
19、什么是java序列化,如何实现java序列化
&&& java对象的序列化是指将一个java对象写入IO流中,于此对应的是,对象的反序列化则是从IO流中恢复的Java对象。如果要让某个对象支持反序列化机制,必须让它的类是可序列化,则需要实现Serializable接口或者Externalizable接口
20、对象在序列化时不想给一个字段的数据保存到硬盘上
&&& 使用transient关键字
21、IO中的适配器模式
&&& 适配器模式:讲一个累的接口转换成客户希望的另一个接口,使得原本由于接口不兼容而不能一起工作的哪些类可以一起工作在java IO中。
&&& BufferedReaderbr = new BufferedReader(new InputStreamReader(is2,&utf8&));
&&&&&&& (将字节流接口,转换成字符流接口)
&&& br.readLine();
&&& 因为要逐行解析字符串, 我们需要使用字符流,对文件内容进行处理, 所以使用Reader输入流下面的BufferedReader,BufferedReader并不能直接处理文件,它需要传入一个Reader类型的参数,Reader下面能处理文件的类:InputStreamReader,以及其子类FileReader,这2个类都需要一个InputStream来读取文件中的内容并转换, 这2个类其实就是适配器, 可以把字节流转换成字符流, 然后使用Reader来解析其中的内容
22、IO中的装饰模式
&&& 装饰模式就是对一个类进行装饰,增强其方法行为,在装饰模式中,作为原来的这个类的使用者应该感受不到装饰前和装饰后的不同。装饰模式就是对原有功能的扩展。
22、适配器模式和装饰模式的总结
&&& 适配器模式主要是将一个接口转变成另一个接口,它的目的是通过改变接口来达到重复使用的目的。装饰模式则是不是改变被装饰对象的接口,而是保持原来的接口,但是增强了元有对象的功能,或改变原有对象的方法而提高性能
23、同步和异步、阻塞和非阻塞
&&& 同步:当一个同步调用发出后,调用者要一直等待返回消息通知后,才能进行后续执行
&&& 异步:当一个异步过程调用发出后,调用者不能立刻得到返回消息。在调用结束后,通过消息回调来通知调用者是否成功
&&& 阻塞:阻塞调用是指调用结果返回之前,当前线程会被挂起,一直处于等待消息通知,不能够执行其他业务,函数只有在得到结果后才会返回
&&& 非阻塞:非阻塞和阻塞的概念相对应,指再不能立刻得到借过钱,该函数不会阻塞当前线程,而会立刻返回
&&& 同步和异步的重点在于消息通知的方式,也就是调用结果通知的方式
&&& 阻塞和非阻塞的重点是当前线程等待消息返回的行为
&&& 分类:同步阻塞、同步非阻塞、异步阻塞、异步非阻塞
24、进程和线程的区别
&&& 进程是正在进行中的程序。线程其实就是进程中一个程序执行控制单元,一条执行路径。进程负责的是应用程序的空间的标示。
&&& 一个进程至少有一个线程在运行,当一个进程中出现多个线程时,这个应用程序就是多线程应用程序,每个线程在栈区都有自己的执行空间,自己的方法区、自己的变量。
25、线程的运行
&&& start方法,作用1、启动了线程,2)、让jvm调用了run方法
26、创建线程的方式
&&& 1)、继承Thread,由子类重写run方法,由run方法体来完后曾线程需要做的事
&&& 2)、实现了Runnable接口,由run方法体来完后曾线程需要做的事
&&& 3)、通过Callable和FutrueTask创建线程。创建Callable的实现类,实现call()方法,该call()方法作为线程执行体,并有返回值
&&& 创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。
27、多线程安全问题
&&& 当一个线程执行多条语句时,并运算同一个数据时,在执行过程中,其他线程参与进来,并操作这个数据,导致了错误数据的产生
&&& 涉及到两个因素
&&&&&&& 1、多个线程在操作共享数据
&&&&&&& 2、有多条数据对共享数据进行运算
&&& 解决方案:
&&&&&&& 只要将操作共享数据的语句在某一个时段让一个线程执行完,在执行过程中,其他线程不能进来执行就可以解决--------使用同步代码块
28、同步的好处与弊端
&&& 好处是解决了线程安全问题,弊端是相对降低性能,因为判断锁需要资源,产生了死锁
&&& 前提:必须有两个及以上的线程才需要同步,多个线程必须保证是同一个锁
29、同步代码块和同步函数的区别
&&& 同步代码块使用的锁可以是任意对象
&&& 同步函数使用的锁是this,静态同步函数的锁是该类的字节码文件对象
&&& 在一个类中只有一个同步,可以使用同步函数。如果有多同步,必须使用同步代码块,来确定不同的锁。同步代码块相对灵活一些
30、请写一个延迟加载的单例模式?写懒汉式;当出现多线程访问时怎么解决?加同步,解决安全问题;效率高吗?不高;怎样解决?通过双重判断的形式解决。
//懒汉式:延迟加载方式。
当多线程访问懒汉式时,因为懒汉式的方法内对共性数据进行多条语句的操作。所以容易出现线程安全问题。为了解决,加入同步机制,解决安全问题。但是却带来了效率降低。
为了效率问题,通过双重判断的形式解决。
class Single{
&&& privatestatic Single s =
&&& privateSingle(){}
&&& publicstatic Single getInstance(){ //锁是谁?字节码文件对象;
&&&&&&& if(s== null){
&&&&&&&&&&& synchronized(Single.class){
&&&&&&&&&&&&&&& if(s== null)
&&&&&&&&&&&&&&&&&&& s= new Single();
&&&&&&&&&&& }
31、等待唤醒机制
&&& wait:将同步中的线程处于冻结状态。释放了执行权,释放了资格,同时将线程对象存在线程池中
&&& notify:唤醒线程池中的某一个等待线程
&&& notifyAlll:唤醒的是线程池中的所有线程
32、sleep和wait的区别
&&& wait:可以指定时间也可以不指定时间,不指定时间,只能由对应的notify或者notifyall来唤醒
&&& sleep:必须指定时间,时间到自动从冻结状态转成运行状态(临时阻塞状态)
&&& wait:线程会释放执行权,而且线程会释放锁
&&& sleep:线程会释放执行权,但不释放锁
33、线程死锁的出现和解决办法
&&& 当线程任务出现了多个同步(多个锁)时,如果同步嵌套了其他的同步,这时容易引发一种现象:线程出现无限等待,都在等待对方的执行结束
&&& 解决方案:线程按照一定的顺序加锁,按照同一顺序访问对象,避免事务中用户的交互,保持事务处于一个批处理,死锁检测
34、lock和synchronize的区别
&&& lock不是java内置的,synchronize是java的关键字,lock是一个类,通过这个类可以实现同步访问
&&& Lock和Synchronize的最大不同:采用Synchronize不需要用户去手动加锁,当Synchronize方法或者代码块执行完成后,系统会自动让线程释放对锁的占用,而lock则必须要用户手动释放锁,如果没有自动释放锁,会出现死锁的现象
35、启动一个线程是run()还是start()?它们的区别?
&&& 启动一个线程是start()
&&& 区别:
&&&&&&& start: 启动线程,并调用线程中的run()方法
&&&&&&& run& : 执行该线程对象要执行的任务
36、单例设计模式
&&& 两种方式
A:饿汉式:当类加载时就创建对象
&&& &&& class Student{
&&& &&& &&& privateStudent(){}
&&&&&&& &&& private static final Student s = newStudent();
&&& &&& &&& publicstatic Student getInstance(){
&&&&&&& &&& &&&
&&& &&& &&& }
B:懒汉式 当使用的时候,才去创建对象
&&&&&&& classStudent{
&&&&&&&&&&& privateStudent(){}
&&&&&&&&&&& privatestatic final Student s =
&&&&&&&&&&& publicstatic Student getInstance(){
&&&&&&&&&&&&&&& if(s==null){
&&&&&&&&&&&&&&&&&&& //线程1进来了,线程2就进来了
&&&&&&&&&&&&&&&&&&& s= new Student();
&&&&&&&&&&&&&&& }
&&&&&&&&&&&&&&&
&&&&&&&&&&& }
饿汉式和懒汉式的区别
&&&&&&& 饿汉式是类一加载就创建好对象,
&&&&&&& 懒汉式是类加载进内存,对象还没有存在,只有调用getInstance()方法才创建对象
&&&&&&& 懒汉式是延迟加载,如果多个线程同时操作懒汉式就可以出现线程安全问题,
&&&&&&& 开发中常使用饿汉式,因为饿汉式安全。
37、Java中创建(实例化)对象的五种方式
&&& 1、用new语句创建对象,这是最常见的创建对象的方法。
&&& 2、通过工厂方法返回对象,如:String str = String.valueOf(23);
&&& 3、运用反射手段,调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()&&&& 实例方法。如:Object obj =Class.forName(&java.lang.Object&).newInstance();
&&& 4、调用对象的clone()方法。
&&& 5、通过I/O流(包括反序列化),如运用反序列化手段,调用java.io.ObjectInputStream&&&& 对象的 readObject()方法。
&&& 程序运行过程中的不正常现象叫做异常
&&& 异常的根类是Throwable
&&&&&&& |--Error:重大问题,处理不了,例如JVM内存溢出&&
&&&&&&& |--Exception:一般性错误,需要我们编写代码进行处理
&&& &&&&&&&
39、异常的分类:
&&& 编译时异常
&&&&&&&&&&& 在编译时,如果没有处理,编译失败
&&& 运行时异常
&&&&&&&&&&& 在编译时,不需要处理,编译器不检查
&&&&&&&&&&& 该异常的发生,减一不处理,让程序停止,需要对代码进行修正
40、java中三种常见内存溢出错误的处理方法
&&& jvm管理的内存大致包括三种不同类型的内存区域:Permanent Generation space(永久保存区域)、Heapspace(堆区域)、Java Stacks(Java栈)。
第一种OutOfMemoryError: PermGen space
&&&&&&& 原因是:程序中使用了大量的jar或class,使java虚拟机装载类的空间不够&&&
&&&&&&& 解决方案:
&&&&&&&&&&& 1、增加java虚拟机中的XX:PermSize和XX:MaxPermSize参数的大小,其中&&&&&&&& XX:PermSize是初始永久保存区域大 小,XX:MaxPermSize是最大永久保存区域大小。
&&&&&&&&&&& 2、清理应用程序中web-inf/lib下的jar,如果tomcat部署了多个应用,很多&&&&&&&&&& 应用都使用了相同的jar,可以将共同的jar移到tomcat共同的lib下,减少类的重&&&& 复加载。
第二种OutOfMemoryError:& Java heap space
&&&&&&& 原因是java虚拟机创建的对象太多,在进行垃圾回收之间,虚拟机分配的到堆内&&&& 存空间已经用满了,与Heapspace有关
&&& 解决方案:
&&&&&&& 1、检查程序,看是否有死循环或不必要地重复创建大量对象。找到原因后,修改 程序和算法。
&&&&&&& 2、增加Java虚拟机中Xms(初始堆大小)和Xmx(最大堆大小)参数的大小。
第三种OutOfMemoryError:unable to create new native thread
&&&&&&& 因为JVM已经被系统分配了大量的内存,并且它至少要占用可用内存的一半
&&&&&&& 要想创建更多的线程,你必须减少分配给JVM的最大内存
41、final、finally、finalize区别
&&& final是最终的意思,可以用于修饰类、成员变量、成员方法
&&&&&&& 它修饰的类不能被继承,修饰的变量是常量,修饰方法不能被重写
&&& finally:是一场处理里面的关键字
&&&&&&& 它其中的代码永远会被执行,特殊情况:在执行前jvm退出
&&& finalize是Object类中的一个方法
&&&&&&& 它用于垃圾回收器调用方式
42、什么是锁?锁的作用是什么?
&&& 锁就是对象
&&& 锁的作用是保证线程同步,解决线程安全问题。
&&& 持有锁的线程可以在同步中执行,没有锁的线程即使获得cpu执行权,也进不去。
43、什么是ThreadLocal类,怎么使用它?
&&& ThreadLocal类提供了线程局部 (thread-local) 变量。是一个线程级别的局部变量,并非“本地线程”。
&&& ThreadLocal为每个使用该变量的线程,提供了一个独立的变量副本,每个线程修改副本时不影响其它线程对象的副本
&&& 下面是线程局部变量(ThreadLocal variables)的关键点:
&&&&&&& 一个线程局部变量(ThreadLocal variables)为每个线程方便地提供了一个单独的变量。
&&&&&& ThreadLocal实例通常作为静态的私有的(private static)字段出现在一个类中,这个类用来关联一个线程。
&&&&&&& 当多个线程访问 ThreadLocal 实例时,每个线程维护 ThreadLocal 提供的独立的变量副本。
&&&&&&& 常用的使用可在 DAO 模式中见到,当 DAO 类作为一个单例类时,
&&&&&&& 数据库链接(connection)被每一个线程独立的维护,互不影响。(基于线程的单例)
44、集合和数组的区别
&&& 数组的长度是固定的,而集合长度是可变的
&&& 数组值可以存储对象,还可以存储基本数据类型;而集合只能够只能存储对象
&&& 数组存储的数据类型是固定的,而集合存储的数据类型不固定
45、HashSet是如何保证元素唯一性的呢?
&&& 如果两元素的hashCode值不同,则不会调用equals方法
&&& 如果两元素的hashCode值相同,则继续判断equals是否返回true;
&&& hashCode和equals方法虽然定义在自定义对象类里面,但不是我们手动调用而是往&&&&&&&&&& HashSet集合里面存储元素的时候,集合底层自己调用hashCode和equals它自己&&&&& 拿对象去判断,自己判断两元素是否是同一个元素。
&&& Map:顶层接口,该集合存储的是键值对,而且键是唯一的,Map和Set很像,Set集合底层就&& 是使用了Map集合。
&&& Map集合没有迭代器,要取出元素必须先将Map集合转换成Set集合才能遍历元素
&&& && |---&HashTable(JDK1.0):
&&&&&&& 底层是哈希表数据结构;
&&&&&&& 不可以使用null键和null值;
&&&&&&& 用作键的对象必须实现hashCode和equals方法来保证键的唯一性
&&&&&&& 线程同步,效率低
&&& && |---&HashMap(JDK1.2):
&&&&&&& 底层是哈希表数据结构;
&&&&&&& 允许使用null键和null值;
&&&&&&& 线程不同步,效率高;
&&&&&&& 保证元素唯一性的:
&&&&&&&&&&& &原理:先判断元素的hashCode值是否相同,再判断两元素的equals方法是&&&& 否为true
&&&&&&& &(往HashSet里面存的自定义元素要复写hashCode和equals方法,以保证元素的&&& 唯一性!)
47、LisIterator、Comparable、Comparator、Collections和Arrays
&&& LisIterator:系列表迭代器,允许程序员按任一方向遍历列表、迭代期间修改列表&&&&&& Comparable:此接口强行对实现它每个类的对象进行整体自然排序。使元素具备比较性
&&& Comparator:强行对某个对象collection进行整体排序的比较函数,使集合具备比较性
&&& Collections:此类完全由在 collection 上进行操作或返回 collection 的静态方法组成。
&&& Arrays:此类包含用来操作数组(比如排序和搜索)的各种静态方法
48、Map集合和Collection集合的区别?
&&& &&& Map中一次存储是键值对。
&&& &&& Collection中一次存储是单个元素。
&&& &&& Map的存储使用的put方法。
&&& &&& Collection存储使用的是add方法。
&&& &&& Map集合没有迭代器,Map的取出,是将Map转成Set,在使用迭代器取出。
&&& &&& Collection取出,使用就是迭代器。
&&& &&& 如果对象很多,必须使用集合存储。
&&& &&& 如果元素存在着映射关系,可以优先考虑使用Map存储或者用数组,
&&& &&& 如果没有映射关系,可以使用Collection存储。
49、IO流常用基类方法摘要:
&&&&&&& **字节写入流:OutputStream:
&&&&&&&&&&& voidclose() 关闭此输出流并释放与此流有关的所有系统资源。
&&&&&&&&&&& voidflush()刷新此输出流并强制写出所有缓冲的输出字节。
&&&&&&&&&&& abstract& void write(int b)& 将指定的字节写入此输出流。
&&&&&&&&&&& voidwrite(byte[] b) 将 b.length 个字节从指定的 byte数组写入此输出流。&&&
&&&&&&&&&&& voidwrite(byte[] b, int off, int len)
&&&&&&&&&&&&&&&&&&& 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。
&&&&&&& **字节读取流:InputStream:
&&&&&&&&&&& voidclose() 关闭此输入流并释放与该流关联的所有系统资源。
&&&&&&&&&&& intavailable() (特有方法!!)
&&&&&&&&&&&&&&& 返回此输入流下一个方法调用可以不受阻塞地从此输入流读取(或跳过)&&&&&&&&&&&&&&& 的估计字节数。
&&&&&&&&&&& abstract& int read() 从输入流中读取数据的下一个字节。
&&&&&&&&&&& intread(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组 &&&&&&&&&&&&&&&& b中。
&&&&&&&&&&& intread(byte[] b, int off, int len) 将输入流中最多len个数据字节读入byte数组。
&&&&&&&&&&& longskip(long n) 跳过和丢弃此输入流中数据的 n 个字节。
&&&&&&&&&&
&&&&&&& **字符写入流:Writer:
&&&&&&&&&&& abstract& void close() 关闭此流,但要先刷新它。
&&&&&&&&&&& abstract& void flush() 刷新该流的缓冲。
&&&&&&&&&&& voidwrite(int c) 写入单个字符。
&&&&&&&&&&& voidwrite(char[] cbuf) 写入字符数组。&&&&&&&&&
&&&&&&&&&&& abstract& void write(char[] cbuf, int off, int len) 写入字符数组的某一部分。
&&&&&&&&&&& voidwrite(String str) 写入字符串。
&&&&&&&&&&& voidwrite(String str, int off, int len) 写入字符串的某一部分。
&&&&&&& **字符读取流:Reader:
&&&&&&&&&&& abstract& void close() 关闭该流并释放与之关联的所有资源。
&&&&&&&&&&& intread() 读取单个字符。
&&&&&&&&&&& intread(char[] cbuf)& 将字符读入数组
&&&&&&&&&&& abstract& int read(char[] cbuf, int off, int len) 将字符读入数组的某一部分。
&&&&&&&&&&& longskip(long n)& 跳过字符。
50、流的操作流程
&&& (1)第一步:先明确源和目的
&&&&&&& 源:
&&&&&&&&&&& 文本:用Reader
&&&&&&&&&&& 字节:用InputStream
&&&&&&& 目的:
&&&&&&&&&&& 文本:用Writer
&&&&&&&&&&& 字节:用OutputStream
&&& (2)第二步:明确是不是纯文本
&&&&&&& 是:用字符流;
&&&&&&& 不是:用字节流
&&& (3)第三步:明确流体系后,通过设备来明确具体使用哪个流对象
&&&&&&& 源设备:
&&&&&&&&&&& 键盘:System.in
&&&&&&&&&&& 硬盘:文件流File
&&&&&&&&&&& 内存:数组流ArrayStream
&&&&&&& 目的设备:
&&&&&&&&&&& 键盘:System.out
&&&&&&&&&&& 硬盘:文件流File
&&&&&&&&&&& 内存:数组流ArrayStream
51、File类常见需求:
(1)文件名过滤:列出给定目录的所有.java文件
&&&&&&& publicvoid showFileName(File file)
&&&&&&&&&&& String[]filenames = file.list(new FilenameFilter()//匿名内部类
&&&&&&&&&&& {
&&&&&&&&&&&&&&& publicboolean accept(File dir,String name)//复写唯一方法
&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&& returnname.endsWith(&.java&);//列出所有.java文件
&&&&&&&&&&&&&&& }
&&&&&&&&&&& });
(2)列出指定目录下的所有文件和文件夹(递归)
&&& **示例1:不带层次递归:
&&& publicstatic void showDir(File dir)
&&&&&&& File[]files = dir.listFile();
&&&&&&& for(inti = 0;i&files.i++)
&&&&&&&&&&& if(files[i].isDirectory&&!files[i].isHidden())
&&&&&&&&&&&&&&& showDir(files[i]);
&&&&&&&&&&& else
&&&&&&&&&&&&&&& sop(files[i]);
&&& **示例2:带层次递归:
&&& publicstatic void showDir(File dir,int level)
&&&&&&& sop(getLevel(level)+C);//进来先打印层次和目录
&&&&&&& level++;
&&&&&&& File[]files = dir.listFile();
&&&&&&& for(inti = 0;i&files.i++)
&&&&&&&&&&& if(files[i].isDirectory&&!files[i].isHidden())
&&&&&&&&&&&&&&& showDir(files[i]);
&&&&&&&&&&& else
&&&&&&&&&&&&&&& sop(getLevel(level)+files[i]);//是文件就打印层次和目录
&&& publicstatic String getLevel(int level)
&&&&&&& sop(&|--&);
&&&&&&& StringBuildersb = new StringBuilder();
&&&&&&& for(inti=0;i&i++)
&&&&&&&&&&& sb.inset(0.&|& &)
&&&&&&& returnsb.toString();
(3)需求:删除带内容的目录:
&&& publicstatic void removeDir(File dir)
&&&&&&& File[]files = file.listFile();
&&&&&&& for(inti = 0;i&files.i++)
&&&&&&&&&&& if(files[i].isDirectory&&!files[i].isHidden())
&&&&&&&&&&&&&&& removeDir(files[i]);//如果是文件夹则继续调用函数
&&&&&&&&&&& else//如果是文件则删除。注意删除的时候打印删除的结果,防止误删或者重删的情况
&&&&&&&&&&&&&&& sop(files[i].toString()+&::&+files[i].delete());
&&&&&&& sop(dir+&::&+dir.delete());
&(4)需求:将制定目录下java文件的绝对路径存储到文本文件中。
&&& && 思路:
&&& && **对指定目录进行递归
&&& && **获取递归过程中所有java文件的路径
&&& && **将这些路径存储到集合中
&&& && **将集合中的数据写入文件中
&&& &//对指定目录进行递归并将所以Java文件存储到集合中
&&& publicstatic void getFileName(File file,ArrayList&File& arraylist){
&&&&&&& File[]files = file.listFiles();
&&&&&&& for(int i = 0; i & files. i++) {
&&&&&&&&&&& if(files[i].isDirectory()&&!files[i].isHidden()){
&&&&&&&&&&&&&&& getFileName(files[i],arraylist);
&&&&&&&&&&& }else{
&&&&&&&&&&&&&&& if(files[i].getName().endsWith(&.java&)){
&&&&&&&&&&&&&&&&&&& arraylist.add(files[i]);
&&&&&&&&&&&&&&& }
&&&&&&&&&&& }
&&& //将集合中所有数据存储到新文件中
&&& publicstatic void saveFileToNewDir(ArrayList&File& arraylist,File newDir){
&&&&&&& BufferedWriterbufw =
&&&&&&& try{
&&&&&&&&&&& bufw= new BufferedWriter(new FileWriter(newDir));
&&&&&&&&&&& for(File file : arraylist) {
&&&&&&&&&&&&&&& StringfileAbsolutePath = file.getAbsolutePath();
&&&&&&&&&&&&&&& bufw.write(fileAbsolutePath);
&&&&&&&&&&&&&&& bufw.newLine();
&&&&&&&&&&&&&&& bufw.flush();&&
&&&&&&&&&&& }
&&&&&&& }catch (Exception e) {
&&&&&&&&&&& System.out.println(&文件写入失败&);
&&&&&&& }finally{
&&&&&&&&&&& try{
&&&&&&&&&&&&&&& if(bufw!=null)
&&&&&&&&&&&&&&&&&&& bufw.close();
&&&&&&&&&&& }catch (Exception e2) {
&&&&&&&&&&&&&&& System.out.println(&文件写入流关闭失败&);
&&&&&&&&&&& }
52、Properties
&&& (1)Properties是HashTable的子类,具备Map集合的特点,里面存储的是键值对
&&& (2)Properties是IO流合集合相结合的集合容器
&&& (3)Properties的特点是可以用于存储键值对形式的配置文件
53、网络模型:
&&&&&&& 应用层、表示层、会话层、传输层、网络层、数据连接层、物理层
TCP/IP模型
&&&&&&& 应用层、传输层、网际层、主机至网络层
54、UDP和TCP的区别:
&&&&&&& 将数据及源和目的封装成数据包中,不需要建立连接
&&&&&&& 每个数据报的大小在限制在64k内
&&&&&&& 因无连接,是不可靠协议
&&&&&&& 不需要建立连接,速度快
&&&&&&& 建立连接,形成传输数据的通道。
&&&&&&& 在连接中进行大数据量传输
&&&&&&& 通过三次握手完成连接,是可靠协议
&&&&&&& 必须建立连接,效率会稍低
55、XML文档的定义形式?他们之间的本质区别,解析XML文档的方式
&&& XMl文档定义分为DTD和Schema两种形式,二者都是对XML语法的约束,其本质的区别在于Schema本省就是一个xml文件,可以被XML解析器解析,而且乐意为XML承载的数据定义类型约束比DTD更强大。
&&& 对XML的解析主要有DOM(文档对象模型),SAX和StAX。
&&& DOM处理大型文件时其性能下降的非常厉害,这个问题是由DOM树结构占用的内存较多造成的,而且DOM解析方式必须在解析文件之前把整个文档装入内存,适合对XML的随机访问(典型的用空间换取时间的策略);SAX是事件驱动型的XML解析方式,它顺序读取XML文件,不需要一次全部装载整个文件。当遇到像文件开头,文档结束,或者标签开头与标签结束时
56、你在项目中哪些地方用到了XML?
&&& XML的主要作用有两个方面:数据交换和信息配置。在做数据交换时,XML将数据用标签组装成起来,然后压缩打包加密后通过网络传送给接收者,接收解密与解压缩后再从XML文件中还原相关信息进行处理,XML曾经是异构系统间交换数据的事实标准,但此项功能几乎已经被JSON(JavaScriptObjectNotation)取而代之。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:338次
排名:千里之外
(window.slotbydup = window.slotbydup || []).push({
id: '4740887',
container: s,
size: '250,250',
display: 'inlay-fix'}

我要回帖

更多关于 ansible synchronize 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信