麻了,石化盈科一面面经
Java面向对象的三大特性,分别介绍一下
-
封装(Encapsulation):
- 封装是面向对象编程的基本原则之一。它将类的实现细节隐藏起来,只向外部暴露必要的接口和数据。通过封装,对象内部的实现细节对外部是不可见的,这提高了代码的安全性和可维护性。封装可以通过访问修饰符(如private、protected、public)来实现,同时提供公共的方法来访问或修改私有属性。
-
继承(Inheritance):
- 继承是一种通过重用现有类的属性和方法来创建新类的机制。子类继承父类的特性,可以使用父类中的方法和属性,同时可以在子类中扩展或修改这些方法和属性。继承实现了代码的重用,提高了代码的可维护性。Java中通过关键字
extends
来实现继承关系。
- 继承是一种通过重用现有类的属性和方法来创建新类的机制。子类继承父类的特性,可以使用父类中的方法和属性,同时可以在子类中扩展或修改这些方法和属性。继承实现了代码的重用,提高了代码的可维护性。Java中通过关键字
-
多态(Polymorphism):
- 多态是指同一个操作作用于不同的对象可以有不同的行为。多态提高了代码的灵活性和可扩展性。Java中有两种类型的多态:编译时多态(静态多态)和运行时多态(动态多态)。运行时多态是通过方法的重写(Override)和接口来实现的。编译时多态是通过方法的重载(Overload)来实现的。多态是面向对象编程中一个非常重要的概念,它使得程序更容易扩展和维护。
List如何去重复
在Java中,可以使用以下几种方式对List进行去重:
-
使用Set: 利用Set的元素不可重复性,将List转换为Set,然后再转回List。这会自动去除重复元素。
List<String> list = new ArrayList<>(); // 添加元素到list Set<String> set = new LinkedHashSet<>(list); // 使用LinkedHashSet保持顺序 list.clear(); list.addAll(set);
-
Java 8 Stream API: 使用Java 8引入的Stream API,通过流的distinct()方法去重。
List<String> list = new ArrayList<>(); // 添加元素到list list = list.stream().distinct().collect(Collectors.toList());
-
Apache Commons Collections: 使用Apache Commons Collections库中的ListUtils类。
List<String> list = new ArrayList<>(); // 添加元素到list list = ListUtils.distinct(list);
-
使用Java 8 Lambda 表达式和Collectors.toSet():
List<String> list = new ArrayList<>(); // 添加元素到list list = list.stream().collect(Collectors.toSet()).stream().collect(Collectors.toList());
说一下冒泡排序的思想
冒泡排序是一种简单的排序算法,它的基本思想是通过多次遍历待排序的元素,比较相邻两个元素的大小,并根据需要交换它们的位置。在一次遍历中,将最大(或最小)的元素移动到最右边(或最左边),然后缩小待排序元素的范围,重复进行比较和交换直至完成排序。
具体的冒泡排序过程如下:
- 从第一个元素开始,依次比较相邻的两个元素。
- 如果前一个元素大于后一个元素,则交换它们的位置。
- 继续向后比较和交换,直到最后一个元素,此时最大的元素已经被移到了最右边。
- 缩小待排序的范围,重复上述步骤,直到所有元素都有序。
冒泡排序的特点是每一轮遍历都会确定一个最大(或最小)值的最终位置,因此总共需要进行 n-1 轮遍历,其中 n 是待排序元素的个数。
冒泡排序的时间复杂度为 O(n^2),其中 n 是待排序元素的个数。尽管它在效率上不如快速排序等高级算法,但由于其简单易懂的原理,通常在教学和理解排序算法的过程中被介绍和使用。
创建线程有哪几种方式?线程池有哪几个
在Java中,创建线程有两种主要的方式:继承Thread类和实现Runnable接口。线程池则是通过java.util.concurrent
包中的Executor
框架来创建和管理线程。
创建线程的方式:
-
继承Thread类:
- 创建一个类继承自Thread类,并重写run方法,然后创建该类的实例并调用start方法启动线程。
class MyThread extends Thread { public void run() { // 线程执行的代码 } } MyThread myThread = new MyThread(); myThread.start();
-
实现Runnable接口:
- 创建一个类实现Runnable接口,实现run方法,然后创建Thread类的实例,将实现了Runnable接口的对象作为参数传递给Thread的构造方法,并调用start方法启动线程。
class MyRunnable implements Runnable { public void run() { // 线程执行的代码 } } Thread thread = new Thread(new MyRunnable()); thread.start();
线程池的方式:
Java中的线程池是通过java.util.concurrent
包提供的Executor框架实现的。常用的线程池有以下几种:
newCachedThreadPool
:
-
创建一个可缓存的线程池,线程池的大小可根据需要进行自动扩展,但在某些情况下可能会回收线程。
ExecutorService executor = Executors.newCachedThreadPool();
2. **`newFixedThreadPool`:**
- 创建一个固定大小的线程池,线程数始终保持不变。
```java
ExecutorService executor = Executors.newFixedThreadPool(10); // 10为线程池的大小
-
newSingleThreadExecutor
:- 创建一个单线程的线程池,保证所有任务按照指定顺序(FIFO,LIFO,优先级)执行。
ExecutorService executor = Executors.newSingleThreadExecutor();
-
newScheduledThreadPool
:- 创建一个定时执行任务的线程池。
ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);
这些线程池的创建方式都是通过Executors
工厂类提供的方法来实现的。选择不同的线程池取决于具体的业务需求和性能要求。
SpringBoot有哪些优点
Spring Boot 是一个基于 Spring 框架的快速开发脚手架,它简化了 Spring 应用的初始搭建和开发过程。以下是 Spring Boot 的一些优点:
-
简化配置: Spring Boot 通过约定大于配置的原则,采用默认配置,减少了开发人员的配置工作。同时提供了丰富的可配置项,使得配置变得更加灵活。
-
内嵌容器: Spring Boot 内置了常用的Servlet容器(如Tomcat、Jetty),使得应用程序可以以独立的方式运行,无需外部Web服务器的支持。这降低了部署和运维的难度。
-
自动化配置: Spring Boot 根据项目的依赖,自动进行应用程序上下文的配置。这意味着无需手动配置大量的Bean,开发者可以更专注于业务逻辑的实现。
-
快速开发: Spring Boot 提供了大量的开箱即用的功能,如自动配置、热部署、可执行的 JAR 文件等,使得开发者可以更快地构建原型和开发功能。
-
集成测试支持: Spring Boot 提供了方便的测试支持,可以轻松编写集成测试和单元测试。测试的便捷性有助于确保应用程序的稳定性和可靠性。
-
微服务支持: Spring Boot 很好地支持微服务架构,可以通过 Spring Cloud 进行更进一步的微服务治理,提供服务注册、发现、负载均衡等功能。
-
丰富的扩展生态系统: Spring Boot 集成了众多 Spring 生态项目,如Spring Data、Spring Security等,可以方便地使用这些功能进行开发。
-
大量的社区支持: Spring Boot 有着庞大的社区,社区提供了大量的文档、教程和解决方案,开发者可以方便地获取帮助和分享经验。
-
监控和管理: Spring Boot 提供了许多用于监控和管理应用程序的工具,如Spring Boot Actuator,可以方便地查看应用程序的运行状态、性能指标等。
-
生态系统: Spring Boot 借助于Spring生态系统,提供了丰富的功能和解决方案,使得开发者能够更轻松地构建各类应用程序,包括企业级应用和微服务。
SpringBoot常用的注解
Spring Boot 提供了许多注解,用于简化应用程序的配置和开发。以下是一些常用的 Spring Boot 注解:
-
@SpringBootApplication
:- 该注解用于标识一个主程序类,通常位于项目的入口处。它包含了
@Configuration
、@EnableAutoConfiguration
、@ComponentScan
三个注解,用于启用自动配置和组件扫描。
- 该注解用于标识一个主程序类,通常位于项目的入口处。它包含了
-
@RestController
:- 用于标识一个类是 RESTful 风格的控制器,它的方法返回的数据直接作为响应体,不会被视图解析器解析。
-
@RequestMapping
:- 用于映射 HTTP 请求的路径和方法,可以用在类和方法上,定义了请求的路径和处理方法。
-
@Autowired
:- 用于进行依赖注入,可以标注在构造方法、Setter 方法、字段、方法上。
-
@Service
、@Repository
、@Component
:- 分别用于标识一个类是业务服务层、数据访问层、通用组件,让 Spring 进行组件扫描并纳入 IoC 容器管理。
-
@Configuration
:- 用于定义配置类,类似于 XML 配置文件。标注在类上,表示该类是一个配置类。
-
@Value
:- 用于将属性值注入到 Bean 中,可以注入简单类型、字符串、表达式等。
-
@PathVariable
:- 用于将 URL 模板中的变量绑定到方法参数中。
-
@RequestParam
:- 用于将请求参数绑定到方法参数中,可以指定参数名、是否必须等。
-
@ResponseBody
:- 用于标识一个方法返回的结果直接作为响应体,不进行视图解析。
-
@GetMapping
、@PostMapping
、@PutMapping
、@DeleteMapping
:- 这些注解用于简化常见 HTTP 方法的映射,分别对应于 GET、POST、PUT、DELETE。
-
@ConfigurationProperties
:- 用于将配置文件中的属性值绑定到一个 JavaBean 中,方便统一管理配置。
-
@EnableAutoConfiguration
:- 用于开启 Spring Boot 的自动配置功能,通常不需要手动添加,
@SpringBootApplication
已经包含了该注解。
- 用于开启 Spring Boot 的自动配置功能,通常不需要手动添加,
-
@Async
:- 用于标识一个方法是异步的,可以在方法上使用,也可以在类上使用。
-
@EnableScheduling
:- 用于开启 Spring 的定时任务功能,标注在配置类上。
数据库事务了解吗
事务是一组被视为单个逻辑工作单元的数据库操作,要么全部执行成功,要么全部失败回滚,以确保数据库的一致性和可靠性。事务具有四个基本特性,通常称为 ACID 特性:
-
原子性(Atomicity):
- 事务是原子的,要么全部执行成功,要么全部失败回滚。如果事务在执行过程中发生错误,所有的修改将被撤销,数据库将会回滚到事务开始前的状态。
-
一致性(Consistency):
- 事务使数据库从一个一致的状态转变到另一个一致的状态。在事务执行过程中,数据库约束一直保持有效,不会因为事务的执行而被破坏。
-
隔离性(Isolation):
- 多个事务可以并发执行,但每个事务的操作应该与其他事务隔离。隔离性能防止多个事务之间相互影响,保证每个事务都感觉不到其他事务的存在。
-
持久性(Durability):
- 一旦事务提交,它对数据库的修改将是永久性的,即使系统发生故障。数据库系统通过将事务的修改记录到物理存储中来实现持久性。
在关系型数据库中,通常使用以下方式来管理事务:
-
显式事务管理:
- 开发者通过编程方式开始、提交或回滚事务。通常使用数据库连接对象的
beginTransaction()
、commit()
和rollback()
等方法。
- 开发者通过编程方式开始、提交或回滚事务。通常使用数据库连接对象的
-
声明式事务管理:
- 基于注解或配置的方式声明事务的边界。在 Spring 框架中,可以使用
@Transactional
注解来声明事务。这样的声明式事务管理更加方便,开发者无需显式编写事务管理的代码。
- 基于注解或配置的方式声明事务的边界。在 Spring 框架中,可以使用
事务的使用场景包括需要一致性和可靠性的数据库操作,例如在银行应用中的转账操作、在线购物中的支付过程等。通过使用事务,可以确保这些操作不会在执行过程中发生错误或中断而导致数据不一致。
小程序向后端发起请求经过了哪些网络节点
当小程序向后端发起请求时,经过了一系列网络节点。以下是一般情况下的主要网络节点:
-
小程序端:
- 请求发起的地方,可以是用户的手机或其他设备上运行的小程序。
-
小程序服务器:
- 小程序端发送请求到小程序服务器,这是请求的第一个目标。小程序服务器负责接收请求、处理业务逻辑,然后向后端服务器发送请求。
-
反向代理服务器(可选):
- 在一些部署架构中,可能会存在反向代理服务器,用于负载均衡、安全过滤等。这个节点并不是必需的,具体是否存在取决于后端服务的架构。
-
应用服务器:
- 后端应用服务器,接收小程序服务器的请求,处理业务逻辑,访问数据库等。这可能是一个单独的服务器或者一个集群。
-
数据库服务器:
- 如果请求涉及到数据库操作,后端应用服务器会向数据库服务器发送请求,执行相应的数据库操作。
-
其他第三方服务(可选):
- 有时,后端服务可能还会涉及到与其他第三方服务进行交互,比如支付服务、消息推送服务等。
-
返回路径:
- 从数据库或其他第三方服务获取到数据后,数据经过相同的路径返回,依次经过应用服务器、反向代理服务器(可选)、小程序服务器,最终到达小程序端。
在整个过程中,数据通过网络传输,每个网络节点都可能引入延迟,因此优化网络请求的性能是开发中需要考虑的一个重要方面。安全性也是关键问题,确保数据在传输过程中是加密的,并且服务端对请求进行了合适的身份验证和授权。
小程序请求接口过程中网络安全是如何保证的
在小程序请求接口的过程中,网络安全是非常重要的,涉及到用户的隐私和数据的保护。以下是一些主要的措施,这些措施一般也适用于其他前端应用:
-
HTTPS加密:
- 小程序要求所有的网络请求必须使用HTTPS协议,确保数据在传输过程中是加密的。HTTPS通过SSL/TLS协议对通信内容进行加密,防止数据被中间人窃取或篡改。
-
数据签名与加密:
- 对于重要的请求,可以使用签名机制确保请求的完整性和真实性。通常使用类似于 HMAC(Hash-based Message Authentication Code)的算法,将请求参数和密钥进行签名,并将签名附加到请求中。服务端根据相同的密钥进行签名验证。
-
小程序登录态与用户鉴权:
- 小程序通过调用
wx.login
获取登录凭证,然后将凭证发送到后端服务器。后端服务器使用这个凭证调用微信服务端接口验证,并获取到用户的唯一标识,以此来识别用户。确保在接口调用中对用户进行鉴权,只允许合法的用户访问敏感接口。
- 小程序通过调用
-
接口访问限制:
- 限制用户的访问频率,通过防刷策略来避免恶意攻击和非法访问。这可以通过限制同一 IP 地址的访问频率或者使用令牌桶、漏桶等算法进行限流。
-
OAuth2.0认证:
- 对于需要用户授权的操作,可以使用 OAuth2.0 协议,通过微信提供的用户授权接口,获取用户的授权同意后的令牌(access token)来进行接口访问。
-
防止SQL注入和XSS攻击:
- 在处理用户输入时,对输入进行有效的过滤和转义,防止SQL注入和XSS攻击。不信任的输入数据应该被过滤或者进行合适的编码,确保它们不会被误认为是执行代码或者SQL语句。
-
敏感数据保护:
- 对于敏感数据的存储和传输,需要进行适当的加密处理,包括数据库中的密码、个人隐私信息等。同时,确保在传输中采用安全的协议,如HTTPS。
-
错误处理:
- 在接口中提供详细的错误信息是为了方便开发调试,但在生产环境中应该尽可能减少详细的错误信息的返回,以防泄漏敏感信息。
这些安全措施需要在前端小程序和后端服务器都进行合作实施,形成端到端的安全体系。前端应保护用户信息和凭证,后端则需要验证和授权请求,以确保系统的整体安全性。
linux相关的命令
以下是一些常用的Linux命令,用于在终端中执行各种任务:
-
ls
- 列出文件和目录:- 用于列出当前目录下的文件和子目录。
ls
-
cd
- 切换目录:- 用于更改当前工作目录。
cd directory_name
-
pwd
- 显示当前工作目录:- 用于显示当前工作目录的路径。
pwd
-
cp
- 复制文件或目录:- 用于复制文件或目录。
cp source destination
-
mv
- 移动/重命名文件或目录:- 用于移动文件或目录,也可用于重命名。
mv source destination
-
rm
- 删除文件或目录:- 用于删除文件或目录。
rm file_name
-
mkdir
- 创建目录:- 用于创建新目录。
mkdir directory_name
-
rmdir
- 删除空目录:- 用于删除空目录。
rmdir directory_name
-
cat
- 查看文件内容:- 用于查看文件的内容。
cat file_name
-
more
- 逐屏显示文件内容:- 用于逐屏显示文件的内容。
more file_name
-
less
- 逐屏显示文件内容,支持向前翻页:- 用于逐屏显示文件的内容,支持向前翻页。
less file_name
-
head
- 显示文件头部内容:- 用于显示文件的头部内容。
head file_name
-
tail
- 显示文件尾部内容:- 用于显示文件的尾部内容,常用于查看日志。
tail file_name
-
grep
- 在文件中查找匹配的文本:- 用于在文件中查找包含指定文本的行。
grep pattern file_name
-
find
- 在文件系统中查找文件:- 用于在文件系统中递归查找文件。
find directory -name file_name
-
chmod
- 修改文件权限:- 用于修改文件或目录的权限。
chmod permissions file_name
-
chown
- 修改文件所有者:- 用于修改文件或目录的所有者。
chown owner:group file_name
-
ps
- 显示当前运行的进程:- 用于显示当前正在运行的进程信息。
ps
-
kill
- 终止进程:- 用于终止指定的进程。
kill process_id
-
man
- 查看命令手册:- 用于查看Linux命令的手册页。
man command_name
#23届找工作求助阵地##24秋招求职节奏总结#kill和kill -9有哪些区别
收录各个网友分享的各个公司的面经,并给出答案。