上海 Java开发工程师 14-20K
人力外包至甲方公司:栈略数据
一、岗位职责
1、负责保司对接需求的分析、梳理和开发;
2、负责TPA各个保司对接项目的维护,能够快速响应业务、运营和保司人员反馈的问题;
3、负责对线上问题进行排错并能快速落地可行的解决方案;
4、负责联调对接工作,处理保司对接联调过程中的沟通、问题跟进和问题处理;
5、负责代码的单元测试、定期的code review,保证代码的持续优化,保证代码的可维护性和健壮性;
二、任职要求
- 计算机相关专业,统招全日制本科以上学历,5年工作经验左右;
- 熟练掌握Java,SpringBoot,Spring Cloud,Hibernate/Mybatis, Maven, GIT等;
- 熟练掌握Restful Service的开发,熟悉SOA,熟悉Micro-Service;
- 有扎实的SQL功底,熟悉MySQL数据库;
- 具有良好的计算机基础,了解数据结构、算法、操作系统、设计模式等;
- 对业界相关技术的形态、发展有自己的理解,对当前流行的开源产品和技术保持开放和探索精神;
- 良好的编程习惯和团队协作精神,注重质量,工作效率高;思维敏捷,虚心好学,领悟能力强,抗压能力强;
- 有复杂业务项目对接经验优先
现场面试
大部分不记得了,挑重点记几个
笔试手写代码
笔试题一 有序数组找出两个数等于给定数字,要求时间复杂度o(n)、空间复杂度o(1)
public int[] twoSum(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while (left < right) {
int currentSum = nums[left] + nums[right];
if (currentSum == target) {
return new int[] {nums[left], nums[right]};
} else if (currentSum < target) {
left++;
} else {
right--;
}
}
return new int[0]; // 没有找到符合条件的两个数
}
// 示例输入
int[] nums = {2, 7, 11, 15, 18, 20};
int target = 26;
int[] result = twoSum(nums, target);
if (result.length == 2) {
System.out.println("找到两个数为: " + result[0] + " 和 " + result[1]);
} else {
System.out.println("未找到符合条件的两个数");
}
笔试题二 递归和迭代 f(0)=0 f(1)=1 f(n)=f(n-1)+f(n-2) 求f(n)
public class Fibonacci {
public static int fibonacciRecursive(int n) {
if (n <= 1) {
return n;
} else {
return fibonacciRecursive(n - 1) + fibonacciRecursive(n - 2);
}
}
public static void main(String[] args) {
int n = 10;
int result = fibonacciRecursive(n);
System.out.println("f(" + n + ") = " + result);
}
}
public class Fibonacci {
public static int fibonacciIterative(int n) {
if (n <= 1) {
return n;
}
int a = 0;
int b = 1;
int sum = 0;
for (int i = 2; i <= n; i++) {
sum = a + b;
a = b;
b = sum;
}
return sum;
}
public static void main(String[] args) {
int n = 10;
int result = fibonacciIterative(n);
System.out.println("f(" + n + ") = " + result);
}
}
- http https底层
HTTP 和 HTTPS 在底层的主要区别在于数据传输的安全性和加密方式:
HTTP(Hypertext Transfer Protocol) :
- HTTP 是基于 TCP 协议的应用层协议,用于在客户端和服务器之间传输超文本数据。
- HTTP 在传输过程中是明文传输的,数据不经过加密处理,因此容易被窃听和拦截。这种情况下,传输的数据可能会被黑客获取并篡改,存在安全风险。
HTTPS(Hypertext Transfer Protocol Secure) :
- HTTPS 实际上是在 HTTP 的基础上加入了 SSL/TLS 协议的加密传输协议。
- HTTPS 使用 SSL/TLS 加密机制对数据进行加密处理,确保在传输过程中数据的机密性和完整性。因此,即使数据被截获,黑客也无法轻易解密其内容。
- springMvc底层
Spring MVC 是 Spring Framework 中用于构建 Web 应用程序的一部分,它提供了一种基于 MVC(Model-View-Controller)模式的方式来构建 Web 应用程序。Spring MVC 的底层包括以下几个主要组件:
- DispatcherServlet(派发Servlet) :DispatcherServlet 是 Spring MVC 的核心组件,它充当前端控制器(Front Controller)的角色,负责接收所有的 HTTP 请求并将其分发给适当的处理程序。DispatcherServlet 还协调各个处理器(Handler)、解析视图(View)以及执行相关的拦截器(Interceptor)。
- HandlerMapping(处理器映射) :HandlerMapping 用于将请求映射到具体的处理器(Handler)。Spring MVC 提供了多种 HandlerMapping 实现,包括基于 URL 映射、注解映射等。
- Controller(控制器) :Controller 负责处理用户请求并生成响应。在 Spring MVC 中,可以使用注解或配置文件定义控制器,并且控制器通常返回一个 ModelAndView 对象或其他类型的响应数据。
- HandlerAdapter(处理器适配器) :HandlerAdapter 将具体的处理器(Handler)包装成一个可执行的对象,使得 DispatcherServlet 能够通过统一的接口调用不同类型的处理器。
- ViewResolver(视图解析器) :ViewResolver 用于将逻辑视图名称解析为实际的视图对象。Spring MVC 支持多种类型的视图解析器,包括 JSP、Thymeleaf、Velocity 等。
- View(视图) :View 负责向客户端呈现数据,通常是将模型数据渲染为 HTML、JSON 或其他格式的响应。视图可以是 JSP、FreeMarker、PDF 等。
- Interceptor(拦截器) :Interceptor 允许开发者在请求处理的不同阶段插入自定义的逻辑,例如日志记录、权限检查等。
- spring bean 分区了解过么
在 Spring Framework 中,Bean 的作用域定义了 Bean 对象的生命周期和可见范围,决定了在应用程序中如何共享和管理 Bean 实例。Spring Framework 提供了以下五种主要的 Bean 作用域:
- Singleton(单例) :在整个应用程序中只存在一个 Bean 实例。Spring 容器在首次请求时创建该 Bean 实例,并在后续的请求中返回同一个实例。Singleton 是 Spring 默认的作用域。
- Prototype(原型) :每次请求时都会创建一个新的 Bean 实例。每次通过 Spring 容器获取该 Bean 时,容器都会返回一个新的实例。
- Request(请求) :在一次 HTTP 请求过程中创建一个 Bean 实例,该 Bean 仅在当前 HTTP 请求内有效。适用于 Web 应用程序中的每个 HTTP 请求。
- Session(会话) :在一个 HTTP Session 中创建一个 Bean 实例,该 Bean 仅在当前 HTTP Session 内有效。适用于 Web 应用程序中需要跟踪用户会话状态的场景。
- GlobalSession(全局会话) :在一个全局的 HTTP Session 中创建一个 Bean 实例,该 Bean 仅在集群环境下使用。通常用于 Portlet 应用中,一个全局 Session 有多个 Portlet 共享。
- shardingjdbc业务使用情况以及怎么用的
分库分表
- lambda表达式::含义
在 Java 中,
User::getName是方法引用(Method Reference)的一种形式,它表示引用了 User 类中的 getName 方法。这种形式通常与 Lambda 表达式一起使用,用于简化代码并提高可读性。具体来说,
User::getName可以理解为对 User 类中的 getName 方法的引用,而不是调用该方法。这种形式通常用于函数式接口(Functional Interface)中,用于传递方法的引用作为参数,而不是直接编写 Lambda 表达式。
- 了解过bitmap么
位图
- 数据库隔离级别
数据库隔离级别是指在数据库系统中,多个并发事务之间的隔离程度,主要涉及到事务对数据的读取、写入和锁定行为。常见的数据库隔离级别包括:
读未提交(Read Uncommitted) :最低的隔离级别,允许一个事务在另一个事务未提交的数据修改结果之前读取该数据。这可能导致脏读(Dirty Read)问题。
读已提交(Read Committed) :保证一个事务只能读取到另一个已经提交的事务所做的修改,避免了脏读问题。但是由于事务可以在查询过程中多次读取某一行数据,因此可能会出现不可重复读(Non-repeatable Read)问题。
可重复读(Repeatable Read) :保证事务在执行过程中多次读取同一数据集时,返回的数据是一致的。可以避免不可重复读问题,但仍然可能出现幻读(Phantom Read)问题,即一个事务在读取某个范围的数据时,另一个事务插入了新的数据,导致第一个事务看到了新增的数据。
串行化(Serializable) :最高的隔离级别,通过强制事务串行执行来避免任何并发问题,确保事务之间不会相互影响。可以避免脏读、不可重复读和幻读问题,但性能开销较大,一般情况下很少使用。
-
项目遇到的困难
-
幻读是什么
事务A刚开始查询结果是空 事务B插入并提交1 事务A再次查询的时候发现出现一条数据1
- 单独创建线程和用线程池区别
- 单独创建线程:
- 当需要执行一个任务时,可以直接通过创建一个新的线程来处理。这样可以简单快速地实现多线程处理。
- 每次创建新线程都会带来一定的开销,包括线程对象的创建、上下文切换等,因此频繁地创建和销毁线程可能会影响性能。
- 线程的生命周期由程序员手动管理,包括启动、暂停、终止等,需要考虑线程安全性和资源管理。
- 使用线程池:
- 线程池是一组预先创建好的线程集合,可以重复使用这些线程来执行多个任务,避免频繁创建和销毁线程的开销。
- 通过线程池可以控制并发线程的数量,避免无限制地创建线程导致资源耗尽或系统负载过高。
- 线程池提供了各种配置选项,如线程数量、线程存活时间、任务队列等,可以根据实际需求灵活调整线程池参数。
- 线程池还提供了异常处理、任务拒绝策略等功能,能够更好地管理和监控多线程任务执行。
- 组合索引(a,b,c) select * from user where b='张三' 会用到索引么
用不到,因为最左前缀匹配原则
- 最左前缀匹配原则
最左前缀匹配原则是指,在使用组合索引时,索引的最左边列开始的连续子集必须被查询条件使用