秋招突击——8/6——万得数据面试总结

文章目录

    • 引言
    • 正文
      • 面经整理一
        • 1、讲一下java的多态,重载,重写的概念,区别
        • 2、说一下Java的数组,链表的结构,优缺点
        • 3、创建java线程的方式有哪些,具体说说
        • 4、创建线程池呢、每个参数的意义
        • 5、通过那几种方式保证线程安全
        • 6、jvm加载
        • 7、了解数据库事物?特性?
        • 8、怎么提高sql查询性能 (只说了添加索引,分库分表)
        • 9、String特性是什么
        • 10、redis数据类型
        • 11、redis持久化 答了(AOF,RDB)接着问了他们之间的区别
      • 面经整理二
        • 1、spring是怎么实现aop的
        • 2、aop的原理
        • 3、用户通过客户端或者浏览器发送请求,在springboot框架下是如何接收这个请求、解析并向下透传到control层的
        • 4、mysql的底层结构
        • 5、索引分为哪几个类型
        • 6、以非聚簇索引作为一个查询条件,去获取到整条记录的中间过程是什么
        • 7、建索引要满足哪些原则
        • 8、hashmap扩容的过程
        • 9、synchronized和可重入锁有哪些区别
        • 10、线程安全的集合concurrenthashmap是如何保证线程安全的
        • 11、java的内存分布
        • 12、1.8的jvm默认的两个垃圾回收器是哪两个,区别是什么
        • 13、有一个web服务的接口,刚上线的时候没有什么问题,突然一段时间后客户端调用该接口,该接口的反馈都是超时,如何定位这个服务的问题
      • 正式面试
        • 第一面
          • A面
          • B面
            • ThreadLocal了解吗?如何防止内存泄漏?
            • 如何对复杂对象进行深拷贝?
            • SpringAOP的实现过程
    • 笔试
    • 总结

引言

  • 今天要面试万得数据,上午在整理项目相关的问题,看相关的代码,现在整理一下面经,毕竟下午两点钟就要开始的!

正文

面经整理一

作者:网抑云八级选手
链接:https://www.nowcoder.com/feed/main/detail/a44af7a275754bc0a200fcc9778d64c0?sourceSSR=search
来源:牛客网

1、讲一下java的多态,重载,重写的概念,区别

多态

  • 同一个接口或者基类可以指向不同的实现或子类对象,编写更加通用和灵活的代码
    • 编译时多态(静态多态):通过方法重载实现。
    • 运行时多态(动态多态):通过方法重写和接口实现。

重载

  • 重载是指在同一个类中,可以有多个同名的方法但它们的参数列表不同(参数的数量或类型不同)。重载是编译时多态的一种形式
  • 主要特点
    • 方法名相同
    • 参数列表不同(参数的数量或类型不同)。
    • 可以有不同的返回类型
    • 可以有不同的访问修饰符

重写

  • 重写是指子类提供了与父类中同名方法的实现
  • 重写是运行时多态的一种形式。通过重写,子类可以提供特定的实现,而不是使用父类的实现
  • 主要特点
    • 方法名、参数列表、返回类型必须相同。
    • 访问修饰符不能比父类的更严格(可以更宽松)。
    • 子类方法不能比父类方法抛出更多或更广泛的异常。

区别

  • 多态:同一个接口或者基类可以多种实现
  • 重载:在同一个类中,同名方法有不同的参数列表,是编译时多态
  • 重写:子类提供与父类同名方法的实现,运行时多态
2、说一下Java的数组,链表的结构,优缺点

数组

  • 一种线性数据结构,用于存储相同类型元素的集合
  • 数组在内存中是连续分配的,所有元素的大小相同,可以通过索引快速访问。
  • 优点
    • 快速访问:由于数组元素在内存中是连续存储的,可以通过索引在O(1)时间复杂度内直接访问任意元素。
    • 节省内存:没有额外的存储开销(如指针)。
    • 缓存友好:由于数组元素连续存储,使用缓存时效率更高。
  • 缺点
    • 固定大小:数组的大小在创建时必须确定,之后不能改变。这可能导致内存浪费或不够用。
    • 插入和删除效率低:在数组中插入或删除元素需要移动大量元素,时间复杂度为O(n)。
    • 不适合频繁插入和删除操作:由于上述原因,数组不适合在中间频繁进行插入和删除操作。

