专栏首页RendaJava 后台开发面试题分享七

Java 后台开发面试题分享七

数据库中 CHAR 和 VARCHAR 的区别?

1) Char 固定长度

2) Varchar 可变长度

3) Char 类型,如果存入数据的实际长度比指定长度要小,会补空格至指定长度;如果存入的数据的实际长度大于指定长度,低版本会被截取,高版本会报错

4 ) Varchar 类型,如果存入的数据的实际长度比指定的长度小,会缩短到实际长度;如果存入数据的实际长度大于指定长度,低版本会被截取 高版本会报错

5) Varchar 比 Char 节省存储空间

6) Char 效率会更高 Varchar 效率偏低

7) Char 和 Varchar 在指定时必须要指定后面的数字

TCP 建立连接为什么是 3 次握手,为什么不是 2 次握手或者 4 次握手呢?

不是 2 次握手的原因:防止客户端失效的连接请求报文段突然又传到服务器。

例如,以下情况如果使用 2 次握手
1)如果客户端向服务器发送第 1 次连接请求在网络节点上滞留了,没有收到服务器的确认,又重新发送了一次连接请求
2)服务器收到客户端的第 2 次请求发送确认,则连接建立完成
3)服务器客户端进行数据传输,传输完成断开连接。
4)此时,在网络上滞留的客户端第 1 次连接请求到达服务器,服务器发送确认连接但是客户端实际上并没有发送请求,因此不会理睬服务器发送的请求;但是服务器认为连接已完成,并等待客户端进行数据传输;这样就造成了资源的浪费。

如果采用 3 次握手:滞留在网络上的客户端第 1 次请求到达服务器之后,服务器发送确认,但实际上服务器并没有发送请求,因此不会理睬服务器的确认,故不会发送确认,服务器等不到客户端的确认则连接建立失败。这样就防止了客户端失效的连接请求报文段突然又传到服务器。

不是 4 次握手的原因:

模拟一下 4 次握手的过程
1)客户端发送请求报文,发送自己的序列号
2)服务器发送确认报文
3)服务器发送自己的序列号
4)客户端发送确认报文

上述过程中 2、3 步可以合为一步进行发送,因此没有必要进行 4 次握手

数据库中 delete、drop、truncate 区别

  • Truncate 和 Delete 只删除数据,不删除表结构,drop 删除表结构,并且释放所占的空间。
  • 删除数据的速度:drop > truncate > delete
  • Delete 属于 DML 语言,需要事务管理,commit 之后才能生效;drop 和 truncate 属于 DDL 语言,操作立刻生效,不可回滚
  • 使用场合:
- 当不再需要该表时,用 drop
- 当仍要保留该表,但要删除所有记录时,用 truncate
- 当要删除部分记录时(带有 where 子句), 用 delete

注意: 对于有主外键关系的表,如果需要删除所有数据,不能使用 truncate,而应该使用不带 where 子句的 delete 语句,由于 truncate 不记录在日志中,不能够激活触发器

Java 传参 - 基本数据类型和引用数据类型作为参数的区别(值传递)

1. 所谓值传递就是当参数是基本类型时,传递参数的值,比如传递 i = 10,真实传参时,把 10 赋值给了形参。
2. 当参数是对象时,传递的是对象的值,也就是对象的首地址,就是把对象的地址赋值给形参。
3. 基本数据类型的变量中直接存放数据值本身,所以改的时候改的是数据值本身。
4. 引用类型不同的地方在于真正的数据并没有在栈区的变量中保存,而是在堆区里面保存着;所以虽然也拷贝了一份,是副本,但是二者指向的是同一块堆区。

当使用基本数据类型作为方法的形参时,在方法体中对形参的修改不会影响到实参的数值;

当使用引用数据类型作为方法的形参时,若在方法体中修改形参指向的数据内容,则会对实参变量的数值产生影响,因为形参变量和实参变量共享同一块堆区;

当使用引用数据类型作为方法的形参时,若在方法体中修改形参变量的指向,此时不会对实参变量的数值产生影响,形参变量和实参变量分别指向不同的堆区。

Java 四种引用类型是?

强引用:在 Java 中最常见的就是强引用,把一个对象赋给一个引用变量,这个引用变量就是一个强引用;当一个对象被强引用变量引用时,它处于可达状态,它是不可能被垃圾回收机制回收的,即使该对象以后永远都不会被用到, JVM 也不会回收;因此强引用是造成 Java 内存泄漏的主要原因之一。

软引用:软引用需要用 SoftReference 类来实现,对于只有软引用的对象来说,当系统内存足够时它不会被回收,当系统内存空间不足时它会被回收;软引用通常用在对内存敏感的程序中。

弱引用:弱引用需要用 WeakReference 类来实现,它比软引用的生存期更短;对于只有弱引用的对象来说,只要垃圾回收机制一运行,不管 JVM 的内存空间是否足够,总会回收该对象占用的内存。

虚引用:虚引用需要 PhantomReference 类来实现;与软引用、弱引用不同,它不能单独使用,必须和引用队列联合使用;虚引用的主要作用是跟踪对象被垃圾回收的状态。

另外:引用队列可以与软引用、弱引用以及虚引用一起配合使用;当垃圾回收器准备回收一个对象时,如果发现它还有引用,那么就会在回收对象之前,把这个引用加入到与之关联的引用队列中去;程序可以通过判断引用队列中是否已经加入了引用,来判断被引用的对象是否将要被垃圾回收,这样就可以在对象被回收之前采取一些必要的措施。

