day18Excise1

1.阅读下面XML文档,然后判断下列说法正确的是( C )。

<company>
<name>TEDU</name>
<address>北京海淀</address>
</company>
A.<company>是元素对象,同样也是文本对象
B.<name>是元素对象,同样也是文本对象
C.北京海淀是文本对象
D.北京海淀是元素对象

2.下列是格式正确的XML标记的是( CD)。

 A.<name>张三<name>
 B.<name>张三</Name>
 C.<name>张三</name>
 D.<name/>

3.下列选项中可以解析XML文档的是( BC)。
A.DTD
B.DOM
C.SAX
D.CSS

简答题

1.HashMap扩容原理

JDK1.8HashMap底层采用数组+链表+红黑树形式存储.
如果HashMap初始化的时候没有指定容量,会返回一个空的 Node[] table数组。第一次往HashMap中put(添加)元素的时候 ,会使用默认的参数作为数组的初始化长度:
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
当HashMap中的元素数量超过 容量*加载因子 时,会进行扩容操作,容量变为原来的2倍,HashMap的加载因子,默认是0.75:
static final float DEFAULT_LOAD_FACTOR = 0.75f;

2.HashMap底层结构

HashMap底层是一个Node数组,: transient Node<k,V>[] table; (Node<K,V> 类实现了 Map.Entry接口)
当存放元素时,首先会根据Key的hashCode值找到数据应该保存在table数组的下标位置。
如果数组的位置上没有数据 ,直接将这这个键值对保存在该位置上。
如果数组的位置上已经有数据了,即发生了哈希冲突(哈希碰撞),也就是两个对象的key和hash值相等,那么则需要通过Key的equals()方法判断这两个对象是否为同一个对象。如果是,那么原本存储Key的value值会被新值所替换。如果不是同一个对象,则采用链式地址法,把新的键值对对象保存到旧的键值对对象(Node<K,V>)的next变量中,形成单向链表结构,即使从链表的尾部插入。
当链表过长时,查询效率会下降,所以JDK8之后新增了红黑树作为底层数据结构,如果链表长长度超过8并且数组长度大于64时,
static final int TREEIFY_THRESHOLD = 8;
static final int MIN_TREEIFY_CAPACITY = 64;
hashMap会把这个链表转成红黑树来存储(如果数组长度没有超过64会强制扩容而不是转成红黑树,因为红黑树增删数据效率低,数组扩容后减少hash冲突几率)
当链表长度小于6时会从红黑树转回链表
static final int UNTREEIFY_THRESHOLD = 6;

jdk1.7HashMap底层采用数组+链表形式;
创建HashMap时就指定数组容量为16,加载因子为0.75,
当存放元素时,首先会根据Key的hashCode值找到数据应该保存在table数组的下标位置。
如果数组的位置上没有数据 ,直接将这这个键值对保存在该位置上。
如果数组的位置上已经有数据了,即发生了哈希冲突(哈希碰撞),也就是两个对象的key和hash值相等,那么则需要通过Key的equals()方法判断这两个对象是否为同一个对象。如果是,那么原本存储Key的value值会被新值所替换。如果不是同一个对象,也是采用链式存储,直接在数组的该位置插入Entry[]形成单向链表结构,即是从链表的头部插入。当元素个数大于数组容量*加载因子时,数组扩容为原来2倍。

3.HashSet存储原理

HashSet底层由HshMap实现,利用了HashMap的key不能重复的特性
直接将要存储的元素作为key存储到HashMap中。HashSet即是HashMap的Key。
在这里插入图片描述
第一次往HashSet中add()元素时,底层实际调用map的put添加元素,map的键(Key)是HashSet add()的元数,value为每次创建一个Object对象。
在这里插入图片描述
在这里插入图片描述

4.List和Set的区别

  1. Set 接口实例存储不重复的数据,不强调Set的无序性,因为其间接实现类LinkedHashSet提供了通过前驱指针和后继指针实现有序遍历集合的操作。List 接口实例存储的是有序的,可以重复的元素。

  2. Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet>。

  3. List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector> 。Set:检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变<直接实现类有HashSet,间接实现类有LinkedHashSet,TreeSet>

