面试题

面试题

从浏览器中输入一个域名之后,敲下回车,到浏览器展示页面这个过程发生了什么?

1、在浏览器在输入域名之后,DNS会根据域名找到对应的IP

2、根据IP地址建立TCP连接(三次握手)

3、连接成功之后,会发送HTTP请求

4、服务器会响应HTTP请求

5、浏览器响应HTML中的代码,并请求HTML中的静态资源(js、css)

6、关闭TCP连接

7、浏览器渲染页面

解析DNS域名

  • 浏览器查找自己的DNS缓存,如果有直接返回,如果没有进行步骤二

  • 操作系统查找自己的DNS缓存,如果有直接返回给浏览器,如果没有进行步骤三

  • 操作系统查找自己的本地host文件,如果有返回给浏览器,如果没有则进行步骤四

  • 操作系统向本地域名服务器发起请求,查找本地DNS缓存,如果有,返回给操作系统,然后操作系统返回给浏览器,如果没有进行步骤五

  • 操作系统向根域名服务器发起请求得到顶级域名服务器的IP,然后根域名服务器向顶级域名服务器发起请求得到权限域名服务器的IP,顶级域名服务器再向权限域名服务器发起请求得到IP,本地域名服务器返回给操作系统IP,同时将IP缓存起来,操作系统将IP返回给浏览器,同时将IP缓存起来。

注:由于数字式的IP地址难于记忆,所以就使用易于记忆的符号地址,这就需要一个数字地址和符号地址相互转换的机制,也就是DNS.而DNS服务器完成域名与IP地址转换的过程,就是域名解析

具体一些详细的解释

https://www.cnblogs.com/mlgjb/p/8490516.html
https://blog.csdn.net/weixin_38497513/article/details/80918425

char类型的变量可不可以存汉字

答案是可以的

char类型中存储的是Unicode编码,Unicode编码中是存在存在中文的,所以Char自然可以存储汉字,但是!仅限于Unicode中存在的汉字。

一个汉字的占两个字节,一个Unicode也是占两个字节 ,char存储汉字完全没有问题。

接口和抽象类的异同

相同点

  • 都不能被实例化

  • 接口的实现类或者抽象类的子类都必须实现接口或者抽象类中的方法才可以被实例化

不同点

  • 接口使用interface修饰,抽象类使用abstract修饰

  • 实现接口使用implements 继承抽象的关键字extends 一个类可以实现多个接口,但只能继承一个抽象类

  • 接口中没有构造器 抽象中有构造器

  • 接口是定义规范的,抽象是对公共部分的抽取

  • 接口只有定义,方法不能再接口中实现

  • 实现接口的类要实现/重写接口中的所有方法;抽象类可以有定义与实现方法可以在抽象类中实现

Math.round

long round = Math.round(-11.41);
System.out.println(round);	//-11

long round1 = Math.round(-11.5);  //-11 
System.out.println(round1);

long round4 = Math.round(-11.51);  //-12
System.out.println(round4);

long round2 = Math.round(11.5);
System.out.println(round2);    //12

long round3 = Math.round(11.4);
System.out.println(round3); 		//11

long round5 = Math.round(11.49);  
System.out.println(round5);      //11

HashCode equals

hashCode

hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。hashCode() 定义在JDK的Object.java中,这就意味着Java中的任何类都包含有hashCode() 函数。

equals

equals它的作用也是判断两个对象是否相等,**如果对象重写了equals()方法,比较两个对象的内容是否相等;如果没有重写,比较两个对象的地址是否相同 **,价于“==”。同样的,equals()定义在JDK的Object.java中,这就意味着Java中的任何类都包含有equals()函数。

  • 如果两个对象的hashcode()相同,他们不一定相等,因为在散列表中,hashCode()相等,即两个键值对的哈希值相等。然而哈希值相等,并不一定能得出键值对相等,此时就出现所谓的哈希冲突场景。

  • 如果两个对象相等,那么它们的hashCode()值一定相同。这里的相等是指,通过equals()比较两个对象时返回true。

equals ==

1、对于==,如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;如果作用于引用类型的变量,则比较的是所指向的对象的地址。

2、对于equals方法,注意:equals方法不能作用于基本数据类型的变量

  • 如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;

  • 诸如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容。