链表

  • 一种线性数据结构,由一系列节点(Node)组成每个节点包含数据和指向下一个节点的引用(或指针)

  • 根据节点之间的连接方式,链表可以分为单向链表(Singly Linked List)和双向链表(Doubly Linked List)

  • 优点

    • 动态大小:链表可以根据需要动态增长或缩小,不需要预先分配固定大小。
    • 插入和删除操作高效:在链表中插入或删除元素不需要移动其他元素,只需修改指针即可,时间复杂度为O(1)(在已知位置的情况下)。
    • 适用于频繁插入和删除操作:尤其是在中间插入或删除时,链表比数组更高效。
  • 缺点

    • 访问速度慢:由于无法通过索引直接访问元素,必须从头节点开始逐个遍历,时间复杂度为O(n)。
    • 额外的内存开销:每个节点除了存储数据,还需要存储指针,这会占用额外的内存。
    • 缓存不友好:由于链表元素在内存中不是连续存储的,使用缓存时效率较低。
3、创建java线程的方式有哪些,具体说说

继承Thread类

  • 结构
    • 通过继承Thread类并重写run方法来创建线程
  • 步骤
    • 创建一个继承自Thread类的子类。
    • 在子类中重写run方法,将线程的执行逻辑写在run方法中。
    • 创建该子类的实例,并调用start方法启动线程。

实现Runnable接口

  • 结构

    • 通过实现Runnable接口并将其传递给Thread类来创建线程。
  • 步骤

    • 创建一个实现Runnable接口的类。
    • 在类中实现run方法,将线程的执行逻辑写在run方法中。
    • 创建该类的实例,并将其作为参数传递给Thread对象。
    • 调用Thread对象的start方法启动线程。

。。。

总结

  • 继承Thread类:简单直接,但不支持多继承。
  • 实现Runnable接口:推荐使用,符合Java单继承多实现的特性。
  • 使用Callable和Future:适用于需要返回结果或抛出异常的任务。
  • 使用ExecutorService框架:适用于需要高效管理线程池的场景。
4、创建线程池呢、每个参数的意义
5、通过那几种方式保证线程安全
6、jvm加载
7、了解数据库事物?特性?
8、怎么提高sql查询性能 (只说了添加索引,分库分表)
  • 优化查询语句

    • 避免SELECT *,尽量只查询需要的列
    • 使用WHERE条件筛选数据,减少返回的数据量
    • 避免在WHERE子句中使用函数,使用函数会导致无法使用索引,从而降低查询性能。
  • 索引优化

    • 创建合适的索引
    • 使用覆盖索引
  • 数据库分区

    • 使用分区表:将大表按照某个字段(如日期、ID范围)进行分区,减少单个分区的数据量,提高查询性能。
  • 数据库配置优化

    • 调整数据库配置:根据实际需求调整数据库的内存分配、缓存大小、连接数等配置参数,提高整体性能。
9、String特性是什么

不可变性(Immutability)

  • 在Java中,String对象是不可变的。一旦创建,字符串的值就不能更改。如果需要修改字符串,则会创建一个新的字符串对象。

字符串池(String Pool)

  • Java使用字符串池来优化字符串的存储和管理。当你创建一个字符串字面量时,JVM会先检查字符串池中是否存在相同的字符串如果存在,则返回对该字符串的引用;如果不存在,则在池中创建新的字符串

字符串连接(Concatenation):

  • Java支持使用+操作符进行字符串连接,也可以使用StringBuilder或StringBuffer来提高性能。StringBuilder和StringBuffer是可变的,并且提供了对字符串的高效修改操作。
10、redis数据类型
11、redis持久化 答了(AOF,RDB)接着问了他们之间的区别

面经整理二

作者:MO小天才
链接:https://www.nowcoder.com/feed/main/detail/363997511497459ea21b12aa686439d7?sourceSSR=search
来源:牛客网

1、spring是怎么实现aop的
  • 一种用于分离关注点的技术,特别是在横切关注点(如日志记录、事务管理、权限控制等)方面。Spring AOP的实现主要基于代理模式。

  • 切面(Aspect)

    • 面是横切关注点的模块化表现,是通知(advice)和切入点(pointcut)的结合
  • 通知(Advice)

    • 通知是在切入点上执行的操作常见的通知类型包括前置通知(before)、后置通知(after)、返回通知(after returning)、异常通知(after throwing)和环绕通知(around)。
  • 切入点(Pointcut)

    • 切入点定义了通知应当应用到哪些连接点(Join Points)。通常使用AspectJ表达式语言来定义切入点。
  • 目标对象(Target Object)

    • 目标对象是被通知的对象,即那些包含核心业务逻辑的方法被AOP框架拦截的对象
  • 代理(Proxy)

    • 代理是AOP框架创建的对象,它被用来代替目标对象代理对象负责拦截方法调用,并在适当的时间执行通知
  • 织入(Weaving)

    • 织入是将切面应用到目标对象并创建代理对象的过程。Spring AOP在运行时通过动态代理或CGLIB代理进行织入。