一、存储元素的方式:
java.util.List:线性表,可以保存重复元素并且有序,可通过下标操作。
java.util.Set: 不可重复集合,这里的重复元素判定是依靠元素自身的equals方法比较的结果而定,为true就认为是重复元素则不添加。
二、添加对象:
List添加对象没有要求,Set添加对象,要求对象所在的类必须重写equals()和hasCode(),相等的对象必须具有相等的散列码。
三、检索效率
Set:检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变
List:类似动态数组,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变。
List接口有三个直接实现类,Set有一个直接实现类,两个间接实现类
在这里插入图片描述

5.HashMap和Hashtable的区别

相同点:
HashMap 和 Hashtable都实现了Map接口,Cloneable(可克隆),Serializable(可序列化)这三个接口
不同点:
1,HashMap线程不安全的,效率高;允许key和value存储null
2,Hashtable:作为古老的实现类;线程安全的,效率低;key和value不能存储null
3.Hashtable提供了对键的列举(Enumeration).

不同点:

  1. 底层数据结构不同:jdk1.7底层存储数据采用数组+链表,JDK1.8底层存储数据采用数组+链表+红黑树
  2. Hashtable 是不允许键或值为 null 的,HashMap 的键值则都可以为 null。
    3.添加key-value的 hash 值算法不同:HashMap添加元素时,是使用自定义的哈希算法,而HashTable是直接采用key的hashCode()
    4.实现方式不同:Hashtable 继承的是 Dictionary类,而 HashMap 继承的是 AbstractMap 类。
  3. 初始化容量不同:HashMap 的初始容量为:16,Hashtable 初始容量为:11,两者的加载因子默认都是:0.75。
  4. 扩容机制不同:当已用容量>总容量 * 加载因子时,HashMap 扩容规则为当前容量翻倍,Hashtable 扩容规则为当前容量翻倍 +1。
  5. 支持的遍历种类不同:HashMap只支持Iterator遍历,而HashTable支持Iterator和Enumeration两种方式遍历
    迭代器不同:HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以当有其它线程改变了HashMap的结(增加或者移除元素),将会抛出ConcurrentModificationException,但迭代器本身的remove()方法移除元素则不会抛出ConcurrentModificationException异常。但这并不是一个一定发生的行为,要看JVM。而Hashtable 则不会。
  6. 部分API不同:HashMap不支持contains(Object value)方法,没有重写toString()方法,而HashTable支持contains(Object value)方法,而且重写了toString()方法
  7. 同步性不同: Hashtable是同步(synchronized)的,适用于多线程环境,而HashMap不是同步的,适用于单线程环境。多个线程可以共享一个Hashtable;而如果没有正确的同步的话,多个线程是不能共享HashMap的。
    由于Hashtable是线程安全的也是synchronized,所以在单线程环境下它比HashMap要慢。如果你不需要同步,只需要单一线程,那么使用HashMap性能要好过Hashtable。

6.xml文件的语法要求有哪些?

1、XML 文档必须有根元素,有且只能有一个根元素,在根元素里面可以写很多子节点
2、XML 声明:XML 声明文件的可选部分,如果存在需要放在文档的第一行
3,、除了自闭合标签,所有的 XML 元素都必须有一个关闭标签
自闭合标签形式:,定义属性只能在<>里的/之前定义。
4,XML的所有标签名是自定义的,所以XML 标签对大小写敏感
5、标签成对存在,自闭合标签,可以独立存在
6.XML 中的注释采用:

7.常用的xml解析方式

XML解析常用方式:
1.DOM(Document Object Model,文档对象模型)
是官方提供的平台无关的解析方式。
会将一个XML文档内容以树的结构一次性加载到内存中,可以对XML文档的内容进行随机访问或修改的操作。但是对大文档来说解析效率低,内存成本高。
2.SAX(以事件为驱动)
以事件为驱动,需要哪些数据再加载和解析哪些内容,解析速度快,占用内存少,但是不会将内容加载到内存,使用起来不方便,反而会增加程序负担。

3.JDOM(JAVADOM用的是集合)
是java和DOM的结合体,是基于java平台使用的,简单高效,但是需要加载整个文档,对内容容量要求高。

4.DOM4J
是一个java的XML API,类似于JDOM,用来读写xml文件,性能优异,功能强大,简单易用,且开放源代码,是目前最流行、最好用的xml解析工具,解析xml速度最快

8.什么是maven

