公告

👇微信扫码添加好友👇

Skip to content

每日一题 - 202401

1-31

什么是同步?

同步 IO 和 非同步 IO 是操作系统级别的,主要描述操作系统在收到程序请求 IO 操作后, 如果 IO 资源没有准备好,该如何响应程序的问题。前者不响应,直到 IO 资源准备好,后者返回标记, 当 IO 资源准备好之后,再通过事件机制返回给程序。

1-30

什么是阻塞?

阻塞 IO 和 非阻塞 IO 是程序级别的,主要描述程序请求操作系统 IO 操作后, 如果 IO 资源没有准备好,那么程序该如何处理的问题,前者等待,后者继续执行(一直轮询)。

1-29

如何理解 IO 流?

从数据传输方式来讲,IO 流分为字节流和字符流,字节流处理二进制文件,字符流读取单个字符,用于处理文本文件。

从数据流向来讲,IO 流分为输入流和输出流,输入流用于读取数据,输出流用于写入数据。

从数据操作类型来讲,IO 流分为文件流、管道流、缓冲流、数据流、对象流、序列化流、打印流、转换流等。

1-28

描述异常的底层?

JAVA 代码编译之后,会生成一个异常表(Exception Table),如下:

java
public static void simpleTryCatch() {
   try {
       testNPE();
   } catch (Exception e) {
       e.printStackTrace();
   }
}

该段代码编译后生成的字节码如下:

//javap -c Main
 public static void simpleTryCatch();
    Code:
       0: invokestatic  #3                  // Method testNPE:()V
       3: goto          11
       6: astore_0
       7: aload_0
       8: invokevirtual #5                  // Method java/lang/Exception.printStackTrace:()V
      11: return
    Exception table:
       from    to  target type
           0     3     6   Class java/lang/Exception

异常表包含了可能发生异常的起始点、结束点、异常处理代码的起始点、异常类型等信息。当发生异常时,JVM 会根据异常表中的信息来决定如何处理异常。

1-27

Java 7 的 try-with-resource?

Java 7 引入了 try-with-resource 语句,该语句可以自动关闭实现了 AutoCloseable 接口的资源。 大部分的 JAVA 标准资源都继承了该接口。当在 try 代码块执行后货异常处理后,会自动调用资源的 close() 方法。

java
public class TryWithResourceTest {

    @Test
    public void test() throws IOException {
        try (FileInputStream fis = new FileInputStream("test.txt")) {
            int data = fis.read();
            while (data != -1) {
                System.out.print((char) data);
                data = fis.read();
            }
        }
    }
}

1-26

JAVA throw 和 throws 的区别?

  • throw 用在方法体内,用来抛出一个异常对象,将这个异常对象传递到调用者处,并终止当前方法的执行。
  • throws 用在方法声明后面,跟的是异常类名,可以跟多个异常类名,用逗号隔开,表示当前方法不处理异常,而是提醒该方法的调用者来处理异常(将异常抛给调用者), 如果调用者也不处理异常,那么继续往上抛,最终抛给 JVM 处理,JVM 会终止程序的运行。

1-25

getName、getCanonicalName 与 getSimpleName 的区别?

  • getName():获取全限定类名,包含包名。
  • getCanonicalName():获取全限定类名,不包含包名。
  • getSimpleName():获取类名,不包含包名。

1-24

什么是反射?

反射是指程序可以访问、检测和修改它本身状态或行为的一种能力。 Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法; 对于任意一个对象,都能够调用它的任意一个方法和属性。

如下:

java
    @Test
    public void classTest() throws Exception {
        // 获取Class对象的三种方式
        logger.info("根据类名:  \t" + User.class);
        logger.info("根据对象:  \t" + new User().getClass());
        logger.info("根据全限定类名:\t" + Class.forName("com.test.User"));
        // 常用的方法
        logger.info("获取全限定类名:\t" + userClass.getName());
        logger.info("获取类名:\t" + userClass.getSimpleName());
        logger.info("实例化:\t" + userClass.newInstance());
    }

1-23

Quartz是做什么用的?

Quartz 是开源的 JAVA 任务调度框架,能够灵活且简单的管理定时任务。支持数据库集成、集群、插件等。支持使用 cron-like 表达式。

1-22

如何限制规定泛型的范围?

可以使用 extends 关键字: class Test<T extends Number> 限制泛型的范围为 Number 及其子类。