事务具有的 4 个基本特征

1、Atomic - 原子性:事务中包含的操作被看做一个逻辑单元,这个逻辑单元中的操作要么全部成功,要么全部失败。

2、Consistency - 一致性:事务完成时,数据必须处于一致状态,数据的完整性约束没有被破坏,事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

3、Isolation - 隔离性:事务允许多个用户对同一个数据进行并发访问,而不破坏数据的正确性和完整性;同时,并行事务的修改必须与其他并行事务的修改相互独立。

4、Durability - 持久性:事务结束后,事务处理的结果必须能够得到固化。

高并发、任务执行时间短的业务怎样使用线程池?低并发、任务执行时间长的业务怎样使用线程池?高并发、业务执行时间长的业务怎样使用线程池?

1)高并发、任务执行时间短的业务:线程池线程数可以设置为 CPU 核数 + 1,减少线程上下文的切换。

2)低并发、任务执行时间长的业务:

- 假如是业务集中在 IO 操作上,也就是 IO 密集型的任务:因为 IO 操作并不占用 CPU,所以不要让所有的 CPU 闲下来,可以加大线程池中的线程数目,让 CPU 处理更多的业务
- 假如是业务集中在计算操作上,也就是计算密集型任务:线程池中的线程数设置得少一些,减少线程上下文的切换,和“高并发、任务执行时间短的业务”设置一样。

3)高并发、业务执行时间长的业务:解决这种类型任务的关键不在于线程池而在于整体架构的设计;第一步看看这些业务里面某些数据是否能做缓存;第二步增加服务器;至于线程池的设置,参考“低并发、任务执行时间长的业务”;最后,业务执行时间长的问题,也可能需要分析一下,看看能不能使用中间件对任务进行拆分和解耦。

线程类的构造方法、静态块是被哪个线程调用的?

线程类的构造方法、静态块是被 new 这个线程类所在的线程所调用的,而 run 方法里面的代码才是被线程自身所调用的。

假设 Thread 2 中 new 了 Thread 1,main 函数中 new 了 Thread 2,那么:

(1)Thread 2 的构造方法、静态块是 main 线程调用的,Thread 2 的 run() 方法是 Thread 2 自己调用的
(2)Thread 1 的构造方法、静态块是 Thread 2 调用的,Thread 1 的 run() 方法是 Thread 1 自己调用的

Thread.sleep(0) 的作用是什么

Thread.Sleep(0) 并非是真的要线程挂起 0 毫秒,意义在于这次调用 Thread.Sleep(0) 的当前线程确实的被冻结了一下,让其他线程有机会优先执行;

Thread.Sleep(0) 是让线程暂时放弃 cpu,也就是释放一些未用的时间片给其他线程或进程使用,就相当于一个让位动作。

什么是线程上下文的切换?

CPU 通过分配时间片来执行任务,当一个任务的时间片用完,就会切换到另一个任务;在切换之前会保存上一个任务的状态,当下次再切换到该任务,就会加载这个状态;任务从保存到再加载的过程就是一次上下文切换。

本文分享自微信公众号 - Renda(Renda_Zhang),作者:Renda Zhang

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-10-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 算法基础:递归

    递归的基本思想就是把规模大的问题转化为规模小的相同的子问题来解决。在函数实现时,因为大问题和小问题是一样的问题,因此大问题的解决方法和小问题的解决方法也是同一个...

    RendaZhang
  • Spring:JDBC Template,声明式事务

    JdbcTemplate 是 spring 框架中提供的一个模板对象,是对原始繁琐的 JDBC API 对象的简单封装。

    RendaZhang
  • Java 语言基础(异常机制和File类,IO流,多线程,网络编程,反射机制)

    序列化机制是通过在运行时判断类的 serialVersionUID 来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的 serialVersion...

    RendaZhang
  • Java中实现多线程的3种方法介绍和比较

    黄小怪
  • 同行评审以权谋私,让投稿人多引用自己文章,爱思唯尔将彻查此事

    爱思唯尔发现,某些同行评审正在滥用自己的权力,提高自己文章的引用率。他们会在投稿人的在审稿意见中加入一句提醒:“请参考XXX文献”,而这篇文献往往是审稿人自己的...

    量子位
  • 看完本文,再也不怕问java线程创建的几种方式了

    使用继承Thread类的方法来创建线程类时候,多个线程之间是无法共享线程类的实例变量的。

    田维常
  • 每天学一个 Linux 命令(5):grep

    https://github.com/mingongge/Learn-a-Linux-command-every-day

    民工哥
  • java多线程系列_使用Runnable接口创建线程(3)

    实现Runnable接口的类必须使用Thread类的实例才能创建线程。通过Runnable接口创建线程分为两步:

    Hongten
  • brpc介绍、编译与使用

            brpc又称为baidu-rpc,是百度开发一款“远过程调用”网络框架。目前该项目已在github上开源——https://github.com...

    方亮
  • 第三方组件安全剖析 | 洞见

    Apache Struts2再曝高危漏洞 前段时间,Apache Struts2又接连曝出了两个高危远程代码执行(Remoce Code Execution,下...

    ThoughtWorks

扫码关注云+社区

领取腾讯云代金券