2、aop的原理
  • Spring AOP通过动态代理(JDK动态代理和CGLIB代理)实现了AOP的功能使得我们可以在不修改业务代码的情况下将横切关注点(如日志记录、事务管理等)应用到目标对象的方法上
3、用户通过客户端或者浏览器发送请求,在springboot框架下是如何接收这个请求、解析并向下透传到control层的

1、接收请求

  • 当用户发送HTTP请求时,嵌入式服务器会受到请求

2、请求解析

  • 将请求传递给Servlet容器进行解析,变成HttpServletRequest和HttpServletResponse对象

3、拦截请求

  • DispatcherServlet,它是Spring MVC的前端控制器,负责处理所有进来的HTTP请求。
  • 映射到所有路径(/),因此它会拦截所有请求

4、映射控制器

  • 会根据请求的URL和HTTP方法(GET、POST等),通过HandlerMapping找到相应的处理器
  • HandlerMapping的工作是将请求映射到具体的控制器类和方法上。

5、调用控制器方法

  • DispatcherServlet会使用HandlerAdapter调用控制器方法
    • 控制器方法通常使用@RequestMapping或其他映射注解(如@GetMapping、@PostMapping等)来指定URL路径和请求方法

6、处理请求并返回响应对象

  • 控制器方法处理请求,并返回一个响应对象,一般是调用service层的处理业务逻辑,并将结果返回

7、返回给客户端

  • 响应返回给Servlet容器,Servlet容器将响应发送回客户端
4、mysql的底层结构
5、索引分为哪几个类型
6、以非聚簇索引作为一个查询条件,去获取到整条记录的中间过程是什么

1. 在非聚簇索引中查找键值

  • 查找索引键:、
    • 数据库引擎在非聚簇索引的 B+ 树中查找符合查询条件的索引键
  • 获取聚簇索引键
    • 找到匹配的索引键后,获取指向实际数据记录的指针或聚簇索引键值

2. 在聚簇索引中查找完整记录

  • 查找数据记录
    • 使用从非聚簇索引中获取的聚簇索引键值,在聚簇索引的 B+ 树中查找完整的数据记录。
  • 返回完整记录
    • 找到对应的叶节点后,提取并返回完整的数据记录
7、建索引要满足哪些原则
8、hashmap扩容的过程

触发条件

  • 容量(capacity):HashMap桶(bucket)数组的当前大小。
  • 负载因子(load factor):当HashMap的元素数量超过capacity * load factor时触发扩容。默认负载因子为0.75。

扩容过程

  • a. 计算新容量

    • HashMap扩容时,新容量通常是旧容量的两倍。扩容后,新容量和新阈值会重新计算。
  • b. 创建新桶数组

    • 创建一个大小为新容量的新的桶数组
  • c.重新分配元素

    • 将旧桶数组中的所有元素重新计算哈希并分配到新桶数组中。由于容量的变化,元素的位置可能会发生变化。
    • 链表节点重新分配旧桶数组中存在链表时,需要对链表节点重新分配。根据节点的哈希值决定其在新桶数组中的位置。如果节点的哈希值与旧容量进行按位与运算结果为0,则其放置在新桶中的原位置,否则放置在原位置加上旧容量的位置。
  • 更新HashMap的引用和阈值

    • 将HashMap的桶数组引用更新为新的桶数组,并更新阈值。
9、synchronized和可重入锁有哪些区别
10、线程安全的集合concurrenthashmap是如何保证线程安全的
  • 分段锁
    • 减少锁争用,提高并发性能。
  • CAS 操作和自旋锁
    • 保证原子性和线程安全。
  • 细粒度锁
    • 对每个桶进行锁定,允许更多并发操作。
  • 树化和链化
    • 提高哈希冲突处理效率,每一个桶的链表长度超过阈值,转为红黑树,提高查找和出入效率
  • 无锁读操作
    • 提高并发读性能。
  • 高效扩容
    • 分批次进行扩容,减少性能影响。
11、java的内存分布
  • 堆(Heap):存储所有对象实例和数组,分为年轻代和老年代。
  • 栈(Stack):每个线程都有自己的栈,存储局部变量、方法调用等信息
  • 方法区(Method Area):存储类的元数据、静态变量、常量池等。在Java 8之后称为元空间(Metaspace)。
  • 程序计数器(PC Register):指示当前线程执行的字节码位置。
  • 本地方法栈(Native Method Stack):为虚拟机执行本地方法服务。
