互联网Java工程师面试题·Java 总结篇·第十弹

目录

82、JDBC 能否处理 Blob 和 Clob?

83、简述正则表达式及其用途。

84、Java 中是如何支持正则表达式操作的?

85、获得一个类的类对象有哪些方式?

86、如何通过反射创建对象?

87、如何通过反射获取和设置对象私有字段的值?

88、如何通过反射调用对象的方法?

89、简述一下面向对象的”六原则一法则”。


82、JDBC 能否处理 Blob 和 Clob?

        Blob 是指二进制大对象(Binary Large Object),而 Clob 是指大字符对象(Character Large Objec),因此其中 Blob 是为存储大的二进制数据而设计的,而 Clob 是为存储大的文本数据而设计的。JDBC 的 PreparedStatement 和ResultSet 都提供了相应的方法来支持 Blob 和 Clob 操作。下面的代码展示了如何使用 JDBC 操作 LOB:

        下面以 MySQL 数据库为例,创建一个张有三个字段的用户表,包括编号(id)、姓名(name)和照片(photo),建表语句如下:

create table tb_user
(
id int primary key auto_increment,
name varchar(20) unique not null,
photo longblob
);

下面的 Java 代码向数据库中插入一条记录:

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;class JdbcLobTest {public static void main(String[] args) {Connection con = null;try {// 1. 加载驱动(Java6 以上版本可以省略)Class.forName("com.mysql.jdbc.Driver");// 2. 建立连接con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "123456");// 3. 创建语句对象PreparedStatement ps = con.prepareStatement("insert into tb_user values (default, ?, ?)");ps.setString(1, "骆昊");// 将 SQL 语句中第一个占位符换成字符串try (InputStream in = new FileInputStream("test.jpg"))
{
// Java 7 的 TWR
ps.setBinaryStream(2, in);
// 将 SQL 语句中第二个占位符换成二进制流// 4. 发出 SQL 语句获得受影响行数System.out.println(ps.executeUpdate() == 1 ? "插入成功" : "插入失败");} catch(IOException e) {System.out.println("读取照片失败!");}} catch (ClassNotFoundException | SQLException e) { // Java7 的多异常捕获e.printStackTrace();} finally { // 释放外部资源的代码都应当放在 finally 中保证其能够得到执行try {if(con != null && !con.isClosed()) {con.close();// 5. 释放数据库连接con = null; // 指示垃圾回收器可以回收该对象}}catch (SQLException e) {e.printStackTrace();}}}
}

83、简述正则表达式及其用途。

        在编写处理字符串的程序时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。

说明:计算机诞生初期处理的信息几乎都是数值,但是时过境迁,今天我们使用计算机处理的信息更多的时候不是数值而是字符串,正则表达式就是在进行字符串匹配和处理的时候最为强大的工具,绝大多数语言都提供了对正则表达式的支持。


84、Java 中是如何支持正则表达式操作的?

Java 中的 String 类提供了支持正则表达式操作的方法,包括:matches()、replaceAll()、replaceFirst()、split()。此外,Java 中可以用 Pattern 类表示正则表达式对象,它提供了丰富的 API 进行各种正则表达式操作,请参考下面面试题的代码。

面试题: - 如果要从字符串中截取第一个英文左括号之前的字符串,例如:北京市(朝阳区)(西城区)(海淀区),截取结果为:北京市,那么正则表达式怎么写?

import java.util.regex.Matcher;
import java.util.regex.Pattern;class RegExpTest {public static void main(String[] args) {String str = "北京市(朝阳区)(西城区)(海淀区)";Pattern p = Pattern.compile(".*?(?=\\()");Matcher m = p.matcher(str);if(m.find()) {System.out.println(m.group());}}
}

说明:上面的正则表达式中使用了懒惰匹配和前瞻,如果不清楚这些内容,推荐读一下网上很有名的《正则表达式 30 分钟入门教程》。


85、获得一个类的类对象有哪些方式?

方法 1:类型.class,例如:String.class

方法 2:对象.getClass(),例如:”hello”.getClass()

方法 3:Class.forName(),例如:Class.forName(“java.lang.String”)


86、如何通过反射创建对象?

方法 1:通过类对象调用 newInstance()方法,例如:String.class.newInstance()

方法 2:通过类对象的 getConstructor()或 getDeclaredConstructor()方法获得构造器(Constructor)对象并调用其 newInstance()方法创建对象,

例如:String.class.getConstructor(String.class).newInstance(“Hello”);


87、如何通过反射获取和设置对象私有字段的值?

        可以通过类对象的 getDeclaredField()方法字段(Field)对象,然后再通过字段对象的 setAccessible(true)将其设置为可以访问,接下来就可以通过 get/set 方法来获取/设置字段的值了。下面的代码实现了一个反射的工具类,其中的两个静态方法分别用于获取和设置私有字段的值,字段可以是基本类型也可以是对象类型且支持多级对象操作,例如 ReflectionUtil.get(dog, “owner.car.engine.id”);可以获得 dog 对象的主人的汽车的引擎的 ID 号。

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;import java.util.List;public class ReflectionUtil {private ReflectionUtil() {throw new AssertionError();}
/**
* 通过反射取对象指定字段(属性)的值
* @param target 目标对象
* @param fieldName 字段的名字
* @throws 如果取不到对象指定字段的值则抛出异常
* @return 字段的值
*/
public static Object getValue(Object target, String fieldName) {Class<?> clazz = target.getClass();String[] fs = fieldName.split("\\.");try {for(int i = 0; i < fs.length - 1; i++) {Field f = clazz.getDeclaredField(fs[i]);f.setAccessible(true);target = f.get(target);clazz = target.getClass();}Field f = clazz.getDeclaredField(fs[fs.length - 1]);f.setAccessible(true);return f.get(target);}catch (Exception e) {throw new RuntimeException(e);}
}
/**
* 通过反射给对象的指定字段赋值
* @param target 目标对象
* @param fieldName 字段的名称
* @param value 值
*/
public static void setValue(Object target, String fieldName, Object value) {Class<?> clazz = target.getClass();String[] fs = fieldName.split("\\.");try {for(int i = 0; i < fs.length - 1; i++) {Field f = clazz.getDeclaredField(fs[i]);f.setAccessible(true);Object val = f.get(target);if(val == null) {Constructor<?> c =
f.getType().getDeclaredConstructor();c.setAccessible(true);val = c.newInstance();f.set(target, val);}target = val;clazz = target.getClass();}Field f = clazz.getDeclaredField(fs[fs.length - 1]);f.setAccessible(true);f.set(target, value);}catch (Exception e) {throw new RuntimeException(e);}}
}

88、如何通过反射调用对象的方法?

import java.lang.reflect.Method;class MethodInvokeTest {public static void main(String[] args) throws Exception {String str = "hello";Method m = str.getClass().getMethod("toUpperCase");System.out.println(m.invoke(str)); // HELLO}
}

89、简述一下面向对象的”六原则一法则”。

单一职责原则:一个类只做它该做的事情。(单一职责原则想表达的就是”高内聚”,写代码最终极的原则只有六个字”高内聚、低耦合”,就如同葵花宝典或辟邪剑谱的中心思想就八个字”欲练此功必先自宫”,所谓的高内聚就是一个代码模块只完成一项功能,在面向对象中,如果只让一个类完成它该做的事,而不涉及与它无关的领域就是践行了高内聚的原则,这个类就只有单一职责。我们都知道一句话叫”因为专注,所以专业”,一个对象如果承担太多的职责,那么注定它什么都做不好。这个世界上任何好的东西都有两个特征,一个是功能单一,好的相机绝对不是电视购物里面卖的那种一个机器有一百多种功能的,它基本上只能照相;另一个是模块化,好的自行车是组装车,从减震叉、刹车到变速器,所有的部件都是可以拆卸和重新组装的,好的乒乓球拍也不是成品拍,一定是底板和胶皮可以拆分和自行组装的,一个好的软件系统,它里面的每个功能模块也应该是可以轻易的拿到其他系统中使用的,这样才能实现软件复用的目标。)

开闭原则:软件实体应当对扩展开放,对修改关闭。(在理想的状态下,当我们需要为一个软件系统增加新功能时,只需要从原来的系统派生出一些新类就可以,不需要修改原来的任何一行代码。要做到开闭有两个要点:

①抽象是关键,一个系统中如果没有抽象类或接口系统就没有扩展点;

②封装可变性,将系统中的各种可变因素封装到一个继承结构中,如果多个可变因素混杂在一起,系统将变得复杂而换乱,如果不清楚如何封装可变性,可以参考《设计模式精解》一书中对桥梁模式的讲解的章节。)

依赖倒转原则:面向接口编程。(该原则说得直白和具体一些就是声明方法的参数类型、方法的返回类型、变量的引用类型时,尽可能使用抽象类型而不用具体类型,因为抽象类型可以被它的任何一个子类型所替代,请参考下面的里氏替换原则。)

里氏替换原则:任何时候都可以用子类型替换掉父类型。(关于里氏替换原则的描述,Barbara Liskov 女士的描述比这个要复杂得多,但简单的说就是能用父类型的地方就一定能使用子类型。里氏替换原则可以检查继承关系是否合理,如果一个继承关系违背了里氏替换原则,那么这个继承关系一定是错误的,需要对代码进行重构。例如让猫继承狗,或者狗继承猫,又或者让正方形继承长方形都是错误的继承关系,因为你很容易找到违反里氏替换原则的场景。需要注意的是:子类一定是增加父类的能力而不是减少父类的能力,因为子类比父类的能力更多,把能力多的对象当成能力少的对象来用当然没有任何问题。)

接口隔离原则:接口要小而专,绝不能大而全。(臃肿的接口是对接口的污染,既然接口表示能力,那么一个接口只应该描述一种能力,接口也应该是高度内聚的。例如,琴棋书画就应该分别设计为四个接口,而不应设计成一个接口中的四个方法,因为如果设计成一个接口中的四个方法,那么这个接口很难用,毕竟琴棋书画四样都精通的人还是少数,而如果设计成四个接口,会几项就实现几个接口,这样的话每个接口被复用的可能性是很高的。Java 中的接口代表能力、代表约定、代表角色,能否正确的使用接口一定是编程水平高低的重要标识。)

合成聚合复用原则:优先使用聚合或合成关系复用代码。(通过继承来复用代码是面向对象程序设计中被滥用得最多的东西,因为所有的教科书都无一例外的对继承进行了鼓吹从而误导了初学者,类与类之间简单的说有三种关系,Is-A 关系、Has-A 关系、Use-A 关系,分别代表继承、关联和依赖。其中,关联关系根据其关联的强度又可以进一步划分为关联、聚合和合成,但说白了都是Has-A 关系,合成聚合复用原则想表达的是优先考虑 Has-A 关系而不是 Is-A 关系复用代码,原因嘛可以自己从百度上找到一万个理由,需要说明的是,即使在Java 的 API 中也有不少滥用继承的例子,例如 Properties 类继承了 Hashtable类,Stack 类继承了 Vector 类,这些继承明显就是错误的,更好的做法是在Properties 类中放置一个 Hashtable 类型的成员并且将其键和值都设置为字符串来存储数据,而 Stack 类的设计也应该是在 Stack 类中放一个 Vector 对象来存储数据。记住:任何时候都不要继承工具类,工具是可以拥有并可以使用的,而不是拿来继承的。)

迪米特法则:迪米特法则又叫最少知识原则,一个对象应当对其他对象有尽可能少的了解。(迪米特法则简单的说就是如何做到”低耦合”,门面模式和调停者模式就是对迪米特法则的践行。对于门面模式可以举一个简单的例子,你去一家公司洽谈业务,你不需要了解这个公司内部是如何运作的,你甚至可以对这个公司一无所知,去的时候只需要找到公司入口处的前台美女,告诉她们你要做什么,她们会找到合适的人跟你接洽,前台的美女就是公司这个系统的门面。再复杂的系统都可以为用户提供一个简单的门面,Java Web 开发中作为前端控制器的 Servlet 或 Filter 不就是一个门面吗,浏览器对服务器的运作方式一无所知,但是通过前端控制器就能够根据你的请求得到相应的服务。调停者模式也可以举一个简单的例子来说明,例如一台计算机,CPU、内存、硬盘、显卡、声卡各种设备需要相互配合才能很好的工作,但是如果这些东西都直接连接到一起,计算机的布线将异常复杂,在这种情况下,主板作为一个调停者的身份出现,它将各个设备连接在一起而不需要每个设备之间直接交换数据,这样就减小了系统的耦合度和复杂度,如下图所示。迪米特法则用通俗的话来将就是不要和陌生人打交道,如果真的需要,找一个自己的朋友,让他替你和陌生人打交道。)


要想了解更多:

千题千解·Java面试宝典_时光の尘的博客-CSDN博客

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

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

相关文章

基于SSM+Vue的体育馆管理系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

紫光同创FPGA实现UDP协议栈网络视频传输,带录像和抓拍功能,基于YT8511和RTL8211,提供2套PDS工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐我这里已有的以太网方案紫光同创FPGA精简版UDP方案紫光同创FPGA带ping功能UDP方案紫光同创FPGA精简版UDP视频传输方案 3、设计思路框架OV5640摄像头配置及采集数据缓冲FIFOUDP协议栈详解MAC层发送MAC发送模式MAC层接收ARP发送ARP接收ARP缓…

【Linux】如何判断RS-232串口是否能正常使用

1.RS-232串口短接 使用RS-232协议的串口引脚一般如图下所示 为了让串口能够接收到自己发出的串口数据&#xff0c;需要将输出端和输入端&#xff08;RXD和TXD&#xff09;进行短接操作&#xff1a; 短接完成后&#xff0c;才能实现自发自收的功能&#xff08;走其他协议的串口清…

学信息系统项目管理师第4版系列32_信息技术发展

1. 大型信息系统 1.1. 大型信息系统是指以信息技术和通信技术为支撑&#xff0c;规模庞大&#xff0c;分布广阔&#xff0c;采用多级 网络结构&#xff0c;跨越多个安全域&#xff1b;处理海量的&#xff0c;复杂且形式多样的数据&#xff0c;提供多种类型应用 的大系统 1.1.…

【计算机网络笔记】OSI参考模型基本概念

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

LeetCode 799. 香槟塔【数组,模拟,简单线性DP】1855

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

日志回滚工作原理剖析及在文件系统的作用

日志回滚原理 当涉及到崩溃恢复和一致性保护时&#xff0c;日志回滚是一种常见的机制。它通过记录写入操作到一个事务日志中&#xff0c;而不是直接应用到文件系统&#xff0c;以保护文件系统的一致性。下面是日志回滚的一般工作原理&#xff1a; 日志记录&#xff1a;在进行写…

uni-app实现拍照功能

直接些这样的组件代码 <template><view><button click"takePhoto">拍照</button><image :src"photoUrl" v-if"photoUrl" mode"aspectFit"></image></view> </template><script&g…

阿里云服务器x86计算架构ECS规格大全

阿里云企业级服务器基于X86架构的实例规格&#xff0c;每一个vCPU都对应一个处理器核心的超线程&#xff0c;基于ARM架构的实例规格&#xff0c;每一个vCPU都对应一个处理器的物理核心&#xff0c;具有性能稳定且资源独享的特点。阿里云服务器网aliyunfuwuqi.com分享阿里云企业…

Mybatis对数据库进行增删查改以及单元测试

这篇写的草率了&#xff0c;是好几天前学到&#xff0c;以后用来自己复习 UserInfo import lombok.Data;Data public class UserInfo {private int id;private String name;private int age;private String email;//LocalDateTime可用于接收 时间}Mapper UserMapper pack…

【word技巧】word页眉,如何禁止他人修改?

我们设置了页眉内容之后&#xff0c;不想其他人修改自己的页眉内容&#xff0c;我们可以设置加密的&#xff0c;设置方法如下&#xff1a; 先将页眉设置好&#xff0c;退出页眉设置之后&#xff0c;我们选择布局功能&#xff0c;点击分隔符 – 连续 设置完之后页面分为上下两节…

sqoop 脚本密码管理

1&#xff1a;背景 生产上很多sqoop脚本的密码都是铭文&#xff0c;很不安全&#xff0c;找了一些帖子&#xff0c;自己尝试了下&#xff0c;记录下细节&#xff0c;使用的方式是将密码存在hdfs上然后在脚本里用别名来替代。 2&#xff1a;正文 第一步&#xff1a;创建密码对…

11. 机器学习 - 评价指标2

文章目录 混淆矩阵F-scoreAUC-ROC 更多内容&#xff1a; 茶桁的AI秘籍 Hi, 你好。我是茶桁。 上一节课&#xff0c;咱们讲到了评测指标&#xff0c;并且在文章的最后提到了一个矩阵&#xff0c;我们就从这里开始。 混淆矩阵 在我们实际的工作中&#xff0c;会有一个矩阵&am…

Cocos Creator3.8 项目实战(十)使用 protobuf详细教程

在 Cocos Creator 中使用 protobuf.js 库可以方便地进行协议的序列化和反序列化。 下面是使用 protobuf.js 的详细说明&#xff1a; 一、protobuf环境安装 1、安装 npm protobuf环境安装安装需要使用 npm 命令进行&#xff0c;因此首先需要安装 npm 。 如果你还没安装 npm …

mysql宋红康第一篇

mysql宋红康第一篇 索引的数据结构 为什么使用索引&#xff1f; 索引是存储引擎用于快速找到数据记录的一种数据结构&#xff0c;就好比一本教科书的目录部分&#xff0c;通过目录中找到对应文章的页码&#xff0c;便可快速定位到需要的文章。MySQL中也是一样的道理&#xf…

STM32内部flash闪存的总结

最近在做无人船和机巢远程在线升级的项目&#xff0c;牵扯到flash的操作&#xff0c;特此记录&#xff0c;便于以后查找。IMU也用到过&#xff0c;当时没记录 具体细节看 E:\Documets\AY\a-project\IMU\IMU16500\S0IMU v3.3 study\User\Driver\source eeprom.c E:\Documets\A…

SPSS|正负偏态的转换方法|限值1.96|反转后处理(对数法)|正态得分法|实战小练-SPSS学习(2)

目录 学习目的软件版本参考文档基础数据正负偏态的转换方法&#xff08;引自《小白爱上SPSS》&#xff09;正偏态数据转换方法负偏态数据转换 实战数据准备数据初探输出结果分析查看峰度、偏度查看峰度标准误差、偏度标准误差计算偏度系数和峰度系数Tips&#xff1a;为什么判断…

Vue3 + Nodejs 实战 ,文件上传项目--大文件分片上传+断点续传

目录 1.大文件上传的场景 2.前端实现 2.1 对文件进行分片 2.2 生成hash值&#xff08;唯一标识&#xff09; 2.3 发送上传文件请求 3.后端实现 3.1 接收分片数据临时存储 3.2 合并分片 4.完成段点续传 4.1修改后端 4.2 修改前端 5.测试 博客主页&#xff1a;専心_前端…

JS初步了解环境对象this

什么是环境对象&#xff1f; 环境对象&#xff1a;指的是函数内部特殊的变量this&#xff0c;它代表着当前函数运行时所处的环境 **作用&#xff1a;**弄清楚this的指向&#xff0c;可以让我们代码更简洁 在普通函数中&#xff1a; // 每个函数里面都有this 普通函数的this指向…

计网----数据包在传输中的变化过程,单播组播和广播,APR协议,APR代理,免费ARP,DNS协议,路由数据转发过程

计网----数据包在传输中的变化过程&#xff0c;单播组播和广播&#xff0c;ARP协议&#xff0c;ARP代理&#xff0c;免费ARP&#xff0c;DNS协议&#xff0c;路由数据转发过程 一.数据包在传输中的变化过程&#xff08;在同一个路由器下&#xff09; 1.传输数据时&#xff0c…