也可以使用 interface 关键字: class Test<T implements Test> 限制泛型的范围为 Test 的实现方法。

1-21

泛型类如何定义使用?

java

class Test<T>{                  // 此处可以随便写标识符号,T是type的简称
    private T t;                // 类型由T指定,即:由外部指定  
    public void setT(T t){
        this.t = t;
    }
    public T getT(){
        return t;
    }
}

public class TestDemo{
    public static void main(String[] args){
        Test<String> test = new Test<String>();
        test.setT("hello");
        System.out.println(test.getT());
    }
}

1-20

this() & super() 在构造方法中的区别?

  • 调用super()必须写在子类构造方法的第一行, 否则编译不通过
  • super从子类调用父类构造, this在同一类中调用其他构造均需要放在第一行
  • 尽管可以用this调用一个构造器, 却不能调用2个
  • this和super不能出现在同一个构造器中, 否则编译不通过
  • this()、super()都指的对象,不可以在static环境中使用
  • 本质this指向本对象的指针。super是一个关键字

1-19

什么是 Java 移位运算符?

  • << 左移运算符,num << 1,相当于 num 乘以 2
  • >> 右移运算符,num >> 1,相当于 num 除以 2
  • >>> 无符号右移运算符,忽略符号位,空位都以0补齐

1-18

JAVA 能在 Switch 中使用 String 吗?

在 Java 7 之前,switch 只能支持 byte、short、char、int、enum 类型,Java 7 之后,可以支持 String 类型。

1-17

为什么DNS通常基于 UDP?

DNS 通常基于 UDP,因为 UDP 没有连接的开销,而且 DNS 服务需要尽可能快地响应请求,而不是等待连接建立。但当数据长度大于512字节时,为保证传输质量,就会使用基于TCP的实现形式。

1-16

TCP 三次握手中,最后一次回复丢失,会发生什么?

如果最后一次回复丢失,客户端会认为服务端没有收到确认信息,会再次发送确认信息,服务端收到确认信息后,会再次发送确认信息,客户端收到确认信息后,会再次发送确认信息,如此循环,直到连接超时。

1-15

什么是 TCP 三次握手?

TCP 三次握手是指建立 TCP 连接时,客户端和服务端需要进行三次通信,以确认双方的接收能力和发送能力是否正常。

  1. 发送端首先发送一个带SYN(synchronize)标志的数据包给接收方【第一次的seq序列号是随机产生的,这样是为了网络安全,如果不是随机产生初始序列号,黑客将会以很容易的方式获取到你与其他主机之间的初始化序列号,并且伪造序列号进行攻击】
  2. 接收端收到后,回传一个带有SYN/ACK(acknowledgement)标志的数据包以示传达确认信息【SYN 是为了告诉发送端,发送方到接收方的通道没问题;ACK 用来验证接收方到发送方的通道没问题】
  3. 最后,发送端再回传一个带ACK标志的数据包,代表握手结束若在握手某个过程中某个阶段莫名中断,TCP协议会再次以相同的顺序发送相同的数据包

1-14

什么是754层网络模型?

754网络模型及对应

OSI依层次结构来划分:应用层(Application)、表示层(Presentation)、会话层(Session)、传输层(Transport)、网络层(Network)、数据链路层(Data Link)、物理层(Physical)

1-13

什么是日志系统和日志门面?

日志系统是用来记录应用程序运行时的状态信息,比如错误日志、警告日志、调试日志等。

  • Log4j
  • Logback
  • Log4j2

日志门面是一种日志系统的抽象,它定义了一组日志系统的公共接口,以便于应用程序通过这组公共接口来记录日志,而不用关心具体的日志系统实现。

  • SLF4J
  • Commons Logging
  • Log4j-to-SLF4J

1-12

什么是 JWT?

JWT(JSON Web Token)是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于作为 JSON 对象在各方之间安全地传输信息。

通过非对称加密算法,可以对 JWT 进行签名,从而保证 JWT 的真实性和完整性。

1-11

Spring Security 的原理?

SpringSecurity 的核心是一个过滤器链,它由一系列的过滤器组成,每个过滤器负责一项安全控制功能,比如认证、授权、会话管理等。

1-10

什么是 Spring Security?

SpringSecurity 是基于 Spring 的安全框架,它提供了较为全面的一套安全性解决方案,并且可以与 SpringMVC、SpringBoot 等框架无缝集成。 它充分利用了依赖注入和 AOP 技术,可以将安全性应用到方法调用或 Web 请求上,为应用系统提供声明式的安全访问控制功能。