12、1.8的jvm默认的两个垃圾回收器是哪两个,区别是什么
  • 1. Parallel GC(并行垃圾回收器)

    • 特点
      • 年轻代收集:使用多线程的复制算法(copying)
      • 老年代收集:使用多线程的标记-压缩算法(mark-compact)
      • 多线程:使用多个线程同时进行垃圾回收操作,适用于多核 CPU,提高垃圾回收效率
      • 吞吐量优先:Parallel GC 设计的目标是最大化吞吐量,最小化垃圾回收对应用程序的影响时间
  • 2. G1 GC(Garbage-First Garbage Collector)

    • 特点
      • 分区:将整个堆内存划分为多个相等大小的独立区域(Region),每个区域可以充当 Eden、Survivor 或 Old 区
      • 混合收集年轻代和老年代一起进行收集(mixed collection),在一次垃圾回收过程中,既回收年轻代,又回收部分老年代
      • 并发标记G1 GC 使用并发标记阶段来标记存活对象,从而减少应用程序暂停时间。
      • 停顿时间目标:允许用户指定期望的停顿时间,通过调优停顿时间目标来满足应用程序的低延迟要求。
13、有一个web服务的接口,刚上线的时候没有什么问题,突然一段时间后客户端调用该接口,该接口的反馈都是超时,如何定位这个服务的问题
  • 1. 检查服务器资源
  • 2. 检查应用日志
  • 3. 检查数据库性能
    • 慢查询
    • 连接池耗尽
    • 锁争用
  • 4、检查外部依赖是否正常
    • 缓存服务器
    • 消息队列
  • 5、分析网络问题
    • 网络延迟
    • 防火墙和负载均衡器
  • 6、重现问题
    • 尝试在本地或者测试环境中,重现则个问题,以便更容易调试和分析

正式面试

第一面
A面
  • 1、重点介绍一下个人项目

    • 说的过于琐碎,没有必要,需要概括一下,重点说出你的要点,而不是很细致地完全讲出来,没有必要!
    • 重点介绍Java相关的项目
  • 2、浮点数了解吗?怎么实现的

    • 浮点数的实现主要是基于科学计数法,有以下四部分构成,分别是
      • 符号位:0正数,1负数
      • 基数:使用二进制表示
      • 指数:表示基数应该乘以多少次幂,可以是正数或者负数
      • 尾数:有效位数
    • 特殊
      • 不能表示所有数字,涉及小数比较时,需要处理小数误差
      • 正零和负零
      • 无穷大:超出表示范围的数字
      • NaN:未定义或者不确定地结果
  • 3、给你一个数组,数组里面全部是数字,然后再给你一个s表示窗口的大小,从最左侧滑动,然后滑动到最右侧,求取每一次移动的滑动窗口平均值,你计算一下滑动窗口的最小值?并计算一下的时间复杂度和空间复杂度

    • 想不出更好的做法,只能使用模拟的方式实现,维护滑动窗口的sum,然后每一次计算一次平均值,比较平均值的最最优值。
    • 时间复杂度是O(n),空间复杂度是O(1).
B面
  • 1、简单的自我介绍

    • 项目介绍太过繁琐,很多细节不需要,只需要说你做了什么项目,大概概括一下!项目就说做了什么,然后你有哪些工作,然后总结一下,没有必要面面俱到,什么都说。
  • 项目上线了吗?

    • 并没有上线,在等进一步审核。
  • 系统的准确率是多少

    • 分情况说,比较真实。
  • 针对这种情况有什么其他的优化方案吗?

    • 拓宽信息模态
    • 更换信息收集场景
  • 这个项目是基于大语言模型的,谁在维护和训练?

    • 使用开源大语言模型的API直接调用的,并没有的自己训练一个大语言模型
  • 说一下ThreadLocal的使用?怎么防止内存泄露

    • ThreadLocal是的key是弱引用,但是他的value会强引用,通过调用对应的set等方法会自动回收不再使用value,但是线程不再被使用,不再调用对应方法就不会进行内存回收,导致内存泄漏
    • 如何避免内存泄漏
      • 先获取到 ThreadLocalMap 这个引用的,并且调用了它的 remove 方法,手动调用remove方法,防止内存泄漏
  • MySQL中聚簇索引和非聚簇索引有什么区别

    • 聚簇索引

      • 聚簇索引决定了磁盘上的存储顺序,同时聚簇索引的叶子节点包含了完整的数据行,查询聚簇索引无需额外查询数据
      • 主键默认创建为聚簇索引,如果没有指定主键,会选择一个唯一非空索引作为聚簇缩影。
    • 非聚簇索引

      • 非聚簇索引是单独的索引结构,叶子节点不包含数据行,而是包含了指向数据行的指针
      • 非聚簇索引和数据的存储顺序无关,非聚簇索引的叶子节存储的是数据行的位置或者主键位置,通常需要二次查找。
  • 建表的时候,没有指定任何列作为他的主键,会创建的主键索引吗?

    • 首先,检查表中是否存在唯一非空的索引,有就将其作为主键索引
    • 然后,如果表中没有主键,没有唯一索引,自动生成一个6字节长的隐藏主键列,不可见无法访问
  • InnoDB引擎默认的隔离级别是什么?这个隔离级别会带来问题?做了哪些操作来尽量缓解这个问题?

    • 可重复读,解决了脏读和不可重读,但是还是存在部分幻读
    • 如何解决幻读的问题
      • 提供了两种查询方式的,分别是快照读和当前读,都会产生幻读
      • 针对快照读,使用MVCC来解决幻读问题,第一次查询生成一个readview,然后在当前事务中都使用相同的readview,保证结果相同。
      • 针对当前读,依靠行级锁中的间隙锁来实现
      • 但并不能完全避免,一般是没有加上对应的for update
  • SpringAOP的实现过程

    • 用于在不修改代码的情况下,动态地将某些行为应用到特定的方法或者类上。主要是基于动态代理和字节码操作实现。
    • 定义一个切面类,这个切面类中要指明增强的方式是@Before还是@AfterReturning等,同时指定对应地切点,然后定义具体的需要额外执行的逻辑和行为。
    • 主要是定义通知类和配置类,具体编程实现如下

