亚信科技Java后端外包一面

文章目录

1.List 有哪些实现,Arraylist 和LinkedList之间的区别是啥?

List是一个接口,继承了Collection。 实现类包括了三个,Vector、LinkedList、ArrayList 三个实现类。

三个类的创建方式

plain 复制代码
Vector<Integer> vector = new Vector<>();
ArrayList<Integer> arrayList = new ArrayList<>();
LinkedList<Integer> linkedList = new LinkedList<>();

从线程安全角度考虑:

Vector是线程安全的,其他两个都不是线程安全的。

Vector 方法上面都加上了synchroniozed关键字。是线程安全的

常用的是后面两个。

ArrayList 是基于数组实现了,LinkedList是基于双向链表实现的。

ArrayList: 插入效率高,但是需要扩容。 查找效率很高。 删除效率低

LinkedList 是基于双向链表的,插入效率高。 查找效率低

在多线程的情况下面,ArrayList中添加了1000个数字,但是最终只有995个,中间有五个数字消失了。

plain 复制代码
public static void main(String[] args) {
    List<Integer> list = new ArrayList<>();

    // 创建多个线程同时向 ArrayList 添加元素
    for (int i = 0; i < 1000; i++) {
        new Thread(() -> {
            list.add(1);
        }).start();
    }

    // 等待所有线程执行完成
    try {
        Thread.sleep(2000); // 简单等待2秒,实际项目中应使用更好的同步机制
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    // 输出 ArrayList 的大小,期望是1000,但由于线程不安全,结果可能不正确
    System.out.println("ArrayList size: " + list.size());
}

为什么会出现不一致的问题呢? 这个涉及到原子性的问题了,add方法 需要判断当前容量、插入到数组中下一个位置、修改当前的size。可以认为是散步,如果当前容量还有一个,两个线程同时进行判断容量之后,都插入到数组中的位置,此时其实就发生了问题。会出现覆盖或者遗漏现象。

解决线程安全问题

使用 Collections.synchronizedList 方法将 ArrayList 包装为一个线程安全的列表。

java 复制代码
List<Integer> list = Collections.synchronizedList (new ArrayList<>());

使用 CopyOnWriteArrayList,它是 java.util.concurrent 包的一部分,专为并发环境设计。

java 复制代码
 List<Integer> list = new CopyOnWriteArrayList<>();

2Redis的数据类型

Redis的基本数据类型,Redis有八种数据类型

基础的五种数据类型

string :用来存储字符串或者二进制的数据包括 片、音频等信息,存储验证码

set: 去重的set集合 ,去重校验、用户标签、共同好友

列表: list 列表 ,用来存储消息队列

Zset: 有序集合,给每一个成员关联一个分数,根据分数进行有序排列。 场景:排行榜

hash: 存储对象的多个属性。

bitmap: 基于字符串实现的位数组,可以进行位操作。 存储用户的点击、网页的浏览量

HyperLogLog: 用来处理大量数据的去重计算

  • 统计网站的独立访客数(UV)。

Geospatial: 地理空间,支持地理坐标和地理相关的查询。查找附近的餐馆、加油站。

3 Redis的内存淘汰策略

Redis的内存是有限制的,可以在配置文件中设置内存的大小。

java 复制代码
maxmemory 100mb    //指定最大内存为100mb

对于内存淘汰有下面几种策略:

1.不淘汰,最简单的不淘汰内存。

  1. 所有的键都使用LRU淘汰策略
  2. 带过期时间的使用LRU淘汰策略
  3. 所有键随机淘汰
  4. 带过期时间的键随机淘汰
  5. 带过期时间的优先淘汰
  6. 所有键使用LFU算法
  7. 带过期时间的键使用LFU算法

4.TCP和HTTP的区别,网络模型是哪七层模型

TCP是传输控制协议,在传输层,在两个端点之间提供了可靠的、面向连接、基于字节流的服务,保证数据按序到达并且无误。

HTTP是应用层的协议,HTTP是超文本传输协议,用来传输图片、文字、音频的协议。

TCP 需要通过三次握手建立连接、四次挥手释放连接。 对于可靠传输、流量控制、拥塞控制 还得复习。

HTTP 客户端发送请求,服务器返回HTTP响应。基本请求 get、delete、put、post请求。 这边又可以衍生出来好多关于计算机网络的问题。



网络模型包括了

应用层、 表示层、会话层、传输层、网络层、数据链路层、物理层。一共七层


  • 应用层处理具体的应用程序任务(如网页浏览、文件传输等)。
  • 表示层负责数据格式的转换、加解密等。
  • 会话层管理会话并确保对话的可靠性。
  • 传输层保证端到端的数据传输可靠性。
  • 网络层负责数据包的路由和转发。
  • 数据链路层确保数据在物理网络上传输时无误。
  • 物理层负责通过硬件实现比特流的传输。

5.Exception和Error有什么区别?

都是基础与Throwable,标识程序允许出现了异常。

exception: 标识程序出现是逻辑上面的错误,可以被捕获进行处理,后序还是可以继续执行的。

受检 编译的时候就会被检查 sqlexception、ClassNotFoundException

非受检异常 允许时候会跑出来的,不需要显式的捕获或者声明。 通常是程序逻辑错误,比如 空指针、下标越界。

Error 是系统级别的错误,程序无法再运行的,比如 内存不足、栈移除、虚拟机错误等。

  • OutOfMemoryError:内存不足。
  • StackOverflowError:栈溢出。
  • VirtualMachineError:虚拟机错误(例如JVM崩溃)

6如何处理异常

在开发中使用全局异常处理器+自定义异常来处理。

设置全局异常处理器。

使用RestControllerAdvice 实现全局异常处理。

plain 复制代码
@RestControllerAdvice   
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public Result handleException(Exception ex) {
        return Result.error(ex.getMessage());
    }
}

