首页 / 面试交流地
#

面试交流地

#
9070次浏览 164人互动
此刻你想和大家分享什么
热门 最新
2024-08-23 15:22
已编辑
华东师范大学 C++
柏楚测开一面
🕘 软件测试工程师(柏楚)/2024.08.23👥面试题目:1.  为什么还没做笔试?2. 下学期的学习工作安排?秋招的主要投递方向?3.  测试相关:    【测试理论】    · 软件测试的流程?    · 常见的黑盒测试方法有哪些?用场景法设计几个测试用例来测试一个鼠标。    · 白盒测试方法逻辑覆盖法中,判断覆盖、条件覆盖、判断-条件覆盖哪个方法的粒度最大?为什么?        · 一道题目:给定了一个简单的流程图,分别用判断覆盖和判断-条件覆盖设计测试用例。    【测试工具】    · 会用Postman和Jmeter吗?哪个更好用?    · 平时什么时候会用到python?熟悉pytest吗?    · 如果需要用pytest完成一个自动化测试任务,且需要快速交付,你会怎么做?4. 简历/项目相关:    · 看简历里有提到“熟悉测试用例编写方法”是什么意思?    · 项目中遇到的最大困难是什么,怎么解决的?    · 项目中的Flask框架和okhttp在使用中有什么困难/难点?难实现的技术细节?5. 应用题:    · 一道几何数学应用题(难度初中水平)    · 一道测试程序设计题:给定一个软件安装包和安装完成后的目录baseline,如何写一个程序验证安装后的目录是否和baseline一致?这个程序的输入和输出分别是什么?中间的处理流程包括什么?6. 反问环节    “对本次面试进行评价和提出建议?”    “公司的氛围怎么样?”🤔面试感受:面试官人很nice,看我判断-条件覆盖这块我不是很熟,进行了一些循循善诱。问的问题都是关于测试理论和应用的,一点编程都没有,感觉我后续应该加强这方面的学习。
柏楚电子一面7人在聊 查看22道真题和解析
点赞 评论 收藏
分享
2024-08-12 14:20
广东工业大学 Java
浩鲸科技面试
一笑而过2222:1. 对java了解过什么,学习过程中有啥对你印象深刻的 - 数据结构方面 - Java中的数据结构包括数组、链表、栈、队列、树(二叉树、红黑树等)、图、哈希表(如HashMap底层使用的哈希表结构)等。这些数据结构在不同的场景下有不同的应用。例如,数组适合随机访问,链表适合动态插入和删除操作。 - Spring相关 - Spring是一个开源的Java应用框架,它提供了很多功能,如依赖注入(DI)和面向切面编程(AOP)。它简化了Java企业级应用的开发,通过配置文件或注解的方式来管理对象之间的依赖关系,提高了代码的可维护性和可扩展性。 2. spring不可变是为了什么? - 在Spring中,一些对象被设计为不可变的主要原因包括: - 线程安全:不可变对象在多线程环境下是线程安全的,不需要额外的同步机制来保证数据的一致性。多个线程可以同时访问不可变对象,不会出现数据竞争和不一致的情况。 - 简化设计和维护:不可变对象的状态一旦确定就不能改变,这使得对象的行为更加可预测。在设计和维护大型系统时,更容易理解和推理对象的行为,减少了由于对象状态变化而带来的复杂性和错误。 - 缓存友好:不可变对象可以被安全地缓存,因为它们的值不会改变。这可以提高应用程序的性能,尤其是在频繁使用某些对象的情况下。 3. hashmap底层实现 - 结构基础 - HashMap底层是基于数组和链表(在Java 8中,当链表长度达到一定阈值时会转换为红黑树)实现的。它使用哈希函数将键(key)映射到数组的一个索引位置上,以实现快速的查找、插入和删除操作。 - 采用这种结构的原因 - 快速查找:通过哈希函数计算键的哈希值,可以快速定位到数组中的一个位置,平均情况下查找时间复杂度接近O(1)。如果没有哈希冲突(即不同的键计算出相同的哈希值),查找操作可以非常迅速。 - 动态扩展:数组可以根据需要动态扩展,以适应不断增加的键值对数量。当数组中的元素数量达到一定阈值时,会进行扩容操作,重新分配内存空间并重新计算键的哈希值,以保证哈希表的性能。 - 自动升级(Java 8中链表转红黑树)的原因和好处 - 原因 - 当链表过长时,查找操作的时间复杂度会退化为O(n),其中n是链表的长度。为了避免这种情况,当链表长度达到一定阈值(默认为8)且数组长度达到一定条件时,链表会转换为红黑树。 - 好处 - 红黑树是一种自平衡的二叉搜索树,它可以保证查找、插入和删除操作的时间复杂度在最坏情况下仍然是O(log n),大大提高了在哈希冲突较多情况下的查找性能。 4. 线程池了解过吗?说说线程池 - 概念和作用 - 线程池是一种用于管理和复用线程的机制。它预先创建一定数量的线程,并将这些线程保存在一个池中,当有任务需要执行时,从线程池中获取一个空闲的线程来执行任务,任务执行完成后,线程不会被销毁,而是返回线程池中等待下一个任务。这样可以避免频繁地创建和销毁线程,提高系统的性能和资源利用率。 - 8大参数问题 - 核心线程数(corePoolSize):线程池中的核心线程数量,这些线程即使在空闲状态也不会被销毁。 - 最大线程数(maximumPoolSize):线程池允许创建的最大线程数量,当任务队列已满且核心线程都在忙碌时,会创建新的线程直到达到最大线程数。 - 线程存活时间(keepAliveTime):当线程池中的线程数量超过核心线程数时,多余的线程在空闲状态下的存活时间。 - 时间单位(unit):用于指定线程存活时间的单位,如秒、分钟等。 - 任务队列(workQueue):用于存储等待执行的任务的队列。常见的任务队列有ArrayBlockingQueue(有界队列)、LinkedBlockingQueue(无界队列,默认容量为Integer.MAX_VALUE)、SynchronousQueue(同步队列,不存储任务,直接将任务交给线程执行)等。 - 线程工厂(threadFactory):用于创建新线程的工厂类,可以自定义线程的名称、优先级等属性。 - 拒绝策略(handler):当线程池和任务队列都已满,无法再接受新的任务时所采取的策略。常见的拒绝策略有AbortPolicy(直接抛出异常)、CallerRunsPolicy(由调用者所在的线程执行任务)、DiscardPolicy(直接丢弃任务)、DiscardOldestPolicy(丢弃任务队列中最旧的任务)等。 - 任务满了怎么办,等待队列问题 - 当任务队列已满且线程池中的线程数量达到最大线程数时,会根据所采用的拒绝策略来处理新的任务。如果是AbortPolicy,会直接抛出异常;如果是CallerRunsPolicy,由调用者所在的线程执行任务;如果是DiscardPolicy,直接丢弃任务;如果是DiscardOldestPolicy,丢弃任务队列中最旧的任务。 5. 使用锁的时候遇到了什么问题 - 共享区数据原子性问题(以常见的情况为例) - 当多个线程同时访问和修改共享区域的数据时,如果没有合适的锁机制,可能会出现数据不一致的情况。例如,两个线程同时对一个计数器进行加1操作,如果没有锁,可能会出现两个线程同时读取到相同的计数器值,然后各自加1,最终计数器只增加了1,而不是预期的2。使用锁可以保证在同一时刻只有一个线程能够访问和修改共享数据,从而保证数据的原子性和一致性。 6. 缓存穿透问题 - 概念 - 缓存穿透是指查询一个不存在的数据,由于缓存中没有该数据,所以会去数据库中查询。如果大量这样的请求同时发生,会给数据库带来很大的压力,甚至可能导致数据库崩溃。 - 布隆穿透器实现原理 - 布隆过滤器是一种数据结构,它由一个位数组和多个哈希函数组成。当一个数据要被判断是否存在时,会使用多个哈希函数对该数据进行哈希运算,得到多个哈希值,然后根据这些哈希值在位数组中查找相应的位置。如果所有位置都被标记为存在,那么该数据可能存在;如果有任何一个位置被标记为不存在,那么该数据一定不存在。这样可以在一定程度上避免缓存穿透,因为它可以快速判断一个数据是否可能存在于缓存中,而不需要每次都去数据库查询。 7. syc锁reen锁区别 - 我不确定这里“syc锁reen锁”是否是“synchronized锁和ReentrantLock锁”的错误表述,如果是,它们的区别如下: - synchronized锁 - 是Java中的内置锁机制,它是一种隐式锁,通过在方法或代码块前加上synchronized关键字来实现。它具有以下特点: - 简单易用:不需要显式地获取和释放锁,由Java虚拟机自动管理锁的获取和释放过程。 - 可重入性:一个线程可以多次获取同一个synchronized锁,不会造成死锁。例如,一个线程在进入一个synchronized方法后,如果在方法内部又调用了另一个synchronized方法,它可以再次获取到锁。 - 局限性: - 不够灵活,无法设置锁的获取和释放的条件。 - 性能方面在一些高并发场景下可能不如ReentrantLock。 - ReentrantLock锁 - 是Java中的一种显式锁,它需要通过lock()方法获取锁,通过unlock()方法释放锁。它具有以下特点: - 灵活性:可以设置公平锁和非公平锁。公平锁是指按照线程请求锁的先后顺序来获取锁,非公平锁则不保证线程获取锁的顺序。 - 可重入性:同样具有可重入性,一个线程可以多次获取同一个ReentrantLock锁。 - 性能优势:在一些高并发场景下,通过合理设置锁的参数和使用方式,可以获得更好的性能。 - 缺点: - 需要显式地获取和释放锁,如果忘记释放锁会导致死锁。 8. threadlocal实现原理 - ThreadLocal是Java中的一个类,它用于在每个线程中提供一个独立的变量副本。其实现原理如下: - 内部结构 - ThreadLocal内部维护了一个静态的内部类ThreadLocalMap,它类似于一个哈希表,用于存储每个线程的变量副本。 - 存储过程 - 当一个线程第一次访问一个ThreadLocal变量时,会在ThreadLocalMap中创建一个新的键值对,键为当前线程对象,值为该ThreadLocal变量的初始值(如果有指定)。此后,该线程每次访问这个ThreadLocal变量时,都会从ThreadLocalMap中获取对应的键值对,从而保证每个线程都能获取到自己独立的变量副本。 - 内存管理 - ThreadLocalMap中的键值对是通过弱引用(WeakReference)来维护的。这意味着当一个线程结束或者不再需要某个ThreadLocal变量时,垃圾回收器可以更方便地回收这些键值对所占用的内存,避免内存泄漏。 9. mybatis实现原理 - MyBatis是一个支持普通SQL查询、存储过程和高级映射的持久层框架。它的实现原理如下: - 配置文件和映射文件 - MyBatis通过配置文件和映射文件来管理数据库连接、SQL语句和对象映射关系。配置文件中包含了数据库连接信息、全局配置参数等,映射文件则针对每个实体类和数据库表,定义了SQL语句和对象映射的细节。 - 动态代理 - MyBatis使用动态代理技术来生成针对接口的代理对象。当调用接口中的方法时,代理对象会根据方法名和参数等信息,在映射文件中查找对应的SQL语句,并执行SQL查询或更新操作,然后将结果映射回实体类对象。 - 结果映射 - 在执行SQL操作后,MyBatis会根据映射文件中的结果映射规则,将查询结果中的数据转换为实体类对象。这可能涉及到字段名和属性名的匹配、数据类型的转换等操作。 10. spring实现原理 - 核心概念 - Spring的核心是依赖注入(DI)和面向切面编程(AOP)。 - 依赖注入原理 - Spring通过配置文件或注解的方式来管理对象之间的依赖关系。在运行时,Spring会根据配置信息,将依赖的对象注入到需要的对象中。例如,如果一个Service类依赖于一个Dao类,Spring会在创建Service类对象时,将Dao类对象注入到Service类中。 - 面向切面编程原理 - AOP是一种编程范式,它通过分离横切关注点(如日志记录、事务管理等)来提高代码的可维护性和可扩展性。Spring通过动态代理或字节码增强等技术来实现AOP。例如,在一个业务方法执行前后,通过AOP可以自动插入日志记录或事务管理的代码,而不需要在每个业务方法中都手动添加这些代码。 - bean初始化 - Spring中的bean初始化过程包括以下几个主要步骤: - 创建对象:根据配置信息或注解,通过反射机制创建bean对象。 - 属性注入:将依赖的对象注入到bean对象中,如前面提到的依赖注入原理。 - 调用初始化方法:如果bean对象定义了初始化方法,Spring会在对象创建和属性注入完成后,调用这个初始化方法。 - 注解有哪些 - Spring中有很多注解,常见的包括: - @Component:用于标识一个普通的组件类,可以被Spring容器扫描并管理。 - @Service:用于标识一个服务类,通常是业务逻辑层的类。 - @Repository:用于标识一个数据访问层的类,通常用于与数据库交互。 - @Controller:用于标识一个控制器类,通常用于处理Web请求。 - @Autowired:用于自动注入依赖对象。 - @Qualifier:用于指定注入对象的具体名称或类型,与@Autowired配合使用。 - @Value:用于注入配置文件中的值。 11. springboot注解 - Spring Boot是在Spring基础上发展起来的,它简化了Spring应用的开发和部署。Spring Boot中有很多注解,常见的包括: - @SpringBootApplication:这是一个组合注解,它包含了@Configuration、@EnableAutoConfiguration和@SpringBootWebApplicationContext等注解的功能。它用于标记一个Spring Boot应用的主类,启动Spring Boot应用时,会从这个主类开始扫描和加载相关的组件。 - @Configuration:用于标识一个配置类,在这个类中可以定义各种配置方法,如定义Bean对象、配置数据源等。 - @EnableAutoConfiguration:它会根据类路径上的现有资源和配置信息,自动配置Spring Boot应用所需的各种组件,如数据库连接、Web服务器等。 - @RestController:这是一个组合注解,它包含了@Controller和@RestService的功能。用于标识一个控制器类,并且这个类中的方法返回值会直接作为JSON格式的数据发送出去,适合用于构建RESTful API。 - @RequestMapping:用于定义一个请求路径,当客户端发出的请求路径与这个定义的路径匹配时,会执行相应的方法。 - 与spring区别 - 配置方式:Spring Boot简化了Spring的配置方式。Spring通常需要大量的配置文件和注解来管理对象之间的依赖关系和各种应用组件,而Spring Boot通过自动配置和约定大于配置的原则,大大减少了配置的工作量。 - 启动方式:Spring Boot有自己独特的启动方式,通过@SpringBootApplication注解标记的主类,使用main方法即可启动应用。而Spring需要更多的手动配置和启动步骤。 - 应用场景:Spring Boot更适合快速开发和部署小型到中型的应用,它提供了一站式的解决方案,包括内置的服务器、自动配置等。Spring则更适合用于大型企业级应用的开发,它提供了更强大的功能和更灵活的配置方式,需要开发者有更高的技能水平和更多的时间来进行配置和维护。
查看23道真题和解析
点赞 评论 收藏
分享
2024-08-14 09:24
上海交通大学 C++
面经深度解析:小红书Java后台
什么情况下加什么行锁:这里考察的是对数据库加锁的理解。当多个事务尝试同时修改同一行数据时,可能会导致数据不一致,为了保证数据的一致性和事务的隔离性,数据库系统会在事务试图修改数据时对相关行加锁,直到事务提交或回滚。因此我们从可能导致修改同一行数据的场景出发,来进行回答。乐观锁的使用场景:乐观锁是一种并发控制策略,主要用于在多用户共享资源的场景下,尤其是在分布式系统和高并发环境下,用来减少锁的竞争和提高系统的整体吞吐量。乐观锁假设大多数情况下不会发生冲突,因此在读取数据时不立即加锁,而是在更新数据时才检查数据是否已被其他事务修改过。回答该问题,我们可以思考哪些场景不会发生冲突,也就是哪些场景是读取数据大于写入数据。三种限流算法的使用场景和实现:限流算法的主要目的是控制在一定时间内请求的数量,防止系统资源被耗尽。不同的算法有不同的特点和适用场景,选择合适的算法需要考虑到系统的实时性、准确性和灵活性需求。常见的限流算法包括固定窗口算法、滑动窗口算法和漏桶算法。redis持久化:Redis的持久化机制确保了数据的持久性和可靠性,即使在服务器重启或故障后,也能恢复数据。RDB和AOF是两种主要的持久化方式,它们在数据恢复速度、数据完整性和资源占用等方面有所不同,因此适用于不同的场景和需求。因此我们可以从两种方式的使用场景、实现方式进行解答。讲讲jdk1.8的垃圾回收jdk1.8的垃圾回收机制中,垃圾回收器的设计目标是在不同场景下提供最优的性能。这包括最小化应用程序暂停时间、最大化吞吐量、以及在大型堆上保持良好性能。不同的垃圾回收器通过采用不同的策略和算法来达到这些目标,从而适应不同的应用程序需求。我们可以从各个回收机制的实现、优劣势、使用场景进行回答。发生频繁的fullgc可能由什么原因导致Full GC涉及整个堆的垃圾回收,包括年轻代和老年代,因此它通常比仅针对年轻代的垃圾回收更加耗时,对系统性能的影响也更大。频繁的Full GC不仅会增加系统的暂停时间,还可能消耗大量的CPU资源,导致应用程序响应变慢甚至停止响应。Spring源码用到的设计模式这里主要考察面试者对于设计模式和Spring框架的综合理解,每种设计模式在Spring中的应用都有其特定的目的和场景,理解这些模式有助于深入掌握框架的内部机制。SpringBoot和Spring主要考察面试者对常用的两个开发框架的认知。Spring 是一个全面的框架,提供了企业级应用开发的各种功能,包括依赖注入、面向切面编程、事务管理、数据访问、MVC框架等。而Spring Boot是在Spring基础上发展起来的一个子项目,旨在简化Spring应用的初始搭建以及开发过程,强调约定优于配置的原则。我们可以从两个框架的联系与区别进行回答。    需要完整面经解析文档的,欢迎评论:面经解析👥面试题目          
点赞 评论 收藏
分享
玩命加载中
牛客网
牛客企业服务