在这里插入图片描述

  • 第二阶段会有一个算法题,HR会通知你的。
ThreadLocal了解吗?如何防止内存泄漏?

资料来源
ThreadLocal介绍

  • 应用场景
    • ThreadLocal用作保存每一个线程独享的对象,每一个线程都创建一个副本,这样每一个线程都可以修改自己所拥有的副本,不会影响其他线程的副本,确保线程安全
      • 保存线程不安全的工具类,典型需要使用的类是SimpleDataFormat
    • ThreadLocal 用作每一个线程内需要独立保存信息,以便供线程内其他方法更方便地获取该信息场景。线程内每个方法获取到的信息是不一样的,前面执行的方法保存了信息后,后续方法可以通过ThreadLocal获取,避免传参,类似线程内的全局变量。
    • 保存业务的一些内容,比如说在拦截器中获取用户的信息,可以让不同方法直接使用,避免了传递参数麻烦

在这里插入图片描述

ThreadLocal可以用来解决共享资源的多线程访问的问题吗?

  • 不是,ThreadLocal 并不是用来解决共享资源问题的。虽然 ThreadLocal 确实可以用于解决多线程情况下的线程安全问题,但其资源并不是共享的,而是每个线程独享的

ThreadLocal和Synchronized关系?

  • ThreadLocal 是通过让每个线程独享自己的副本,避免了资源的竞争。
  • synchronized 主要用于临界资源的分配,在同一时刻限制最多只有一个线程能访问该资源。

ThreadLocal、Thread和ThreadLocalMap的关系

  • 一个Thread有一个ThreadLocalMap,而ThreadLocalMap的key就是一个一个ThreadLocal

防止内存泄漏

  • 内存泄漏
    • 当某一个对象不在有用时,占用的内存却不能被回收,是内存泄漏
  • 引用分析
    • ThreadLocal中的key是弱引用,如果不在引用了,垃圾回收机制能够成功收回
    • ThreadLocal中value是强引用,如果某一个Thread长时间运行,并且某一个Thread不再被使用,那么这个value就会内存泄漏,没法被垃圾回收
      • set、remove和rehash都会刷新key-value,如果key为null,会自动回收对应的value,但是如果不调用就没有办法刷新了
  • 如何避免内存泄漏
    • 先获取到 ThreadLocalMap 这个引用的,并且调用了它的 remove 方法,手动调用remove方法,防止内存泄漏
如何对复杂对象进行深拷贝?
  • 实现 Cloneable 接口并重写 clone() 方法
    • 通过实现 Cloneable 接口并重写 clone() 方法,可以对对象进行深拷贝
  • 使用序列化进行深拷贝
    • 通过将对象序列化为字节流然后反序列化,可以实现深拷贝。
  • 递归实现深拷贝
    • 通过自定义的递归方法,我们可以实现对复杂对象的深拷贝。此方法适用于对象嵌套结构较为复杂的情况。