自定义一个登录异常:

plain 复制代码
public class LoginException  extends RuntimeException{
    public LoginException() {
    }

    public LoginException(String message) {
        super(message);
    }

    public LoginException(String message, Throwable cause) {
        super(message, cause);
    }

    public LoginException(Throwable cause) {
        super(cause);
    }

    public LoginException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

7创建线程的方式

第一种创建线程的方式 继承Thread类,有个缺点是继承Thread之后就不能继承其他类了,因为Java是单继承机制。

java 复制代码
public class MyThread extends Thread{
    @Override
    public void run() {
        System.out.println("aaa");
    }

    public static void main(String[] args) {
        Thread thread=new MyThread();
        thread.start();
    }
}

第二种可以实现Runnable接口。

java 复制代码
public class MyRunnable implements Runnable{
    @Override
    public void run() {
        System.out.println("aa");
    }

    public static void main(String[] args) {
        Runnable runnable=new MyRunnable();
        Thread thread=new Thread(runnable);
        thread.start();
    }
}

通过线程池创建线程

java 复制代码
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("aa");
    }

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);

        for (int i = 0; i < 5; i++) {
            executorService.submit(new MyRunnable());
        }
        executorService.shutdown();
    }
}
  • **ExecutorService executorService = Executors.newFixedThreadPool(3);**
  • 创建一个固定大小的线程池,大小为 3。即线程池中最多只能同时有 3 个线程在执行任务。
  • **executorService.submit(new MyTask("Task-" + i));**
  • 使用 submit() 方法提交任务。任务会被线程池中的线程执行,执行结果会异步返回。

8涉及模式有哪些

涉及模式分类 创建型模式结构型模式行为型模式

常见的一些涉及

创建型模式(Creational Patterns)

这些模式主要关注对象的创建,提供了一种创建对象的方式,增加了代码的灵活性和复用性。

  1. 单例模式****(Singleton Pattern)
    • 目的:确保一个类只有一个实例,并提供一个全局访问点。
    • 应用场景:配置管理器、日志记录器等需要全局唯一实例的场景。
  2. 工厂方法模式****(Factory Method Pattern)
    • 目的:定义一个用于创建对象的接口,让子类决定实例化哪一个类。
    • 应用场景:需要在运行时决定创建哪个对象的场景。
  3. 抽象工厂模式****(Abstract Factory Pattern)
    • 目的:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
    • 应用场景:需要创建一系列相关对象的场景,如UI组件的不同风格。
  4. 建造者模式(Builder Pattern)
    • 目的:将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。
    • 应用场景:对象构建过程复杂,或者需要不同的表示方式的场景。
  5. 原型模式(Prototype Pattern)
    • 目的:通过复制现有的实例来创建新的实例,而不是通过新建操作。
    • 应用场景:创建对象的成本较高,或者需要大量类似对象的场景。
结构型模式(Structural Patterns)

