面试试答0419

my:cookie 是一小段用户相关信息,保存在浏览器中。浏览器接收到服务器返回的用户信息,将其存储到浏览器中,在之后的请求中,请求会带上 cookie 信息访问后端。session 是保存在服务端。

answer:补充,服务器生成 session 并存下来以后,会将 session id 放到 cookie 里返回请求方。cookie 可以存储的信息少,安全性低,用户可以选择禁用 cookie,所以要选择将哪些信息存储在 cookie 中,一般是用户的状态信息。

在浏览器输入一个网址会发生什么

my:输入的是一个域名,首先通过 DNS 服务器去找到对应的 IP 地址。如果 DNS 中没有记录,会调用上一层 DNS 服务器,直至找到对应的 IP 地址。然后通过 IP 去访问对应地址,通过 TCP 三次握手建立连接。如果使用的是 HTTPS 协议,会有发送公钥,证书认证,生成密钥,由非对称加密转到对称加密的一个过程。建立连接后,服务器上可能使用了 Nginx 做反向代理,那么根据请求路径,返回静态资源,或是反向代理到对应的后端服务器。后端服务器会存下 session,然后将请求结果和用户相关信息返回前端,浏览器将用户信息作为 cookie 存下。

answer:差不多,但是每个部分都可以展开讲

HashMap 如何实现线程安全的操作

my:HashMap 主要有两个线程安全的实现,HashTable 和 CurrentHashMap。HashTable 通过对所有读写方法加 synchronized 实现线程安全。CurrentHashMap 之前是使用分段锁,后来优化为使用 synchronized 和 CAS 操作,与HashTable 不同的是,synchronized 只锁头节点。

answer:差不多吧

HashMap 为什么使用红黑树,红黑树特性,树和平衡二叉树的区别,红黑树时间复杂度

my:因为当链表长度太长的时候,会造成读性能的下降。红黑树没有特别了解过。平衡二叉树忘了。红黑树的插入、删除、读取的时间复杂度都是 O(logn)

answer:平衡二叉树红黑树

TCP/IP 模型和 OSI 模型

my:TCP 是传输层协议,IP应该是链路层协议。

answer:就是四层网络模型和七层网络模型。

  • TCP/IP模型是四层网络模型,从上到下是应用层、传输层、网络层、数据链路层。
  • OSI是七层网络模型,从上到下是应用层、表示层、会话层、传输层、网络层、数据链路层、物理层。

lock 和 synchronized 区别

my:synchronized 是更原生的方法,有锁升级的那一套东西。lock 是工具类,有可重入,读写锁那些东西。

answer:

  1. lock 是一个接口,而 synchronized 是 Java 的一个关键字,synchronized 是内置的语言实现。
  2. 异常是否释放锁:synchronized 在发生异常时候会自动释放占有的锁,因此不会出现死锁;而 lock 发生异常时候,不会主动释放占有的锁,必须手动 unlock 来释放锁,可能引起死锁的发生。(所以最好将同步代码块用 try catch包起来,finally 中写入 unlock,避免死锁的发生。)
  3. 是否响应中断,lock 等待锁过程中可以用 interrupt 来中断等待,而 synchronized 只能等待锁的释放,不能响应中断。
  4. 是否知道获取锁:Lock 可以通过 trylock 来知道有没有获取锁,而 synchronized 不能。
  5. Lock 可以提高多个线程进行读操作的效率。(可以通过 ReadWriteLock实现读写分离)
  6. 在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争),此时 Lock 的性能要远远优于 synchronized。所以说,在具体使用时要根据适当情况选择。
  7. synchronized 使用 Object对象本身的 wait 、notify、notifyAll 调度机制,而 Lock 可以使用 Condition 进行线程之间的调度。

乐观锁和悲观锁

my:悲观锁对读写操作都加锁。乐观锁假设在读操作的时候不会有并发问题,读操作不加锁,可允许多个线程同时读,但是写操作与读操作互斥。

answer:上面的答案是错误的,是读锁和写锁的概念。悲观锁认为在操作数据的时候别的线程会修改数据,所以会在操作前后进行上锁、解锁的操作。乐观锁在操作数据的时候并不会上锁,而是在执行更新操作的时候检查在此期间是否有别人修改了数据,如果有则放弃更新操作。乐观锁通常使用 CAS 实现。

volatile 作用,原理

my:多线程有三大问题,原子性、可见性和有序性。volatile 可以解决可见性和有序性的问题,作用是防止指令的重排,以及防止将数据从内存读到 CPU 缓存中。原理好像是内存屏障,有读写、写读、读读、写写四种,具体没有了解过。