SpringAOP的实现过程
  • 一种用于分离关注点的技术,特别是在横切关注点(如日志记录、事务管理、权限控制等)方面。Spring AOP的实现主要基于代理模式。

  • 切面(Aspect)

    • 面是横切关注点的模块化表现,是通知(advice)和切入点(pointcut)的结合
  • 通知(Advice)

    • 通知是在切入点上执行的操作常见的通知类型包括前置通知(before)、后置通知(after)、返回通知(after returning)、异常通知(after throwing)和环绕通知(around)。
  • 切入点(Pointcut)

    • 切入点定义了通知应当应用到哪些连接点(Join Points)。通常使用AspectJ表达式语言来定义切入点。
  • 目标对象(Target Object)

    • 目标对象是被通知的对象,即那些包含核心业务逻辑的方法被AOP框架拦截的对象
  • 代理(Proxy)

    • 代理是AOP框架创建的对象,它被用来代替目标对象代理对象负责拦截方法调用,并在适当的时间执行通知
  • 织入(Weaving)

    • 织入是将切面应用到目标对象并创建代理对象的过程。Spring AOP在运行时通过动态代理或CGLIB代理进行织入。
  • Spring AOP通过动态代理(JDK动态代理和CGLIB代理)实现了AOP的功能使得我们可以在不修改业务代码的情况下将横切关注点(如日志记录、事务管理等)应用到目标对象的方法上

笔试

对于必胜的理解

  • 对于序列a而言,其中的元素[a1,a2,a3,a4,a5]等,要是必赢的情况下,随便取出来一个数字ax,使得剩下元素的最大值amax和amin的累加和 大于等于 target,但是最大值不能大于等于target,只要能够是这种情况,那么先手肯定是必胜的。
  • 如果是这种只能够报数三次的情况,肯定能够判定出来的。当前方选什么才能让后方必输
  • 但是如果当前报数并不能立刻判定出能否获胜的话,就不好判定了!

A和B都会按照最优的方式报数

  • 如果轮到A,只要A能够赢,或者说存在必赢的方案,一定会选择必赢的方案
  • 如果轮到B,只要B能够赢,或者说存在必赢的方案,一定会选择必赢的方案
  • 言外之意,就是A每一次做出决定之前,都要判定会不会给B带来必赢的局面,如果能够给B带来必赢的局面,就不选当前方案

能否通过动态规划实现

  • 如果使用动态规划实现,必须能够使用集合的语言进行表达,但是这个题目不知道怎么用集合的语言表达。
  • 我应该还是会使用回溯实现!

回溯条件

  • 如果无论A选什么,B都存在必胜的条件,那么就返回false
  • 如果无论A选了某个分支,B无论选了什么,那么就返回true

具体实现代码

import java.io.FilterOutputStream;
import java.util.*;/*** @author Long Guo* @create 2024-08-10-14:32*///TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
public class Main {// 定义不同的状态表示当前是谁在报数static boolean A = true;static boolean B = false;static List<Integer> list;   // 能够报的数字的列表static Map<Integer, Boolean> cached;static boolean dfs(int target, boolean AorB, int cacheNum) {/** 具体含义:当前做选择的游戏玩家是否存在胜利的情况,存在返回true,不存在返回false* list表示剩余列表中所有能够选择的数字* target表示目标数值* AorB表示对应的角色,true表示为A先手,false表示B,后手* 基本思路:*    在所有搜索树中,总共有两种选择关系,分别是的由A到B和由B到A*        A选B:一旦所有B的情况中,有一种是B必胜的情况,那么就不能选,因为B一定会选必胜的情况,所以这里需要的将所有B可选的情况通过与&进行连接*        B选A:一旦所有的A的情况中,有一种的A必胜的情况,B就不会选,所以这里要选择全部是false的情况,也就是通过或进行连接,全部为false的情况*    最终通过回溯,判定当前节点下是否存在A必胜的情况*/// 临界条件,必赢状况,这里需要特殊处理,如果是B的回合,那就是A必输的情况int m = list.size();if (list.get(m - 1) >= target) return true;// 分情况遍历所有可能地选择boolean flag;for (int i = 0; i < m; i++) {int curNum = cacheNum | (1 << list.get(i));if (cached.containsKey(curNum)) flag = cached.get(curNum);else {int tempNum = list.get(i);int tempTar = target - tempNum;list.remove(i);flag = dfs(tempTar, !AorB, curNum);cached.put(curNum, flag);list.add(i, tempNum);}if (!flag) return true;}return false;}static boolean isAlwaysWin(int N, int Target) {for (int i = 0; i < N; i++) {int cacheNum = 0 | (1 << i + 1);int tempNum = list.get(i);int tempTar = Target - tempNum;list.remove(i);if (!dfs(tempTar, B, cacheNum)) return true;list.add(i, tempNum);cached.put(cacheNum, false);}return false;}
//public static void main(String[] args) {// 处理输入输出
//        Scanner in = new Scanner(System.in);
//        String nInput = in.nextLine();
//        String targetInput = in.nextLine();
//        int n = Integer.parseInt(nInput.replaceAll("[^0-9]]",""));
//        int target = Integer.parseInt(targetInput.replaceAll("[^0-9]]",""));int n = 5;int target = 8;// 生成对应的可报数的列表list = new ArrayList<>();cached = new HashMap<>();for (int i = 1; i <= n; i++) list.add(i);// 这两种是一个特殊情况,刚好是需要顺次报完所有的数字的,偶数的话后手必胜,奇数的话A必胜if (n % 2 == 0 && target == (n + 1) * n / 2) System.out.println(false);else if (n % 2 == 1 && target == (n + 1) * n / 2) System.out.println(true);else// 正常需要迭代判断的情况System.out.println(isAlwaysWin(n, target));//
//        System.out.println(isAlwaysWinSingle(list,n,target));}
}