这些模式主要关注类和对象的组合,通过继承和组合实现更大的结构。

  1. 适配器模式(Adapter Pattern)
    • 目的:将一个类的接口转换成客户希望的另一个接口,使得原本由于接口不兼容而无法一起工作的类可以一起工作。
    • 应用场景:需要使用现有类,但其接口与需求不符的场景。
  2. 装饰器模式(Decorator Pattern)
    • 目的:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰器模式比生成子类更为灵活。
    • 应用场景:需要动态地给对象添加功能,而不改变其结构的场景。
  3. 代理模式(Proxy Pattern)
    • 目的:为其他对象提供一种代理以控制对这个对象的访问。
    • 应用场景:需要在访问对象时进行控制或增强功能,如懒加载、安全控制等。
  4. 外观模式(Facade Pattern)
    • 目的:为子系统中的一组接口提供一个一致的高层接口,使子系统更易使用。
    • 应用场景:需要为复杂子系统提供简单接口的场景。
  5. 桥接模式(Bridge Pattern)
    • 目的:将抽象部分与实现部分分离,使它们可以独立变化。
    • 应用场景:抽象和实现需要独立扩展的场景。
行为型模式(Behavioral Patterns)

这些模式主要关注对象之间的通信和职责分配。

  1. 观察者模式(Observer Pattern)
    • 目的:定义对象间的一种一对多的依赖关系,当一个对象状态发生改变时,所有依赖于它的对象都会收到通知并自动更新。
    • 应用场景:事件处理系统、订阅-发布系统。
  2. 策略模式(Strategy Pattern)
    • 目的:定义一系列算法,并使它们可以互相替换,让算法独立于使用它的客户端。
    • 应用场景:需要在运行时选择不同算法的场景。
  3. 命令模式(Command Pattern)
    • 目的:将请求封装为对象,从而使你可以用不同的请求对客户进行参数化。
    • 应用场景:需要对操作进行排队、记录或撤销的场景。
  4. 责任链模式(Chain of Responsibility Pattern)
    • 目的:使多个对象都有机会处理请求,避免请求的发送者和接收者之间的耦合关系。
    • 应用场景:需要多个对象处理同一个请求的场景,如事件处理。
  5. 状态模式(State Pattern)
    • 目的:允许一个对象在其内部状态改变时改变其行为,对象看起来好像修改了它的类。
    • 应用场景:对象的行为依赖于其状态,且状态会改变的场景。
  6. 中介者模式(Mediator Pattern)
    • 目的:用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散。
    • 应用场景:对象之间关系复杂,直接交互会导致高度耦合的场景。
  7. 迭代器模式(Iterator Pattern)
    • 目的:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。
    • 应用场景:需要遍历不同集合的场景。

Spring中的设计模式包括了

1.单列模式,每一个Bean的作用域都是单列的,确保容器中只有一个bean。

2.工厂模式: 管理和创建对象实例,使得创建逻辑与使用逻辑分离。

3.代理模式 AOP切面编程,使用JDK的动态代理实现。

plain 复制代码
@Service
public class UserService {
    @Transactional
    public void createUser(User user) {
        // 用户创建逻辑
    }
}

Spring通过代理在createUser方法执行前后插入事务管理逻辑。

4.模板方法模式

Spring的JdbcTemplateJdbcTemplate简化了JDBC操作,封装了连接管理、异常处理等步骤,开发者只需关注具体的数据库操作逻辑。

9.Cookie和Session的区别是什么

在Web开发中,CookieSession都是用于在客户端和服务器之间维护状态信息的重要机制。由于HTTP协议本身是无状态的(每个请求都是独立的,服务器不会记住之前的请求),因此需要借助Cookie和Session来实现用户的会话管理和状态保持。

  • Cookie

  • 客户端存储:Cookie数据存储在用户的浏览器中,每次请求都会自动携带相关的Cookie信息发送到服务器。

  • Session

  • 服务器端存储:Session数据存储在服务器内存或持久化存储(如数据库)中,客户端只保存一个唯一的Session ID(通常通过Cookie传递)。

  • Cookie

  • 容量限制:每个Cookie的大小通常限制在4KB左右,不适合存储大量数据。

  • Session

  • 容量较大:Session存储在服务器端,可以存储较大和复杂的数据,几乎不受容量限制(受服务器资源约束)。

  • Cookie

  • 相对不安全 :由于Cookie存储在客户端,用户可以通过浏览器查看和修改Cookie内容,存在被篡改或盗用的风险。尽管可以使用HttpOnlySecure等标志来增强安全性,但仍需谨慎处理敏感数据。

  • Session

  • 相对安全:Session数据存储在服务器端,用户无法直接访问或修改,降低了敏感数据被泄露的风险。唯一暴露给客户端的是Session ID,虽然Session ID本身也需要保护(如防止会话劫持),但总体安全性更高。

  • Cookie

  • 可控的过期时间 :可以通过设置ExpiresMax-Age属性来定义Cookie的有效期,过期后自动删除。也可以设置为会话Cookie(关闭浏览器后自动删除)。

  • Session

  • 服务器端管理:Session的生命周期由服务器控制,通常基于用户活动的超时机制(如30分钟无操作则失效)。当用户关闭浏览器时,Session并不会立即失效,除非服务器配置了会话终止策略。

  • Cookie

  • 适用于

    • 存储少量非敏感数据,如用户偏好设置、记住用户名等。
    • 实现"记住我"功能,保持用户登录状态。
    • 跟踪用户行为(需注意隐私和合规性)。
  • Session

  • 适用于

    • 存储敏感数据,如用户认证信息、购物车内容等。
    • 需要在多个页面之间共享复杂的数据结构。
    • 实现用户会话管理,保持用户在整个访问过程中的状态。