answer:volatile 对于可见性问题的解决不在内存和 CPU 缓存,而是在工作内存(线程独占内存)和主内存之间。当对 volatile 变量执行写操作后,JMM 会把工作内存中的最新变量值强制刷新到主内存,并且写操作会导致其他线程中的缓存无效。

手写单例模式

my:单例模式有几种实现方法。饿汉式在初始化的时候就创建,懒汉式在使用的时候创建,有一个双重判断的方法。在《effective java》里面推荐使用枚举类来实现单例模式,具体原因忘记了,写不出来。

answer:单例模式,推荐内部类和枚举模式

聚簇索引和非聚簇索引,怎么分配,为什么这样分配

my:不知道

answer:

  • 聚簇索引:将数据存储与索引放到一块,找到索引也就找到了数据,叶子节点存储数据
  • 非聚簇索引:表数据和索引是分成两部分存储的,所有的节点都是索引。叶子节点指向了数据的对应行

聚簇索引的优点:

  • 当需要取出一定范围内的数据时,使用聚簇索引比较好
  • 通过聚簇索引查找目标数据理论上比非聚簇索引快,因为非聚簇索引定位到对应主键时,还要多一次目标记录寻址,即多一次I/O
  • 使用覆盖索引扫描的查询可以直接使用页节点中的主键值

聚簇索引的缺点:

  • 插入速度严重依赖于插入顺序,按照主键的顺序插入是最快的方式,否则将会出现页分裂,严重影响性能。
  • 更新主键的代价很高,因为将会导致被更新的行移动。
  • 二级索引访问需要两次索引查找,第一次找到主键值,第二次根据主键值找到行数据
  • 采用聚簇索引插入新值比采用非聚簇索引插入新值的速度要慢很多,因为插入要保证主键不能重复。聚簇索引遍历所有的叶子节点,非聚簇索引也判断所有的叶子节点,但是聚簇索引的叶子节点除了带有主键还有记录值,记录的大小往往比主键要大的多。这样就会导致聚簇索引在判定新记录携带的主键是否重复时进行昂贵的I/O代价。

重定向和转发的区别

my:不清楚,我猜在请求头中的记录方法不同。有一个x-forward和一个real-address好像。

answer:

  • 重定向(Redirect):当浏览器请求一个 URL 时,服务器返回一个重定向指令,告诉浏览器地址已经变了,需要使用新的 URL 再重新发送新请求。重定向时,浏览器知道重定向规则,并且会自己自动发起新的 HTTP 请求。
  • 转发(Forward):当一个 Servlet 处理请求的时候,它可以决定自己不处理,而是转发给另一个 Servlet 处理。转发的路径必须是同一个 web 容器下的 url,不能转向其他的 web 路径上去。转发时,浏览器并不知道服务器内部的转发逻辑,对浏览器来说,它只发出了一个 HTTP 请求。

ACID

my:忘了,遗憾。A for 原子性,

answer:

  • 原子性(Atomicity):整个事务要么完整发生,要么根本不发生,不会部分发生。
  • 一致性(Consistency):一个事务必须使数据库从一个一致性状态变换到另一个一致性状态(执行成功),或回滚到原始的一致性状态(执行失败)。这意味着必须维护完整性约束,以使在事务之前和之后数据库保持一致性和正确性。
  • 隔离性(Isolation):并发执行的各个事务之间不能互相干扰,即一个事务内部的操作及使用的数据,对并发的其他事务是隔离的。
  • 持久性(Durability):是指一个事务一旦提交,对数据库中对应数据的状态变更就应该是永久性的。即使发生系统崩溃或机器宕机等故障,只要数据库能够重新启动,那么一定能够根据事务日志对未持久化的数据重新进行操作,将其恢复到事务成功结束的状态。

String 创建对象,intern 方法

my:String 创建可以用 new 方法也可以不用,一般都是不用 new 方法,因为这样可以共用对象,减少对象的创建。

answer: String.intern()方法会先去字符串常量池寻找有没有相同的字符串。如果找到,则直接返回字符串常量池中的引用。如果没有找到,JDK6和JDK7及以后存在区别:JDK6 会直接复制一个 String 对象的副本放到常量池,JDK7及以后则是生成一个对原字符串对象的引用放在字符串常量池中。

读写锁加读锁后如何避免写进程饿死

my:使用公平锁?

answer:yep 公平锁和非公平锁

NIO/AIO的区别以及各自的作用

my:不知道

answer: NIO:同步非阻塞,适合连接数多且连接时间的场景 AIO:异步非阻塞,适合连接数目多且连接时间的场景

怎么样确定使用到了索引

my:看执行计划吧,mysql 里面也许用 explain

answer: