做ppt网站动态/商丘seo公司
基础篇
-
面向对象的特征
-
封装(Encapsulation): 封装是指将对象的数据(属性)和行为(方法)结合在一起,形成一个独立的实体。对象的数据被隐藏在内部,只能通过定义好的接口(方法)来访问。这样可以防止外界随意改变对象内部的状态,保证了数据的安全性和完整性。
-
继承(Inheritance): 继承允许新创建的类(子类或派生类)继承现有类(父类或基类)的属性和方法。子类可以重用父类的代码,可以扩展或定制父类的功能。继承提供了代码重用的能力,并且可以建立起类之间的层次关系。
-
多态(Polymorphism): 多态性意味着可以使用相同的接口调用不同的基于对象类型的方法。在编程中,多态通常体现为“一个接口,多个实现”,它允许将对象视为其自身的类型或其父类型的实例,并根据对象的实际类型来调用相应的方法。多态性增加了代码的灵活性和扩展性。
-
抽象(Abstraction): 抽象是将复杂的现实问题简化为模型的过程。在面向对象编程中,抽象意味着隐藏复杂的实现细节,只展示对象的关键特性。一个抽象类或接口可以定义方法和属性的“蓝图”,具体的实现则由子类负责。
-
2 在Java编程语言中,
final
、finally
和finalize
是三个有明显不同用途的概念。
-
final
:final
是一个访问修饰符。它可以修饰类、方法和变量。- 当
final
修饰一个类时,表明这个类不能被继承。 - 当
final
修饰一个方法时,表示这个方法不能被子类覆盖。 - 当
final
修饰一个变量(包括成员变量和局部变量)时,表示这个变量的值一旦被初始化之后就不能再被改变;对于引用类型,其引用不能再指向另一个对象,但对象的内部状态是可以改变的。
- 当
-
finally
:finally
是与try
和catch
语句一起使用的,在异常处理中起着重要的作用。无论是否抛出或捕获异常,finally
块中的代码都会被执行。因此,finally
通常用于进行清理工作,如关闭文件、释放资源等。1try { 2 // 可能会抛出异常的代码 3} catch (ExceptionType name) { 4 // 处理异常 5} finally { 6 // 清理代码,无论是否抛出异常都会执行 7}
-
finalize
:finalize
是一个方法,它定义在java.lang.Object类中。它在垃圾收集器确定不存在对该对象的更多引用时被垃圾收集器调用,用于执行对象销毁前的清理工作。finalize
方法可以被子类覆盖以实现特定的清理逻辑。1@Override 2protected void finalize() throws Throwable { 3 try { 4 // 清理资源,如释放网络连接或关闭文件 5 } finally { 6 super.finalize(); // 调用超类的finalize方法 7 } 8}
需要注意的是,finalize
方法并不推荐使用,因为它的执行时间是不确定的,且容易导致错误和性能问题。从Java 9开始,finalize
方法已经被声明为过时(deprecated),因此应该避免使用,并寻找其他资源管理的方式,比如使用try-with-resources
语句自动管理资源
3 int 和 Integer 有什么区别
int
和 Integer
在Java中是两种不同的类型,它们之间的主要区别在于int
是原始数据类型(primitive data type),而Integer
是包装类(wrapper class)。
以下是int
和Integer
之间的一些关键区别:
-
int
:int
是Java的一种原始数据类型,用于表示32位有符号的整数值。int
类型的变量直接存储数值本身,因此它的处理效率较高。- 作为原始类型,
int
变量不能调用方法,因为它不是对象。 - 默认值为0。
-
Integer
:Integer
是int
的包装类,属于Java的一部分基本类型的包装类,位于java.lang
包中。Integer
是一个类,因此Integer
的变量实际上是一个对象的引用,这个对象包含了一个int
类型的值。- 由于
Integer
是一个类,它可以有方法,例如可以调用.toString()
来将整数转换成字符串,或者调用.equals()
来比较两个Integer
对象的值。 Integer
对象可以为null
,表示它还没有指向任何实际的整数值,这是区分于int
的0值。Integer
类还提供了许多静态方法,例如用于解析字符串的.parseInt()
,或者用于比较两个整数的.compare()
。
从Java 5开始,引入了自动装箱(autoboxing)和自动拆箱(unboxing)特性:
-
自动装箱:当需要
Integer
对象时,原始int
类型的值会自动转换为Integer
对象。1int i = 10; 2Integer integer = i; // 自动装箱
-
自动拆箱:当需要原始
int
类型的值时,Integer
对象会自动转换为int
值。1Integer integer = new Integer(10); 2int i = integer; // 自动拆箱
由于自动装箱和拆箱的存在,int
和Integer
之间的转换在大多数情况下对开发人员是透明的,但是仍然需要注意空指针异常(NullPointerException
),因为Integer
对象可以为null
,而int
类型不能。
在实际编程过程中,选择int
还是Integer
取决于具体情况。如果要利用对象的特性或者需要使用集合类(如ArrayList
),则必须使用Integer
;但如果追求性能或者处理基本数值运算,通常会使用int
。
4.重载和重写的区别
重载(Overloading)和重写(Overriding)是面向对象编程中两种不同的概念,它们都允许程序员在一定程度上修改类的行为。但是,它们的用途和规则有所不同。
-
重载(Overloading):
- 概念:重载是指在同一个类中定义多个名称相同但参数列表不同的方法。方法的返回类型可以相同也可以不同,并且重载与方法的访问修饰符或抛出的异常也没有关系。
- 目的:重载使得程序员可以使用相同的方法名执行不同的功能,提高了方法的可用性。
- 规则:要实现重载,至少要改变方法的参数数量或参数类型。只改变返回类型不足以构成重载。
- 范围:只能在同一个类中进行。
1public class Example { 2 public void display(String s) { 3 // ... 4 } 5 public void display(int i) { // 重载方法 6 // ... 7 } 8}
-
重写(Overriding):
- 概念:重写是指子类重新定义父类中已有的方法。子类的方法必须与父类被重写的方法具有相同的方法名称、参数列表和返回类型。
- 目的:重写允许子类提供特定于自己的实现,这是实现多态性的基础。
- 规则:
- 方法名、参数列表必须完全相同。
- 返回类型必须相同或是协变返回类型(子类重写方法的返回类型可以是父类方法返回类型的子类型)。
- 访问修饰符可以保持相同或者更宽松,但不能更严格。
- 重写方法不能抛出新的检查异常或者比被重写方法更广泛的检查异常。
- 使用
@Override
注解可以明确指示一个方法是重写方法,有助于编译器检查和提高代码可读性。
1public class Base { 2 public void display() { 3 // ... 4 } 5} 6 7public class Derived extends Base { 8 @Override 9 public void display() { // 重写方法 10 // ... 11 } 12}
综上所述,方法的重载发生在同一个类中或者在子类中,它只关心方法签名(方法名和参数列表),而不考虑方法的返回类型;方法的重写专指子类覆盖父类的同一个方法,需要保证方法签名和返回类型与被重写的父类方法一致,是实现运行时多态的关键。
Java接口默认方法:
-
自Java 8起,接口支持定义默认方法。默认方法的定义格式为:`public default 返回值类型 方法名称(参数列表)`。这里的`public`可以略去不写,但`default`是必需的。默认方法可以在接口中定义,并且不需要实现类为其提供实现。这意味着,当一个新的接口特性被添加时,所有已存在的实现类都可以自动获得这个新的功能,而无需修改它们各自的实现代码。
-
默认方法的使用有两种情况:
- 可以直接在实现类中使用接口中的默认方法,就像使用普通接口方法一样。
- 同样地,实现类可以对接口中的默认方法进行覆盖重写,以根据自己的需求定制逻辑。
-
例如,以下是一个带有默认方法和实现类的简单接口示例:
```java
public interface MyInterface {
default void defaultMethod()
}
public class DefaultTest implements MyInterface {
@Override
public String getBrand() {
return "iPhone";
}
}
```
-
从Java 9开始,接口还可以定义静态方法和私有方法。静态方法不能通过接口实现类进行调用,而是需要通过接口名称直接调用。私有方法则是为了在不暴露具体实现细节的情况下,提供一个共用的逻辑块。
-
接口中的常量可以被定义为`public static final`,这样的成员变量将被认为是不可变的。接口中的常量可以是数据值,也可以是构造器,但这取决于具体的编程风格和使用场景。
5.抽象类和接口有什么区别
抽象类(Abstract Class)和接口(Interface)都是Java中支持抽象概念的结构,它们都不能被实例化,可以包含抽象方法(即没有具体实现的方法)。但是,它们之间存在一些关键的区别:
-
设计目的:
- 抽象类通常作为多个类的共同的父类使用,用来封装这些类中的共同特征,包括字段和方法。
- 接口则主要用来规定一个形式标准(Contract),是一种形式化的声明,它定义了类必须实现的方法,但不关注这些方法的实现细节。
-
方法实现:
- 抽象类可以包含抽象方法和具体方法,即可以有方法的实现,也可以没有。
- 接口只能包含抽象方法(在Java 8之前的版本),在Java 8及之后的版本中,接口可以包含默认方法(default methods)和静态方法(static methods),默认方法可以有具体实现。
-
状态存储:
- 抽象类可以包含成员变量(fields),这些变量可以是非常量的,因此可以在抽象类中定义状态(state)。
- 接口只能包含常量(在Java 8之前),即默认为
public static final
的变量。在Java 8及之后的版本中,接口不能包含实例字段,但可以包含静态字段。
-
构造函数:
- 抽象类可以包含构造函数,而接口不能。
-
继承和实现:
- 一个类只能继承自一个抽象类,这是因为Java不支持多重类继承。
- 一个类可以实现多个接口,提供了一种形式的多重继承。
-
访问修饰符:
- 抽象类中的成员可以有多种访问修饰符,可以是public、protected或private。
- 接口中的方法和变量默认都是public的,在Java 9及之后的版本中,接口还可以包含私有方法(private methods),这些方法是不会被继承的。
-
扩展性:
- 向抽象类添加新方法可能会破坏子类。
- 接口是一种更加灵活的结构,尤其是在Java 8之后,可以通过默认方法添加新行为而不破坏实现该接口的类。
根据你的具体需求来选择使用抽象类还是接口。如果你的抽象概念更侧重于"是什么"("is-a"),那么使用抽象类;如果它更侧重于"能做什么"("can-do")或"具有什么功能"("has-a"),那么使用接口。随着Java语言的发展,接口的功能得到了增强(如默认方法),这使得接口在某些情况下可以作为抽象类的替代品。
6.说说反射的用途及实现
反射(Reflection)是一种强大的特性,允许Java程序在运行时检查或修改其自身的结构和行为。反射提供了一种机制,通过它可以在运行时获取类的信息(比如类的方法、字段、构造器等)并动态地创建对象、调用方法、访问字段和构造器等。这种动态性使得Java程序更加灵活和强大。
反射的主要用途包括:
-
运行时类信息获取:可以在运行时获取类的信息,例如类的名字、修饰符、包信息、父类、实现的接口、方法、字段等。
-
动态创建对象:可以在不知道类名的情况下创建对象实例,这对于扩展性和灵活性有很大帮助。
-
动态调用方法:可以在运行时调用任何方法,无需提前编码这些调用,这能够大大增加程序的灵活性。
-
动态访问和修改字段:可以在运行时访问和修改对象的字段,无论它们原本的访问权限如何。
-
实现通用代码:反射允许编写更通用的代码,这些代码可以与许多不同类型的对象一起工作。
-
框架和库:许多流行的框架(如Spring)和库使用反射来实现依赖注入、ORM(对象关系映射)、远程方法调用等功能。
反射的实现通常涉及以下几个步骤:
-
获取
Class
对象的引用:可以通过直接使用.class
语法、调用对象的.getClass()
方法或者使用Class.forName()
静态方法实现。1Class<?> cls1 = String.class; 2Class<?> cls2 = "hello".getClass(); 3Class<?> cls3 = Class.forName("java.lang.String");
-
分析类的能力:使用
Class
对象的方法来检索类的信息。1// 获取类的方法 2Method[] methods = cls1.getDeclaredMethods(); 3 4// 获取类的字段 5Field[] fields = cls1.getDeclaredFields(); 6 7// 获取类的构造器 8Constructor<?>[] constructors = cls1.getDeclaredConstructors();
-
创建实例:使用
Class
对象的newInstance()
方法或者获取到的构造器对象来创建类的实例。1Object obj1 = cls1.newInstance(); // Deprecated since Java 9 2Constructor<?> constructor = cls1.getConstructor(String.class); 3Object obj2 = constructor.newInstance("constructor-arg");
-
访问字段和调用方法:使用
Field
和Method
对象来访问字段和调用方法。1// 访问字段 2Field field = cls1.getField("someField"); 3Object fieldValue = field.get(obj); 4 5// 调用方法 6Method method = cls1.getMethod("someMethod", String.class); 7method.invoke(obj, "method-arg");
-
修改字段的值:可以使用
Field
对象的set()
方法来修改字段的值,即使它是私有的。1field.setAccessible(true); // 设置为可访问,忽略访问权限 2field.set(obj, "new value");
反射虽然功能强大,但也存在一些缺点:
- 性能开销:反射操作通常比直接代码调用要慢,因为它需要在运行时分析类的元数据。
- 安全限制:反射可能会打破封装性,改变原本私有的字段和方法,这可能会导致安全问题或者代码的不稳定。
- 维护难度:由于反射代码的动态性,它可能难以理解和维护。
使用反射时,应该权衡利弊,并在确实需要动态性时才使用。在某些情况下,可以考虑使用其他编程技术或模式(如设计模式)来达到类似的结果,同时保持更好的性能和代码可维护性
7.说说自定义注解的场景及实现
自定义注解(Custom Annotations)在Java中是一种特殊的语法元素,它允许为代码添加元数据,这些元数据可以在编译时、类加载时或者运行时被读取,并且可以影响程序的行为。自定义注解广泛用于提供配置信息、编译检查、代码分析、测试框架等场景。
自定义注解的常见场景:
-
配置框架: 框架,如Spring,使用注解来配置应用程序组件和依赖注入,例如
@Component
、@Service
、@Autowired
等。 -
代码校验: 注解可用于静态代码分析工具,如检查是否遵守某些编码标准或寻找潜在的错误。
-
编译时处理: 创建编译时注解处理器,可以在编译时生成额外的源代码或资源文件。
-
测试代码: 测试框架,如JUnit,使用注解来标识测试方法(
@Test
)、设置测试环境(@Before
、@After
)等。 -
Web应用开发: Web框架使用注解来定义路由、请求和响应类型等,如JAX-RS的
@Path
、@GET
、@POST
等。 -
持久层框架: ORM框架,如Hibernate和JPA,使用注解来映射对象到数据库表。
实现自定义注解:
要实现自定义注解,需要使用@interface
关键字,并且可以选择性地为注解定义成员。成员在使用注解时以键值对的形式提供,如果有默认值可以省略。
1import java.lang.annotation.*; 2 3// 定义注解的保留策略和目标 4@Retention(RetentionPolicy.RUNTIME) 5@Target(ElementType.METHOD) 6public @interface MyAnnotation { 7 // 定义注解的成员 8 String value() default "Default Value"; // 带默认值的成员 9 int number() default 0; // 另一个带默认值的成员 10}
注解成员的类型限制为原始类型、String、Class、枚举、注解以及前述类型的数组。
使用自定义注解:
自定义注解可以被应用到类、方法、字段等元素上,取决于注解的@Target
定义。
1public class Example { 2 @MyAnnotation(value = "Custom Value", number = 42) 3 public void myMethod() { 4 // 方法实现 5 } 6}
读取自定义注解:
在运行时,可以通过反射API读取注解并执行相应的处理。
1Method method = Example.class.getMethod("myMethod"); 2if (method.isAnnotationPresent(MyAnnotation.class)) { 3 MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class); 4 System.out.println("value: " + myAnnotation.value()); 5 System.out.println("number: " + myAnnotation.number()); 6}
8HTTP 请求的 GET 与 POST 方式的区别
HTTP(超文本传输协议)定义了客户端与服务器之间交换数据的不同方法,其中最常用的是GET和POST请求。这两种请求方法有一些关键的区别:
-
用途和语义:
- GET请求通常用于请求服务器发送资源。按照HTTP规范的语义,GET请求应该是幂等的,也就是说,它不应该引起服务器状态的变化。
- POST请求通常用于提交数据给服务器,如表单提交。与GET不同,POST请求可能会引起服务器状态的变化或副作用,比如在数据库中创建一条记录。
-
参数传递:
- GET请求的参数通常附加在URL之后,以查询字符串的形式出现,例如
?key1=value1&key2=value2
。这意味着GET请求的参数会被完全暴露在地址栏中。 - POST请求的参数则包含在请求体中,不会显示在URL中,因此可以发送更多的数据,并且提供了更好的隐私。
- GET请求的参数通常附加在URL之后,以查询字符串的形式出现,例如
-
数据大小:
- GET请求因为受到URL长度的限制(不同浏览器和服务器对URL长度的限制不同),因此无法发送大量数据。
- POST请求没有URL长度限制的问题,理论上可以发送更大量的数据,因此适合表单提交、文件上传等场景。
-
安全性:
- GET请求由于参数在URL中,所以安全性较低,敏感信息不应该通过GET请求传送。
- POST请求更加安全,因为数据不会保存在浏览器历史或服务器日志中。
-
缓存和历史:
- GET请求可以被缓存,并且会留在浏览器的历史记录中。
- POST请求不会被缓存,通常也不会留在浏览器的历史记录中。
-
书签和分享:
- GET请求可以被书签,也更容易分享(复制粘贴URL)。
- POST请求不可以直接书签,因为它包含了请求体,无法通过URL完整表示。
-
幂等性:
- GET请求应该是幂等的,意味着多次执行相同的GET请求,服务器上的资源状态不会改变。
- POST请求一般不是幂等的,同样的POST请求如果多次执行,可能会每次都产生副作用(如创建多个资源)。
-
使用场合:
- 使用GET请求时,主要用于获取信息,例如搜索、查询、阅读页面等操作。
- 使用POST请求时,主要用于修改服务器上的资源,例如用户注册、提交订单等操作。
总结来说,GET和POST请求在HTTP协议中有着不同的语义和使用场景。选择正确的方法将有助于遵循HTTP协议的设计意图,并确保Web应用的可靠性和效率
9.session 与 cookie 区别
Session和Cookie都是用于存储客户端和服务器交互中需要持久化的信息的机制,但它们在处理方式、存储位置和安全性等方面存在一些差异。
Cookie
-
存储位置:Cookie数据存储在客户端(通常是浏览器)。
-
存储内容:Cookie主要用于存储字符串类型的小数据量信息。
-
安全性:由于存储在客户端,Cookie数据容易被篡改和拦截,相对不那么安全。为了提高安全性,可以使用加密Cookie和设置HttpOnly标志。
-
生命周期:Cookie可以设置过期时间。如果不设置过期时间,它就是一个会话Cookie,浏览器关闭时就会被删除。设置了过期时间后,Cookie可以在本地持久化,直到过期时间。
-
发送请求时:每次客户端请求服务器时,Cookie都会自动添加到请求头中发送给服务器。
-
大小限制:Cookie有大小限制(不同浏览器有不同的限制,一般为4KB左右),而且每个域名下存储的Cookie数量也有限制。
Session
-
存储位置:Session数据存储在服务器端。
-
存储内容:Session可以存储任何类型的数据,包括对象和大量数据。
-
安全性:相较于Cookie,Session更安全,因为数据存储在服务器端,客户端无法直接访问。
-
生命周期:Session的生命周期通常由服务器控制,一般是基于用户的会话时间。用户关闭浏览器或服务器端超时设置都可能导致Session结束。
-
发送请求时:为了维持会话,客户端通常需要带上一个Session标识(例如,一个名为JSESSIONID的Cookie),服务器通过这个标识来查找对应的Session数据。
-
大小限制:Session没有大小限制,但存储过多数据会增加服务器的内存压力。
Session和Cookie的比较
-
生命周期:Cookie可以在客户端本地存储,而Session存在于服务器上的会话时间内。
-
安全性:Session比Cookie安全,因为Session数据存储在服务器端。
-
存储能力:Session可以存储更多信息,而Cookie受到大小和数量的限制。
-
服务器资源:Session数据存储在服务器上,如果大量使用将占用较多服务器资源。Cookie则存储在客户端,不占用服务器资源。
-
跨域问题:Cookie设置时可以设置其对应的域(domain)和路径(path),实现跨域访问的控制;而Session通常只在同一域中有效,不同域的Session管理需要特殊的处理。
在实际应用中,为了结合两者的优势,经常会将Session ID存储在Cookie中,以此标识用户的会话。这样既利用了Session的安全性,又使用Cookie方便的客户端存储机制来维持会话状态
9 session 分布式处理
在分布式系统中,由于应用可能部署在多个服务器上,单机版的session管理已经不能满足需求,我们需要确保用户的会话信息在所有服务器之间同步,以便用户可以无缝地与任何服务器交互。以下是几种常见的分布式session处理方案:
-
粘性Session(Sticky Sessions):
- 配置负载均衡器,使得来自同一个用户的所有请求都转发到同一台服务器。
- 这是最简单的方法,但如果那台服务器崩溃,用户的会话信息将丢失。
-
Session复制:
- 在服务器集群中复制session信息。
- 每次session更新时,这些更新都会发送到集群中的其他服务器。
- 这种方法的缺点是它会占用额外的网络带宽,并且随着集群规模的扩大,复制的成本增加。
-
集中式Session存储:
- 将所有session信息存储在集中的数据存储中,例如数据库或内存缓存(如Redis、Memcached)。
- 任何服务器都可以从该存储中读取和写入session信息。
- 这种方法的优点是可以扩展性好,而且对服务器故障有更好的容错性。
-
客户端Session:
- 将session数据存储在客户端,通常是以Cookie的形式。
- 每次HTTP请求都会发送session数据,因此这种方案可能会导致数据暴露或被篡改的风险。
- 可以通过加密和签名来增强安全性,但这会增加处理请求的复杂性。
-
Token-based身份验证(如JWT):
- 使用基于令牌的方法(例如JSON Web Tokens, JWT)来管理会话。
- 服务器验证用户的身份并发放一个签名的token,客户端随后的每个请求都携带这个token。
- 服务器通过验证token的签名来认证用户,而不需要存储会话信息。
- 这种方法减少了服务器的存储需求,但需要额外的考虑来保证token的安全性。
实现分布式Session存储的考虑因素:
- 一致性:需要确保所有服务器看到的session信息都是一致的。
- 可用性:集中式session存储应该具有高可用性,以避免成为单点故障。
- 安全性:存储session数据时需要确保数据安全,避免泄露用户敏感信息。
- 性能:读取和写入session数据应该尽可能快,以避免降低用户体验。
- 扩展性:随着用户数量的增长,session管理系统应该能够容易扩展。
总之,分布式session管理是构建可扩展和高可用性应用程序的关键。在实施任何分布式session解决方案时,都需要权衡不同方案的利弊,并考虑应用的具体需求和限制。
10 JDBC 流程
JDBC(Java Database Connectivity)是Java语言中用于与数据库进行交互的API,它定义了一组接口和类,使得Java应用程序能够统一地访问各种关系型数据库。使用JDBC进行数据库操作通常涉及以下步骤:
-
加载JDBC驱动:
- 在应用程序中加载并注册数据库的JDBC驱动,这样程序就能知道如何与特定的数据库通信。Java 6及以后的版本会自动从类路径中加载驱动,所以通常不需要显式加载驱动。
1// 在Java 6之前的版本中常用的显式加载驱动的代码 2Class.forName("com.mysql.cj.jdbc.Driver");
-
建立数据库连接:
- 通过
DriverManager
类获取数据库的连接(Connection
)。需要提供数据库的URL、用户名和密码。
1String url = "jdbc:mysql://localhost:3306/databaseName"; 2String username = "username"; 3String password = "password"; 4Connection conn = DriverManager.getConnection(url, username, password);
- 通过
-
创建
Statement
对象:- 通过
Connection
对象创建Statement
、PreparedStatement
或CallableStatement
对象。Statement
用于执行静态SQL语句,PreparedStatement
用于执行预编译的SQL语句,而CallableStatement
用于执行存储过程。
1Statement stmt = conn.createStatement(); 2PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM table WHERE column = ?"); 3CallableStatement cstmt = conn.prepareCall("{call stored_procedure(?, ?)}");
- 通过
-
执行SQL语句:
- 使用
Statement
对象执行SQL语句。根据操作类型的不同,可能会调用executeQuery
(用于SELECT查询)、executeUpdate
(用于INSERT、UPDATE、DELETE语句)或execute
(对于更通用的情况)方法。
1ResultSet rs = stmt.executeQuery("SELECT * FROM table"); 2int rowsAffected = pstmt.executeUpdate(); 3boolean hasResults = cstmt.execute();
- 使用
-
处理结果集:
- 对于查询操作,执行SQL语句会返回一个
ResultSet
对象,程序需要遍历这个对象来处理查询结果。
1while (rs.next()) { 2 String data = rs.getString("column_name"); 3 // 处理获取到的数据 4}
- 对于查询操作,执行SQL语句会返回一个
-
关闭资源:
- 使用完数据库资源后,应该关闭
ResultSet
、Statement
和Connection
对象,释放占用的资源。最好在finally
块中或使用try-with-resources语句来确保这些资源总是被正确关闭。
1// 使用try-with-resources语句自动关闭资源 2try (Connection conn = DriverManager.getConnection(url, username, password); 3 Statement stmt = conn.createStatement(); 4 ResultSet rs = stmt.executeQuery("SELECT * FROM table")) { 5 while (rs.next()) { 6 // 处理结果集 7 } 8} catch (SQLException e) { 9 e.printStackTrace(); 10}
- 使用完数据库资源后,应该关闭
以上就是一个典型的JDBC操作数据库的流程。在实际应用中,JDBC代码通常会更加复杂,需要处理异常、事务控制、连接池管理等。因此,很多开发者会选择使用ORM框架(如Hibernate、MyBatis)来简化数据库操作,这些框架内部依然使用JDBC技术与数据库通信。
11.MVC 设计思想
MVC(Model-View-Controller)设计思想是一种软件架构模式,它将应用程序分为三个相互协作的部件或层,以实现业务逻辑、数据处理和用户界面展示之间的解耦。每个部分负责不同的职责:
模型(Model):
模型层代表了应用程序的核心业务逻辑和数据结构。
它包含了所有与应用状态和数据相关的操作,如数据库访问、业务规则验证、数据计算等。
当模型的状态发生变化时,通常会通知相关视图进行更新。
视图(View):
视图层是用户看到并与之交互的界面部分。
视图从模型获取数据并将其呈现给用户,但它不直接操作数据,而是显示由模型提供的数据。
视图通常依赖于模型的数据变化,通过监听或数据绑定机制来自动刷新界面。
控制器(Controller):
控制器层负责接收用户的输入请求,并根据请求执行相应的业务逻辑。
控制器解析用户的操作,调用模型的方法来处理数据,并决定应该向哪个视图传递这些结果或触发什么样的视图更新。
在Web开发中,控制器类通常使用注解如@Controller或@RestController来定义路由处理函数,它们作为HTTP请求和响应处理的入口点。
采用MVC设计模式的好处包括:
分离关注点:各层专注于自己的功能,便于代码维护和扩展。
可重用性:视图可以独立于模型和控制器改变,反之亦然。
灵活性:可以根据需求更改视图的表现形式而无需修改模型或底层业务逻辑。
测试方便:各个组件可以独立测试,降低了模块间相互影响导致的测试复杂度。
在现代Web框架(如Spring MVC、ASP.NET MVC等)中,MVC模式得到了广泛应用和发展,虽然具体的实现细节可能有所不同,但核心理念仍然保持一致。
12.equals 与 == 的区别
在 Java 中,equals
方法和 ==
操作符都用于比较两个对象,但它们的比较方式和使用场景有所不同。
==
操作符
- 基本类型:当用于基本数据类型(如
int
、char
、double
等)时,==
比较的是值是否相等。 - 引用类型:当用于引用类型(如对象)时,
==
比较的是两个引用是否指向内存中的同一个对象实例。
例如:
1String str1 = new String("example"); 2String str2 = new String("example"); 3boolean result = (str1 == str2); // 结果为 false,因为 str1 和 str2 指向不同的对象实例
equals
方法
equals
是Object
类的一个非静态方法,它用于检查两个对象的内容是否相等。默认实现(即Object
类中的实现)是使用==
操作符来比较两个对象的引用。- 通常,当创建一个类时,如果需要基于对象的内容而不是对象引用来判断相等性,就应当重写
equals
方法。 - 例如,
String
类重写了equals
方法,使得它可以比较两个字符串的内容是否相等。
1String str1 = new String("example"); 2String str2 = new String("example"); 3boolean result = str1.equals(str2); // 结果为 true,因为 str1 和 str2 的内容相同
比较
==
用于基本类型的值比较和引用类型的引用比较。equals
用于比较两个对象的内容是否相等,但需要注意,如果没有在类中重写equals
方法,该方法的行为默认是比较对象的引用(与==
相同)。
重要点
当重写 equals
方法时,应该始终遵守以下约定,以确保该方法的行为符合开发者的期望:
- 自反性:对于任何非空引用值
x
,x.equals(x)
应该返回true
。 - 对称性:对于任何非空引用值
x
和y
,x.equals(y)
应该返回true
当且仅当y.equals(x)
返回true
。 - 传递性:对于任何非空引用值
x
、y
和z
,如果x.equals(y)
返回true
并且y.equals(z)
返回true
,那么x.equals(z)
也应该返回true
。 - 一致性:对于任何非空引用值
x
和y
,多次调用x.equals(y)
应该一致地返回true
或一致地返回false
,前提是对象上的信息没有被修改。 - 对 null 的处理:对于任何非空引用值
x
,x.equals(null)
应该返回false
。
在重写 equals
方法时,通常也需要相应地重写 hashCode
方法,以保持 equals
和 hashCode
之间的一致性合同,这对于将对象作为散列集(如 HashSet
)中的键来说是必要的。
13. string、StringBuilder、StringBuffer的区别
在 Java 中,String
、StringBuilder
和 StringBuffer
都用于处理字符串,但它们在功能和性能方面有所不同。
String
-
String
类表示不可变的字符序列。在 Java 中,每次对字符串进行修改(例如通过拼接、替换等操作),实际上都会创建一个新的String
对象,而不是修改原有对象。由于字符串不可变,它们在多线程环境下是线程安全的。 -
由于
String
对象不可变,频繁的字符串操作可能会导致内存和性能开销。例如:1String s = "Hello"; 2s += " World"; // 这里实际上创建了一个新的 String 对象
StringBuilder
-
StringBuilder
类表示可变的字符序列。它是 Java 5 引入的,提供了一系列用于操作字符串内容的方法,例如append
、insert
、delete
等。由于StringBuilder
是可变的,它可以在不生成新对象的情况下修改字符串。 -
StringBuilder
不是线程安全的。在单线程环境中,对性能要求较高的字符串操作通常应该使用StringBuilder
。例如:1StringBuilder sb = new StringBuilder("Hello"); 2sb.append(" World"); // 直接在原有字符串的基础上追加,没有创建新对象
StringBuffer
-
StringBuffer
类与StringBuilder
类似,也表示可变的字符序列,提供了类似的字符串操作方法。不同之处在于StringBuffer
是线程安全的,所有公共方法都是同步的,这意味着它可以在多线程环境中安全使用。 -
由于
StringBuffer
的线程安全特性,它通常比StringBuilder
慢。如果不需要线程安全,通常建议使用StringBuilder
,因为它的性能更优。例如:1StringBuffer sbf = new StringBuffer("Hello"); 2sbf.append(" World"); // 线程安全的追加操作
总结
- String:不可变字符串类,简单使用时最为方便,但不适用于大量频繁的字符串修改操作。
- StringBuilder:可变字符串类,适用于单线程下需要频繁修改字符串的场景,性能优于
StringBuffer
。 - StringBuffer:可变字符串类,线程安全,适用于多线程下需要频繁修改字符串的场景。
在选择使用 String
、StringBuilder
或 StringBuffer
时,应当根据实际需求和上下文来做出决策。通常在循环、大量字符串操作或拼接时,选择 StringBuilder
或 StringBuffer
,而在字符串相对固定且操作较少的场合使用 String
。
14.List 和 Set 区别
Java中的List和Set都是集合框架的一部分,它们都继承自Collection接口,但具有不同的特性:
列表(List):
特性:有序、可重复
插入顺序与迭代顺序相同。
支持通过索引访问元素,因此可以快速进行随机访问。
允许包含多个null元素(但不是推荐的做法)。
常用实现类包括:ArrayList、LinkedList、Vector等。
ArrayList基于动态数组实现,查询快,增删慢;LinkedList基于双向链表实现,查询慢,增删快。
集合(Set):
特性:无序(不保证插入顺序)、不可重复
不支持索引访问,仅能通过迭代器遍历元素。
只允许包含一个null元素(在某些实现中,如HashSet,可能不允许任何null值)。
Set中的元素唯一性由其equals()方法决定。
常用实现类包括:HashSet、TreeSet、LinkedHashSet等。
HashSet基于哈希表实现,检索效率高,插入删除效率也较高,并且不保证元素的插入顺序;TreeSet基于红黑树实现,自动排序元素(根据自然顺序或自定义比较器),插入删除操作比HashSet慢些,但是提供了排序功能;LinkedHashSet结合了HashSet和LinkedList的特点,它保持元素的插入顺序并且不允许重复。
总结来说,如果你需要维护元素的顺序和允许重复元素,那么选择List;如果你关心元素的唯一性而不关注它们的存储顺序(或者有特定排序需求),则应该使用Set。
15.List 和 Map 区别
Java中的List和Map是两种不同类型的集合,它们分别用于存储不同类型的数据结构,并且具有不同的功能和使用场景:
-
列表(List):
- 类型:有序、可重复的元素序列。
- 特性:
- 元素是有序的,即插入顺序与迭代顺序相同(除非进行了排序操作)。
- 支持索引访问,可以通过下标快速获取或修改指定位置的元素。
- 可以包含重复元素,只要equals()方法判断为不相等即可。
- 常用实现类包括ArrayList、LinkedList和Vector。
-
映射(Map):
- 类型:键值对集合,其中每个键与一个值相关联。
- 特性:
- 键不可重复,根据键唯一性来确定元素的唯一性(键的hashCode()和equals()方法共同决定键的唯一性)。
- 不支持索引访问,而是通过键来查找对应的值。
- 值可以重复,即使多个键对应相同的值也是允许的。
- Map中元素没有明确的顺序,尽管某些实现如LinkedHashMap会按照插入顺序或最近最少使用(LRU)顺序进行迭代。
- 常用实现类包括HashMap、TreeMap、LinkedHashMap等。
总结来说,List适用于需要维护元素顺序并且可能有重复数据的场景;而Map则适用于需要通过唯一的键来关联和检索值的场景,它不关心元素的顺序(除非特殊实现),并且确保键的唯一性。
相关文章:

Java 面试题库
基础篇 面向对象的特征 封装(Encapsulation): 封装是指将对象的数据(属性)和行为(方法)结合在一起,形成一个独立的实体。对象的数据被隐藏在内部,只能通过定义好的接口&…...

仿真机器人-深度学习CV和激光雷达感知(项目2)day6【数学基础-坐标变换】
文章目录 前言坐标变换的作用旋转与平移二维变换旋转平移推广到三维齐次坐标问题引入定义用法变换矩阵旋转的其他表示方法*前言 💫你好,我是辰chen,本文旨在准备考研复试或就业 💫本文内容是我为复试准备的第二个项目 💫欢迎大家的关注,我的博客主要关注于考研408以及…...

Android下载gradle失败解决方法
1、在gradle-wrapper.properties文件中查看自己需要下载gradle什么版本的包和zip路径(wrapper/dists)。 2、在setting中查看Gradle的保存路径,如下图:C:/Users/Administrator/.gradle,加上第一步的zip路径得到下载grad…...

C#,最小生成树(MST)克鲁斯卡尔(Kruskal)算法的源代码
一、Kruskal算法简史 克鲁斯卡尔(Kruskal)算法是一种用来寻找最小生成树的算法,由Joseph Kruskal在1956年发表。用来解决同样问题的还有Prim算法和Boruvka算法等。三种算法都是贪婪算法的应用。和Boruvka算法不同的地方是,Kruska…...

Oracle篇—参数文件在11gRAC或12cRAC的启动位置介绍
☘️博主介绍☘️: ✨又是一天没白过,我是奈斯,DBA一名✨ ✌✌️擅长Oracle、MySQL、SQLserver、Linux,也在积极的扩展IT方向的其他知识面✌✌️ ❣️❣️❣️大佬们都喜欢静静的看文章,并且也会默默的点赞收藏加关注❣…...

scrapy pipelines
1.时间的处理 获取当前时间的字符串 # 创建一个datetime对象并设置为当前时间,该时间少8小时 dt datetime.datetime.now() # 将datetime转换为本地时区 local_tz pytz.timezone(Asia/Shanghai) local_dt local_tz.localize(dt) # 将datetime对象格式化为ISO 86…...

element-ui 打包流程源码解析——babel 相关
目录 1,babel-cli2,babel-core3,.babelrc3.1,presets3.2,plugins其他相关 该文章是为了更好的理解:element-ui 打包流程源码解析(上) 第2.5节 npm run build:utils 打包命令 "…...

听神经瘤的听力学表现
听神经瘤的听力学诊断 听神经瘤的听力学表型多样,听力正常者不能排除听神经瘤;听力损失程度不能预判肿瘤大小;纯音测听与言语识别率不一致应警惕蜗后病变;听性脑干诱发电位诊断听神经瘤敏感度随肿瘤增大而增加。 一.纯…...

C#用DateTime.Now静态属性返回日期的星期信息
目录 一、使用的方法 1.Now属性 2.ToString方法 二、示例 使用DateTime结构的Now静态属性,可以方便地获取系统日期信息。调用时间对象的ToString方法,在该方法的参数中添加适当的格式化字符串,将返回日期的星期信息。 一、使用的方法 1…...

ARMv8-AArch64 的异常处理模型详解之异常类型 Exception types
异常类型详解 Exception types 一, 什么是异常二,同步异常(synchronous exceptions)2.1 无效的指令和陷阱异常(Invalid instructions and trap exceptions)2.2 内存访问产生的异常2.3 产生异常的指令2.4 调…...

Linux操作系统概念
绪论: “心灵纯洁的人,生活充满甜蜜和喜悦。——列夫托尔斯泰”,本章的主要内容是介绍了硬件的组成结构冯诺依曼体系结构以及操作系统的概念和操作系统的作用,本章的内容主要是理论他起到承上启下的作用只有理解了操作系统的运行…...

Speech | 人工智能中关于语音务必需要了解的基础知识(信号处理)及代码
语音是指人们讲话时发出的话语,是一种人们进行信息交流的声音,是由一连串的音组成语言的声音,我们可以理解为语音(speech)声音(acoustic)语言(language)。 目录 0.声音的基本属性 0.1.音高(pitch) 0.2.音量(Volume) 0.3.音色(Timbre) 0…...

c# 单例模式实现
方式一: 在C#中,可以使用单例模式来确保一个类只有一个实例,并提供一个全局访问点。 public class Singleton {private static Singleton instance;private static readonly object lockObject new object();private Singleton(){// 私有构…...

万字长文详解Java线程池面试题
王有志,一个分享硬核 Java 技术的互金摸鱼侠 加入 Java 人的提桶跑路群:共同富裕的Java人 今天是《面霸的自我修养》第 6 篇文章,我们一起来看看面试中会问到哪些关于线程池的问题吧。数据来源: 大部分来自于各机构(J…...

【jQuery入门】链式编程、修改css、类操作和className的区别
文章目录 前言一、链式编程二、修改css2.1 获取css的值2.2 设置单个css属性2.3 设置类样式添加类移除类切换类 三、类操作与className的区别总结 前言 jQuery是一个流行的JavaScript库,广泛用于简化DOM操作和处理事件。在jQuery中,链式编程是一种强大的…...

使用的uview 微信高版本 头像昵称填写能力
<template><view><button class"cu-btn block bg-blue margin-tb-sm lg" tap"wxGetUserInfo">一键登录</button><view><!-- 提示窗示例 --><u-popup :show"show" background-color"#fff">&…...

Hadoop3完全分布式搭建
一、第一台的操作搭建 修改主机名 使用hostnamectl set-hostname 修改当前主机名 关闭防火墙和SELlinux 1,使用 systemctl stop firewalld systemctl disable firewalld 关闭防火墙 2,使用 vim /etc/selinux/config 修改为 SELINUXdisabled 使用N…...

中断——外部中断EXIT
前期疑问:中断可以分成外部中断和内部中断吗 文章目录 前言一、中断知识二、中断编程三、EXIT外部中断/事件控制器 3.1 中断事件线3.2 EXTI初始化结构体详解 四、软件设计 4.1 编程要点 五、代码回顾实现六、补充中断知识总结 前言 野火中断章节有这样一句话 【F…...

Kafka-服务端-副本机制
Kafka从0.8版本开始引入副本(Replica)的机制,其目的是为了增加Kafka集群的高可用性。 Kafka实现副本机制之后,每个分区可以有多个副本,并且会从其副本集合(Assigned Replica,AR)中选出一个副本作为Leader副本,所有的读写请求都由…...

银行数据仓库体系实践(4)--数据抽取和加载
1、ETL和ELT ETL是Extract、Transfrom、Load即抽取、转换、加载三个英文单词首字母的集合: E:抽取,从源系统(Souce)获取数据; T:转换,将源系统获取的数据进行处理加工,比如数据格式转化、数据精…...

云计算入门——Linux 命令行入门
云计算入门——Linux 命令行入门 前些天发现了一个人工智能学习网站,通俗易懂,风趣幽默,最重要的屌图甚多,忍不住分享一下给大家。点击跳转到网站。 介绍 如今,我们许多人都熟悉计算机(台式机和笔记本电…...

自然语言处理(NLP)的发展
自然语言处理的发展 随着深度学习和大数据技术的进步,自然语言处理取得了显著的进步。人们正在研究如何使计算机更好地理解和生成人类语言,以及如何应用NLP技术改善搜索引擎、语音助手、机器翻译等领域。 方向一:技术进步 自然语言处理&…...

让uniapp小程序支持多色图标icon:iconfont-tools-cli
前景: uniapp开发小程序项目时,对于iconfont多色图标无法直接支持;若将多色icon下载引入项目则必须关注包体,若将图标放在oss或者哪里管理,加载又是一个问题,因此大多采用iconfont-tools工具,但…...

丹麦公司注册优势 丹麦公司注册条件 丹麦公司注册注意事项
丹麦公司注册优势 1、开-放的商业环境,拥有公平透明的商业法律和制度。 2、简化的注册流程,无需繁琐的审批程序和复杂的材料准备。 3、全球认可的声誉,有助于提升贵公司的国际形象。 4、该国的政-府在坚持适度紧缩的财政政策,…...

C++PythonC# 三语言OpenCV从零开发(4):视频流读取
文章目录 相关链接视频流读取CCSharpPython 总结 相关链接 C&Python&Csharp in OpenCV 专栏 【2022B站最好的OpenCV课程推荐】OpenCV从入门到实战 全套课程(附带课程课件资料课件笔记) OpenCV 教程中文文档|OpenCV中文 OpenCV教程中文文档|W3Csc…...

vue element MessageBox.prompt this.$prompt组件禁止显示右上角关闭按钮,取消按钮,及点击遮罩层关闭
vue element MessageBox.prompt this.$prompt组件禁止或取消显示右上角关闭按钮,取消按钮,及点击遮罩层关闭 实现效果: 实现代码 MessageBox.prompt(请先完成手机号绑定, 系统提示, {confirmButtonText: 提 交,showClose: false,closeOnClic…...

Oracle 日常健康脚本
文章目录 摘要常用脚本 摘要 保持 Oracle 数据库的良好健康状况对于系统的可靠性和性能至关重要。本文将介绍一些常用的 Oracle 日常健康脚本,帮助您监控数据库并及时识别潜在的问题,以保证数据库的稳定运行。 常用脚本 1.查询数据库实例和实例级别的…...

leetcode670最大交换
给定一个非负整数,你至多可以交换一次数字中的任意两位。返回你能得到的最大值。 示例 1 : 输入: 2736 输出: 7236 解释: 交换数字2和数字7。 示例 2 : 输入: 9973 输出: 9973 解释: 不需要交换。 注意: 给定数字的范围是 [0, 108] int maximumSwap(int num) {…...

XML 注入漏洞原理以及修复方法
漏洞名称:XML注入 漏洞描述:可扩展标记语言 (Extensible Markup Language, XML) ,用于标记电子文件使其具 有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。 XM…...

x-cmd pkg | dasel - JSON、YAML、TOML、XML、CSV 数据的查询和修改工具
目录 简介首次用户快速实验指南基本功能性能特点竞品进一步探索 简介 dasel,是数据(data)和 选择器(selector)的简写,该工具使用选择器查询和修改数据结构。 支持 JSON,YAML,TOML&…...