分布式系统中使用session较为复杂。现在一般都是使用JWT令牌。

10.数据库中索引的种类

数据库中的索引主要有

B+树: 大部分都是支持b+树索引的,三层就可以存储千万级别的数据,查找效率很高。

hash索引 只支持精确查找,不支持范围查找。

R-tree(空间索引) 空间索引是MyISAM引擎的一个特殊索引类型,主要用于地理空间数据类

型,通常使用较少

Full-text索引:是一种通过建立倒排索引,快速匹配文档的方式。

11.聚簇索引和非簇索引的区别

聚簇索引决定了数据在磁盘上的物理存储顺序,每一张表只能有一个聚簇索引。

**叶子节点包含数据:在聚簇索引的B树结构中,叶子节点直接存储数据行。 **


非聚簇索引不决定数据在磁盘上的物理存储顺序。它们是独立于数据表的结构,包含索引列的值和指向实际数据行的指针(如行地址或聚簇索引键)。

在非聚簇索引的B树结构中,叶子节点存储索引列的值和指向数据行的指针。 这个指针就是主键ID,这个时候就需要发生回表查询

name是非聚簇索引,b+树中叶子节点存储的是id值,还需要到聚簇索引中去查找一遍,这个过程叫做回标。

12.左连接的关键字是什么 左连接和右连接有什么区别

左外连接的关键字是 left join

左外连接相当于查询表1(左表)的所有数据,当然也包含表1和表2交集部分的数据。

SELECT 字段列表 FROM 表1 LEFT [ OUTER ] JOIN 表2 ON 条件 ... ;

外连接相当于查询表2(右表)的所有数据,当然也包含表1和表2交集部分的数据。

SELECT 字段列表 FROM 表1 RIGHT [ OUTER ] JOIN 表2 ON 条件 ... ;

  • 左连接(LEFT JOIN) :保留左表(<font style="color:rgb(52,73,94);">FROM</font> 子句中指定的第一个表)的所有记录,即使右表中没有匹配的记录。
  • 右连接(RIGHT JOIN) :保留右表(<font style="color:rgb(52,73,94);">JOIN</font> 子句中指定的第二个表)的所有记录,即使左表中没有匹配的记录。

13.HashMap底层的数据结构

hashmap也是经常考察的内容

https://blog.csdn.net/qq_37084904/article/details/109243886

14.如何遍历一个HashMap

相关推荐
夏天的味道٥3 小时前
使用 Java 执行 SQL 语句和存储过程
java·开发语言·sql
冰糖码奇朵5 小时前
大数据表高效导入导出解决方案,mysql数据库LOAD DATA命令和INTO OUTFILE命令详解
java·数据库·sql·mysql
好教员好5 小时前
【Spring】整合【SpringMVC】
java·spring
浪九天6 小时前
Java直通车系列13【Spring MVC】(Spring MVC常用注解)
java·后端·spring
堕落年代6 小时前
Maven匹配机制和仓库库设置
java·maven
功德+n6 小时前
Maven 使用指南:基础 + 进阶 + 高级用法
java·开发语言·maven
香精煎鱼香翅捞饭7 小时前
java通用自研接口限流组件
java·开发语言
ChinaRainbowSea7 小时前
Linux: Centos7 Cannot find a valid baseurl for repo: base/7/x86_64 解决方案
java·linux·运维·服务器·docker·架构
囧囧 O_o7 小时前
Java 实现 Oracle 的 MONTHS_BETWEEN 函数
java·oracle
去看日出7 小时前
RabbitMQ消息队列中间件安装部署教程(Windows)-2025最新版详细图文教程(附所需安装包)
java·windows·中间件·消息队列·rabbitmq