总结

  • 过不过再说哈,现在先写在这里!
  • 第一面还行,直接让我过了,说过两天给我发一道算法题,然后让我好好做一下!继续在准备,晚上去运动一下,然后接着看项目!加油!
    8/11
  • 今天晚上完成了wind数据的笔试,差不多花了四五个小时,然后想清楚了,也写完了。感觉还行,还能继续面试!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/450867.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

普通索引和唯一索引,应该怎么选择?

普通索引和唯一索引&#xff0c;应该怎么选择&#xff1f; 普通索引&#xff0c;不能保证字段的唯一性&#xff0c;所以普通索引会比唯一索引要多N次判断&#xff0c;比如判断下一条记录是否和目标相同。 InnoDB的数据其实是按页来取的&#xff0c;也就是说要拿到某一个数据&a…

AndroidStudio配置MQTT连接云平台EMQX

引言 本篇博客主要介绍mqtt和emqx配置连接实现数据收发&#xff0c;我会从基础的本机连接到手机和本机连接再到手机实现mqtt连接云平台&#xff0c;大家可以根据需要自行选择观看&#xff08;后面两个教程都建立在mqtt和emqx下载完成的基础上&#xff0c;若没有下载完成&#x…

黎巴嫩爆炸事件分析:硬件国产自主可控的意义

黎巴嫩近期发生的寻呼机爆炸事件&#xff0c;不仅对当地社会造成了冲击&#xff0c;也在全球范围内引发了对通信设备安全性的深刻反思。这一事件凸显了在全球化背景下&#xff0c;电子产品安全性的重要性&#xff0c;以及自主可控技术在保障国家安全和公共安全中的关键作用。 …

DataWhale10月动手实践——Bot应用开发task02学习笔记

一、Prompt工程 之前有接触过一些Prompt工程的内容&#xff0c;也做过一些简单的应用&#xff0c;比如使用langchain和Openai库自己搭建了一个助手项目&#xff0c;但是还从未关注过在智能体方面的Prompt。在这篇博客中&#xff0c;我会将我之前掌握的和在本次任务学习中掌握的…

【C++】在Windows中使用Boost库——实现TCP、UDP通信

目录 一、编译Boost库 二、TCP服务端 三、TCP客户端 四、UDP连接 一、编译Boost库 1. 先去官网下载Boost库源码 2. 点击下载最新的版本 下载Windows环境的压缩包&#xff0c;然后解压 3. 在解压后的目录路径下找到“bootstrap.bat” 打开控制台&#xff0c;在“bootstrap.…

ROS2 常用工具之Launch -- 启动管理工具

基于上一篇的action代码上继续&#xff0c;链接如上&#xff1a; ROS2 通信三大件之动作 -- Action-CSDN博客 参考链接&#xff1a;ROS2——教你写新版Launch文件 | 范子琦的博客 1、创建文件 src/action_moudle/launch/action_launch.launch.py 路径下创建文件action_lau…

腾讯六宫格本地识别,本地模型识别,腾讯六图识别

基于K哥爬虫昨天发的文章&#xff0c;特此训练了一版腾讯模型&#xff0c;效果不错&#xff0c;特此感谢K哥的指导&#xff0c;效果如下图: 有需求&#xff0c;有疑问的欢迎评论区点出

尚硅谷大数据Flink1.17实战教程-笔记04【Flink DataStream API】

尚硅谷大数据技术-教程-学习路线-笔记汇总表【课程资料下载】视频地址&#xff1a;尚硅谷大数据Flink1.17实战教程从入门到精通_哔哩哔哩_bilibili 尚硅谷大数据Flink1.17实战教程-笔记01【Flink 概述、Flink 快速上手】尚硅谷大数据Flink1.17实战教程-笔记02【Flink 部署】尚硅…