1.Maven 是 Apache 开源组织奉献的一个开源项目。Maven 这个词可以翻译为“知识的积累”,也可以翻译为“专家”或“内行”
2、Maven 的本质是一个项目管理工具,将项目开发和管理过程抽象成一个项目对象模型(POM)。开发人员只需做一些简单的配置,就可以批量完成项目的构建、报告和文档的生成工作。
3、Maven 是跨平台的,这意味着无论是在 Windows 上,还是在 Linux 或者 Mac 上,都可以使用同样的命令。
综上所诉,Maven 作为一个构建工具,不仅能帮我们自动化构建,还能够抽象构建过程,提供构建任务实现;它跨平台,对外提供了一致的操作接口,这一切足以使它成为优秀的、流行的构建工具
Maven 可以统一管理所有的依赖 jar,甚至是不同的版本。程序员也可以动态地将自己写好的模块打包成 jar 包让它管理。需要的时候,可以直接通过简单的描述文件告诉 Maven,它会自动帮助程序员找出来,集成到项目中。并且它提供了中央仓库,能帮我们自动下载构件。

总结Maven作用:
Maven 统一集中管理好所有的依赖包,不需要程序员再去寻找。
对应第三方组件用到的共同 jar包,Maven 自动解决重复和冲突问题。
Maven 作为一个开放的架构,提供了公共接口,方便同第三方插件集成。程序员可以将自己需要的插件,动态地集成到 Maven,从而扩展新的管理功能。
Maven 可以统一每个项目的构建过程,实现不同项目的兼容性管理。

扩展: jar包是将一系列的类、接口等相关文件压缩打包后形成的文件,表现为扩展名为.jar的文件。

9.什么是反射

反射主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。
Java反射机制是一种动态机制,它允许程序运行起来后再确定实例化对象,调用方法和操作属性,可以提高代码的灵活度。
但是反射会带来较慢的运行速度和更多的系统开销,所以不能过度依赖反射机制。Java反射机制的主要功能:
1、在运行时判断任意一个对象所属的类;
2、在运行时构造任意一个类的对象;
3、在运行时调用任意一个对象的方法等。

在JDK中,主要由以下类来实现Java反射机制,这些类(除了第一个)都位于java.lang.reflect包中:

Class类:代表一个类,位于java.lang包下。newInstance()

Field类:代表类的成员变量(成员变量也称为类的属性)。 Object get(Object obj),
需要指定对象,想要获取那个对象的属性值就哪个对象 getDeclaredField(); Field[] getFields();
获取所有公有方法 getDeclaredFields();获取所有属性包括非私有

Method类:代表类的方法。
getMethod(),
Methods[] getMehtods();
getDeclaredMethod();
getDeclaredMethods();

Constructor类:代表类的构造方法。
Constructor getConstructor(Class<?>… parameterTypes);参数列表是可变参数;当参数列表为空,获取到的是无参构造

Array类:提供了动态创建数组,以及访问数组的元素的静态方法。

10.注解的分类,你用过哪些注解,它们的作用是什么?

注解(Annocation)的概念:又叫标注,是从Java5开始增加的一种引用数据类型,是代码里的特殊标志,注解本质上就是代码中的特殊标记,通过这些标记可以在编译,类加载,以及运行时执行指定的处理。通过@interface 注解名称{ 注解成员;}定义。
注解的分类:
1.五个JDK注解:
1.@Override 限定父类重写方法
2.@Deprecated 标示已过时
3.@SuppressWarnings 抑制编译器警告
4.@SafeVarargs “堆污染”警告
5.@FunctionalInterface 函数式接口
2.元注解
用于描述注解的注解 ,通常配合元注解完成自定义注解
元注解主要有:
@Retention, 定义注解的生命周期,只能指定一个,
@Documented,
@Target, 用来指定注解可以出现的位置,比如出现在类上、方法上、属性上、参数上。 通过ElementType可以指定多个位置,在大括号中用逗号隔开
@Inherited, 指定继承关系
@Repeatable

3.自定义注解
使用@interface 注解名{
注解体;
例如:
类型 属性名() default 默认值;
}

11.谈谈你对socket的理解

Socket也叫做套接字,Java Socket是实现Java网络编程的机制,其中服务器端的套接字成为ServerSocket,而客户端的套接字称为Socket。每一个Socket都由IP地址和端口号唯一确定。
Socket可以分为两种类型:面向连接的Socket通信协议(TCP)和无连接的Socket通信协议(UDP)。
基于TCP的Socket通信过程分为三个步骤:服务器监听、客户端请求、连接确认。
Socket的生命周期可以分为三个阶段:打开Socket,使用socket收发数据和关闭socket。在Java语言中,使用socket实现客户端和服务器端的进行数据交换,与数据流的操作关系密切。Socket提供了getInputStream()和getOutputStream()来写出和读入字节数据通过网络发送给对方。
在这里插入图片描述