1-9

谈谈你对 CGLib 的理解?

JDK 动态代理机制只能代理实现接口的类,一般没有实现接口的类不能进行代理。使用 CGLib 实现动态代理,完全不受代理类必须实现接口的限制。

CGLib 的原理是对指定目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对 final 修饰的类进行代理。

CGLib 的调用流程就是通过调用拦截器的 intercept 方法来实现对被代理类的调用。而拦截逻辑可以写在 intercept 方法的 invokeSuper(o, objects);的前后实现拦截。

1-8

有哪些AOP Advice通知的类型?

  • 前置通知(Before advice) : 这些类型的 Advice 在 joinpoint 方法之前执行,并使用 @Before 注解标记进行配置。
  • 后置通知(After advice) : 这些类型的 Advice 在连接点方法之后执行,无论方法退出是正常还是异常返回,并使用 @After 注解标记进行配置。
  • 返回后通知(After return advice) : 这些类型的 Advice 在连接点方法正常执行后执行,并使用@AfterReturning 注解标记进行配置。
  • 环绕通知(Around advice) : 些类型的 Advice 在连接点之前和之后执行,并使用 @Around 注解标记进行配置。
  • 抛出异常后通知(After throwing advice) : 仅在 joinpoint 方法通过抛出异常退出并使用 @AfterThrowing 注解标记配置时执行。

1-7

AOP 包含的几个概念?

  • 切面(Aspect): 一个关注点的模块化,这个关注点可能会横切多个对象。
  • 连接点(Joinpoint): 程序执行过程中的某个特定的点,比如某方法调用的时候或者处理异常的时候。
  • 通知(Advice): 在切面的某个特定的连接点上执行的动作。
  • 切入点(Pointcut): 匹配连接点的断言,在 AOP 中通知和一个切入点表达式关联。
  • 引入(Introduction): 在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段。
  • 目标对象(Target Object): 被一个或者多个切面所通知的对象,也称为被通知(advised)对象。
  • 织入(Weaving): 把切面连接到其它的应用程序类型或者对象上,并创建一个被通知的对象,这些可以在运行期完成,也可以在编译期完成。

1-6

列举一些重要的Spring模块。

  • Spring Core:核心容器,提供 IoC 和 DI 的功能。
  • Spring AOP:面向切面编程,提供声明式事务管理。
  • Spring Aspects:提供与 AspectJ 的集成功能。
  • Spring JDBC:提供了 JAVA 数据库连接功能。
  • Spring Web:提供了基本的 Web 开发功能。
  • Spring MVC:提供了 MVC 模式的 Web 开发功能。
  • Spring ORM:提供了对常见的 ORM 框架的支持,如 Hibernate、JPA 等。
  • Spring Test:提供了对 JUnit 和 TestNG 的支持。
  • Spring Session:提供了对 Session 的集成支持。
  • Spring Security:提供了对安全认证和授权的支持。

1-5

什么是监听器?

监听器是 Servlet 规范中的一种组件,可以监听 ServletContext、HttpSession、ServletRequest 等域对象的创建和销毁,以及域对象中属性的变化。

配置示例:

java
public class MyListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        // ServletContext 创建时执行
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        // ServletContext 销毁时执行
    }
}

使用示例:

java
@Configuration
public class MyConfig {

    @Bean
    public ServletListenerRegistrationBean<MyListener> myListener() {
        return new ServletListenerRegistrationBean<>(new MyListener());
    }
}

1-4

什么是拦截器?

拦截器是 SpringMVC 的一种组件,可以在请求到达控制器之前或之后执行一些操作,比如记录日志、权限校验等。

配置示例:

java
public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 在请求到达控制器之前执行
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 在请求到达控制器之后,视图渲染之前执行
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 在视图渲染之后执行
    }
}

使用示例:

java
@Configuration
public class MyConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/hello");
    }
}

1-3

Spring Boot 的默认编码是?

SpringBoot 的默认编码是 UTF-8。可以通过 spring.http.encoding.charset 属性来修改编码。

1-2

Spring Boot 应用如何优雅关闭?

SpringBoot 应用可以通过 SpringApplication.exit() 方法来优雅关闭,该方法可以用在任何地方。

1-1

Spring Boot 怎么注册事件监听器?

SpringBoot 可以通过 @EventListener 注解来注册事件监听器,该注解可以用在方法上,也可以用在类上。