synchronized ReentranLock区别

  • synchronized 是一个Java的关键字,synchronized是内置的语言实现,Lock是一个接口。

  • synchronized在发生异常时,会自动释放线程的锁,不会产生死锁现象,Lock发生异常时,如果没有主动释放,极有可能产生死锁,需要在finally主动释放。

  • Lock可以让等待锁的线程响应中断,使用synchronzied只会让等待线程的锁一致等待下去,不能响应中断

锁概念

1、可中断锁

响应中断的锁,Lock是可中断锁 (体现在lockInterruptibly()方法),synchronized不是。

如果线程A正在执行锁中代码,线程B正在等待获取该锁。时间太长,线程B不想等了,可以让它中断自己。

2、公平锁

尽量以请求锁的顺序获取锁。比如同时有多个线程在等待一个锁,当锁被释放后,等待时间最长的获取该锁,跟京牌司法拍卖一个道理。

非公平锁可能会导致有些线程永远得不到锁。synchronized是非公平锁,ReentrantLock是公平锁。

3、读写锁

读写锁将对一个资源(如文件)的访问分为2个锁,一个读锁,一个写锁;读写锁使得多个线程的读操作可以并发进行,不需同步。

而写操作就得需要同步,提高了效率 ReadWriteLock就是读写锁,是一个接口,ReentrantReadWriteLock实现了这个接口。

可通过readLock()获取读锁,writeLock()获取写锁

了解一个类new的过程吗?

当虚拟机遇见new关键字,首先会判断该类是否已经被加载,如果没有加载,首先,会加载这个类、分配内存空间、为静态变量赋值、初始化、使用、销毁。

类的加载 –> 类的连接 —> 类的初始化 —> 类的使用 —>类的销毁

1、类的加载:查找类的二进制数据(.class文件);将class文件加载到JVM中

2、类的连接:分为三个阶段:校验、准备、解析。

  • 校验:校验的类的二进制文件

  • 准备:为静态变量、常量赋默认值

  • 解析:将符号引用变为直接引用

3、初始化:初始化static静态代码块,如果存在父类,先对父类的代码块进行初始化。

4、使用:对象的初始化、对象的垃圾回收、对象的销毁

5、销毁

双亲委派机制

Java是运行在Java的虚拟机(JVM)中的,但是它是怎么就运行在JVM中了呢?我们在IDE中编写的Java源代码被编译器编译成.class的字节码文件。然后由我们得ClassLoader负责将这些class问价加载到JVM中去执行。

ClassLoader

什么是类加载器?

类加载器是jre的一部分,负责动态将类添加到Java虚拟机。

类加载分类

1、启动类加载器 bootstrap classloader :加载jre/lib/rt.jar

2、扩展类加载器 extension classloader :加载jre/lib/ext/*.jar

3、应用程序类加载器 application classloader:加载classpath上指定的类库

双亲委派机制是指当一个类加载器收到一个类加载请求时,该类加载器首先会把请求委派给父类加载器。
每个类加载器都是如此,只有在父类加载器在自己的搜索范围内找不到指定类时,子类加载器才会尝试自己去加载。

  • Bootstrap classLoader:主要负责加载核心的类库(java.lang.*等),构造ExtClassLoader和APPClassLoader。

  • ExtClassLoader:主要负责加载jre/lib/ext目录下的一些扩展的jar。

  • AppClassLoader:主要负责加载应用程序的主函数类

1、不考虑我们自定义类加载器,首先会在AppClassLoader中检查是否加载过,如果有那就无需再加载了。

2、如果没有,那么会拿到父加载器,然后调用父加载器的loadClass方法。父类中同理会先检查自己是否已经加载过,如果没有再往上。

3、注意这个过程,知道到达Bootstrap classLoader之前,都是没有哪个加载器自己选择加载的。如果父加载器无法加载,会下沉到子加载器去加载,一直到最底层,如果没有任何加载器能加载,就会抛出ClassNotFoundException

为什么要设计这种机制

这种设计有个好处是,如果有人想替换系统级别的类:String.java。篡改它的实现,但是在这种机制下这些系统的类已经被Bootstrap classLoader加载过了,所以并不会再去加载,从一定程度上防止了危险代码的植入。

做的不好,多多指教
原文地址:https://www.cnblogs.com/xingStudy/p/14118943.html