【Spring篇】初识之Spring的入门程序及控制反转与依赖注入

&#x1f9f8;安清h&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;【计算机网络】&#xff0c;【Mybatis篇】 &#x1f6a6;作者简介&#xff1a;一个有趣爱睡觉的intp&#xff0c;期待和更多人分享自己所学知识的真诚大学生。 文章目录 &#x1f3af;初始Spring …

【K8S系列】Kubernetes pod节点NotReady问题及解决方案详解【已解决】

Kubernetes 集群中的每个节点都是运行容器化应用的基础。当节点状态显示为 NotReady 时&#xff0c;意味着该节点无法正常工作&#xff0c;这可能会导致 Pod 无法调度&#xff0c;从而影响整个应用的可用性。本文将深入分析节点不健康的各种原因、详细的排查步骤以及有效的解决…

查看SQL执行计划 explain

查看SQL执行计划 explain explain使用方式 alter session set current_schematest; explain plan for sql语句; --并不会实际执行&#xff0c;因此生成的执行计划也是预估的 select * from table(dbms_xplan.display); explain使用场景 1.内存中没有谓词信息了&#xff0…

MySQL从入门到跑路

SQL语言 SQL&#xff08;Structured Query Language&#xff0c;结构化查询语言&#xff09;是用于管理和操作关系数据库的一种标准编程语言。 SQL分类&#xff1a; DDL(Data Definition Language)&#xff1a;数据定义语言&#xff0c;用于操作数据库、表、字段&#xff0c…

前端文件流导出

1、前端代码 ​ /** 导出 */ const handleExport async () > {let config {responseType: blob,headers: {Content-Type: application/json,},};const res await getTargetExport(config);const blob new Blob([res]);const fileName PK目标跟进导出列表.xls;const li…

SpringBoot整合Freemarker(一)

Freemarker和jsp一样是一个视图的引擎模板&#xff0c;其实所有的模板引擎的工作原理都是类似的&#xff0c;如下图&#xff1a; 接下来就具体讲解一下Freemarker的用法&#xff0c;参考手册&#xff1a;模板 数据模型 输出 - FreeMarker 中文官方参考手册 SpringBoot默认就…

【浏览器】如何正确使用Microsoft Edge

1、清理主页广告 如今的Microsoft Edge 浏览器 主页太乱了&#xff0c;各种广告推送&#xff0c;点右上角⚙️设置&#xff0c;把快速链接、网站导航、信息提要、背景等全部关闭。这样你就能得到一个超级清爽的主页。 网站导航       关闭 …

HarmonyOS NEXT和认证(在校生的大福利)

今天重点关注了一下HarmonyOS NEXT&#xff0c;也就是我们所说的纯血鸿蒙&#xff01; 根据官方的说法&#xff1a; 欢迎开发者进入HarmonyOS NEXT。暌违一年&#xff0c;HarmonyOS NEXT终于在万千开发者的期待下从幕后走向台前。 HarmonyOS NEXT采用全新升级的系统架构&#…

【Python】NumPy(一):数据类型、创建数组及基本操作

目录 ​NumPy初识 1.什么是NumPy&#xff1f; NumPy的应用 NumPy数据类型 Python基本数据类型 NumPy数据类型 NumPy数组 创建数组 1.使用numpy.array() 2.使用arange()方法创建 3.使用linspace()创建等差数列 4使用zeros()创建数组 5.使用ones()创建数组 6.利用…

Linux基本使用和程序部署

文章目录 一. Linux背景Linux发行版 二. Linux环境搭建Linux常见命令lspwdcdtouchcatmkdirrmcpmvtailvimgreppsnetstat管道 三. 搭建java部署环境安装jdk安装mysql部署Web项目到Linux 一. Linux背景 1969−1970年,⻉尔实验室的DennisRitchie和KenTompson开发了Unix操作系统. 他…

在Linux操作系统上安装NVM教程——CentOS 7/VMware 17版

目录 一、测试网络是否能上网 二、下载阿里云镜像 三、解决执行yum命令出现报错&#xff08;没有就跳过&#xff09; 四、下载NVM安装包 五、解压NVM安装包 六、安装Node 七、连接新的动态库 八、升级GLIBC版本 九、安装GCC 十、查看当前服务器CentOS版本 一、测试网…

[AWS云]kafka调用和创建

背景:因为因为公司的项目需要使用AWS的kafka&#xff0c;但是在创建和使用过程中都遇到了一些报错和麻烦&#xff0c;毕竟老外的东西&#xff0c;和阿里云、华为使用起来还是不一样。 一、创建&#xff08;创建的配置过程就略了&#xff0c;就是配置一下可用区、型号&#xff0…