编程题

  1. 定义封装类Student,类中的成员有:
    私有属性:学号,姓名,年龄,性别
    无参构造方法,全参数构造方法
    定义每个属性的setters和getters方法
    重写toString方法和equals方法(根据学号比较对象)

    在测试类中利用反射完成以下操作:

    1. 用户从控制台输入要加载的类名
    2. 实例化该类,要求调用有参构造方法完成实例化对象的同时为属性赋值
    3. 获取并遍历类中的所有方法,执行所有的get开头的方法,并将其返回值打印输出。
package JAVA_API.api_homework.day18;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Objects;
import java.util.Scanner;

/**
 * 1. 定义封装类Student,类中的成员有:
 * 	私有属性:学号,姓名,年龄,性别
 * 	无参构造方法,全参数构造方法
 * 	定义每个属性的setters和getters方法
 * 	重写toString方法和equals方法(根据学号比较对象)
 * 	   在测试类中利用反射完成以下操作:
 * 	1. 用户从控制台输入要加载的类名
 * 	2. 实例化该类,要求调用有参构造方法完成实例化对象的同时为属性赋值
 * 	3. 获取并遍历类中的所有方法,执行所有的get开头的方法,并将其返回值打印输出。
 * @author yyc
 * 2021/9/29 19:19
 */
//在测试类中利用反射完成以下操作:
public class StudentTest {
    public static void main(String[] args) throws Exception {

        Student student = new Student();
        System.out.println(Student.class);
        //	1. 用户从控制台输入要加载的类名
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入类名:");
        String className = scanner.nextLine();
        //2.获取类对象
        Class cls = Class.forName(className);
        //className = cls.getSimpleName();

        //3.实例化该类,要求调用有参构造方法完成实例化对象的同时为属性赋值
        //创建并初始化对象的属性,需要使用有参构造器创建,第一步先获取有参构造器,需要指定形参参数类型的类对象
       /* Constructor student = cls.getConstructor(int.class,String.class,int.class,char.class);
        Object student1 = student.newInstance(136184119,"余易彩",18,'女');*/
        //4.为了满足题意,调用构造方法实例化对象的同时为属性赋值
        Object student1 = cls.getConstructor(long.class,String.class,int.class,char.class).newInstance(131141516,"yyc",18,'女');

        //5.获取并遍历类中的所有方法,执行所有的get开头的方法,并将其返回值打印输出
        Method[] methods = cls.getMethods();
        for (Method method : methods){
              //获取方法名
            String methodName = method.getName();
            //输出类对象中的方法
            System.out.println(methodName);
            //判断是否是get开头
            if (methodName.startsWith("get")) {
                //执行方法
                System.out.println(method.invoke(student1));
            }
        }
    }
}

在这里插入图片描述
2.创建Demo类,在类中定义一个私有方法 demo(),方法体中输出“私有方法”,
创建测试类Test,利用反射在运行期输入要加载的类名,然后实例化对象,然后执行该私有方法。

package JAVA_API.api_homework.day18;

import com.sun.xml.internal.bind.v2.model.annotation.RuntimeAnnotationReader;

import javax.lang.model.element.Element;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Scanner;

/**
 *  2.创建Demo类,在类中定义一个私有方法  demo(),方法体中输出“私有方法”,
 *  创建测试类Test,利用反射在运行期输入要加载的类名,然后实例化对象,然后执行该私有方法。
 * @author yyc
 * 2021/9/29 20:56
 */
public class DemoTest {
    public static void main(String[] args) throws Exception {

        System.out.println(Demo.class);
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入类名:");
        String className = scanner.nextLine();
        //1.获取类对象
        Class cls = Class.forName(className);

        //2.实例化对象
        Object demo = cls.newInstance();
        //创建测试类Test,利用反射在运行期输入要加载的类名,然后实例化对象,然后执行该私有方法。
        Method method = cls.getDeclaredMethod("demo");
        //设置强制访问
        method.setAccessible(true);
        //执行方法,非静态的需要传对象
        method.invoke(demo);
    }
}
//创建Demo类,在类中定义一个私有方法  demo(),方法体中输出“私有方法”,
class Demo {
    private void demo(){
        System.out.println("私有方法");
    }
}

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值