Map:key-value键值对,常见的有:HashMap、Hashtable、ConcurrentHashMap以及TreeMap等。Map不能包含重复的key,但是可以包含相同的value。
Set:不包含重复元素的集合,常见的有:HashSet、TreeSet、LinkedHashSet等
List:可包含重复元素的集合,常见的有:ArrayList、LinkedList、Stack以及Vector等
tip1:普通的foreach循环,使用keyset()方法,遍历key
Tip2:把所有的键值对装入迭代器中,然后遍历迭代器
1、get把请求的数据放在url上,其格式为 以?分割URL和传输数据,参数之间以&相连;post把请求的数据放在HTTP的包体内
2、get提交的数据最大是2k,post理论上没有限制
3、get请求会被浏览器主动cache,而post不会(除非手动设置)
4、get请求只能进行url编码,而post支持多种编码方式
5、get请求参数会被完整保留在浏览器历史记录里,而post中的参数不会被保留
6、get只接受ascii字符的参数的数据类型,而post没有限制
7、get产生的url地址可以被bookmark,而post不可以
8、get效率高
在jdbc获取连接对象的时候,通过c3p0的工具类来实现
步骤:
导入C3P0库, 配置C3P0连接池, 使用JDBC连接, 关闭连接
(1)、 用户发送请求至前端控制器DispatcherServlet。
(2)、 DispatcherServlet(前端控制器)收到请求调用HandlerMapping处理器映射器。
(3)、 处理器映射器(HandlerMapping)找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet(前端控制器)。
(4)、 DispatcherServlet(前端控制器)调用HandlerAdapter处理器适配器。
(5)、 HandlerAdapter(处理器适配器)经过适配调用具体的处理器(Controller,也叫后端控制器)。
(6)、 Controller(后端控制器)执行完成返回ModelAndView(模型和视图)。
(7)、 HandlerAdapter(处理器适配器)将controller执行结果ModelAndView返回给DispatcherServlet(前端控制器)。
(8)、 DispatcherServlet(前端控制器)将ModelAndView(模型和视图)传给ViewReslover视图解析器。
(9)、 ViewReslover(视图解析器)解析后返回具体View。
(10)、 DispatcherServlet(前端控制器)根据View进行渲染视图(即将模型数据填充至视图中)。
(11)、 DispatcherServlet(前端控制器)响应用户。
mvc框架包含View视图,Controller控制器,Model模型三部分。视图用于渲染数据,模型用于处理业务,控制器起纽带作用:把视图和模型联系在一起
工作流程:
1.浏览器通过视图向控制器发出请求;
2.控制器接收到请求后对数据进行封装,选择模型进行业务逻辑处理;
3.随后控制器将模型处理结果转发到视图或下一个控制器;
4.在视图层合并数据和界面模板生成HTML并做出最终响应。
(1)避免使用*
(2)避免复杂的多表连接
(3)建立有效索引
(4)读写分离
3、如果是多线程环境下涉及到共享变量的插入和删除操作,StringBuffer则是首选。如果是非多线程操作并且有大量的字符串拼接,插入,删除操作则StringBuilder是首选。
StringBuffer是同步的,StringBuilder不是。
Redis是一种非关系型数据库,存储数据使用K-V形式,有时redis作为缓存来用,搭建redis缓存集群。
Redis的基本数据类型:字符串(String),列表(List),集合(Set),
有序集合(Sorted Set),哈希表(Hash)
老师更新:
ssm指spring、springmvc和mybatis三个框架。springmvc属于spring框架的组件,实现了mvc模型,提供前端路由映射、视图解析等功能。spring框架提供了AOP的编程思想,来管理事务。同时通过IoC实现各层的依赖注入。myabtis集成到spring框架,主要作用在持久层,封装了jdbc,提供了一、二 级缓存。
第六,使用js或dom实现局部刷新。
(1)继承Thread父类
(2)实现runnable接口
(3)使用线程池技术
(4)使用Callable实现有返回值的线程
类的不同:sleep() 来自 Thread类,wait() 来自 Object类。
释放锁:sleep() 不释放锁;wait() 释放锁。
使用的范围是不同的:wait:只能在同步代码块中使用;sleep:可以在任何地方使用
用法不同:sleep() 时间到会自动恢复;wait() 可以使用 notify()/notifyAll()直接唤醒。
start() 方法用于启动线程,run() 方法用于执行线程的运行时代码。
run() 可以重复调用,而 start() 只能调用一次。
第二次调用start() 必然会抛出运行时异常
触发器属于数据库中的对象,通常绑定在某个表上,封装一定的功能,当对该表记录进行增删改操作时,触发器会自动触发并执行其封装的功能
static修饰的属性和方法属于类,供所有类的对象共享
static访问特点:
非静态成员方法
1.能够访问静态的成员变量;
2.能够访问非静态的成员变量;
3.能够访问静态的成员方法;
4.能够访问非静态的成员方法;
静态的成员方法
1.能够访问静态成员变量,但是不能够直接访问非静态成员变量
2.能够访问静态的成员方法,但是不能够直接访问非静态成员方法
当使用static修饰和不使用static时,有以下不同点:(GPT3.5)
1. 内存分配:
使用static修饰的成员在类加载时分配内存,只有一个副本存在于内存中,而不管创建多少类的实例。
不使用static修饰的成员在每个类的实例创建时分配内存,每个实例都有自己的一份成员变量副本。
2. 访问方式:
静态成员可以通过类名直接访问,如ClassName.staticField或ClassName.staticMethod()。
实例成员需要通过创建类的实例来访问,如Object.instanceField或Object.instanceMethod()。
3. 共享性:
静态成员适用于实现全局变量或单例模式,多个类的实例可以共享相同的静态成员。
实例成员用于存储每个类的实例的状态,每个实例拥有独立的成员变量。
4. 生命周期:
静态成员的生命周期与类相同,一直存在于应用程序的整个生命周期。
实例成员的生命周期与类的实例相关联,当实例被销毁时,实例成员也会被销毁。
5. 适用场景:
静态成员适用于存储与类相关的共享信息,如工具类、常量、计数器等。
实例成员适用于存储与类的每个实例相关的状态信息,如对象的属性。
登录过程:
用户提供用户名和密码。
服务器接收到用户名和密码。
服务器查找数据库以获取与提供的用户名相关联的用户记录。
服务器使用存储在数据库中的用户密码的散列值与用户提供的密码进行比较。
如果密码匹配,则用户成功登录;否则,登录失败。
使用jdk自带的工具类通过MD5加密算法加密。
登录功能的密码加密一般使用哈希算法,比如MD5(128位)、SHA-1(160位)、SHA-256(256位)等。在注册时,用户输入的密码经过哈希算法加密后存储到数据库中。在登录时,用户输入的密码再次经过相同的哈希算法加密,与数据库中存储的加密密码进行比较验证。这样可以确保密码不以明文形式存储,增加了安全性。
git属于团队协作的版本控制技术,支持分布式。通常由本地库和远程库构成。同21
先将本地修改的代码缓存起来,git stash,然后是git pull,然后还原暂存的内容git stash pop,git status查看哪些文件冲突了,就vim打开冲突的文件,把文件里面的冲突标识符删掉,然后再git add,git commit即可。
(1)抽象类中可以包含抽象方法和普通方法,而接口中只可以包含抽象方法,且abstract可省略
(2)接口是公开的,里面不能有私有的方法或变量,而抽象类是可以有私有方法或私有变量的
(3)实现接口时一定要实现接口里定义的所有方法,而继承抽象类可以有选择地重写需要用到的方法
(4)接口可以实现多重继承,而一个类只能继承一个父类
1. 在数组中选一个基准数(通常为数组第一个;
2. 将数组中小于基准数的数据移到基准数左边,大于基准数的移到右边;
3. 对于基准数左、右两边的数组,不断重复以上两个过程,直到每个子集只有一个元素,即为全部有序。
快速排序的时间复杂度为O(nlogn),是一种常用且高效的排序算法。
1.Executor接口:
2.ExecutorService接口:
3.ThreadPoolExecutor类:
4.Executors工厂类:
5.Future接口:
6.CompletionService接口:
7.ScheduledExecutorService接口:
8.ThreadPoolExecutor工厂类:
9.BlockingQueue接口:
往届回答的是Java中Executors工厂类创建线程池的四个常见方法
(1).newCachedThreadPool
(2).newFixedThreadPool
(3).newSingleThreadExecutor
(4).newScheduleThreadPool
使用new关键字:
使用反射:
使用对象克隆:
使用工厂方法:
使用单例模式:
使用静态工厂方法:
使用序列化/反序列化:
使用依赖注入框架:
1.浅拷贝会直接进行值传递,也就是将该属性值复制一份给新的对象。 简而言之,需要复用现有对象的基本类型的成员变量数据时,浅拷贝即可。
2.复制整个对象(复制前后两个对象完全一样)。 深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。深拷贝相比于浅拷贝速度较慢并且花销较大。
第一点,深拷贝和浅拷贝的解释
深拷贝:复制整个依赖的变量
浅拷贝:复制过程中只复制一层变量,不会复制深层变量所绑定的变量
第二点,深拷贝和浅拷贝的区别
深拷贝生成的新的列表和原列表没有关系
浅拷贝生成的列表如果修改的不是第一层变量,复制的列表会随之改变,但是如果改变的是第一层的变量,新列表不会修改
两个问题
哪里不同?
都是浅拷贝,但实现方式不同。ArrayList基于System.arraycopy,LinkedList主要依靠自己的循环遍历。
为何不同?
很简单,造成ArrayList和LinkedList各种差异的原因,最终都是由于其底层数据结构不同造成的,前者是数组,后者是链表。
1.前端项目通过Vue框架的脚手架和Node.js工具把项目打包部署到Nginx服务器上
2.后端项目通过Maven打包成war包部署到Tomcat服务器上
3.前后端数据的互通是通过Ajax+Json技术实现的
1.基本数据类型,==比较的是两边的值是否相等;引用类型的对象,==比较的是两个对象地址是否相同
2.equals只能比较引用类型的对象,默认比较两个对象内存地址是否一致;重写equals方法的话,先比较的是对象类型,类型相同才会比较对象里面的值
编译器每次碰到"+"的时候,会new- 个StringBuilder,接着调用append方法,再调用toString方法,生成新字符串。若代码中有很多"+",就会每个"+"生成一次StringBuilder, 这种方式对内存是一种浪费, 效率很不好。由于这样子拼接字符串的低效,我们才需要使用StringBuilder和StringBuffer来拼接。
StringBuffer和StringBuilder二者的区别主要就是StringBuffer是线程安全的,而StringBuilder是线程不安全的。
SELECT:用于从数据库中检索数据。
INSERT INTO:用于将新数据插入到数据库表中。
UPDATE:用于修改数据库表中的数据。
DELETE FROM:用于从数据库表中删除数据。
DISTINCT: 可以去除重复的数据
CREATE TABLE:用于创建新的数据库表。
ALTER TABLE:用于修改数据库表结构。
DROP TABLE:用于删除数据库中的表。
INDEX:用于创建索引,优化数据库性能。
JOIN:用于将两个或多个表中的数据相关联。
UNION:用于将两个或多个查询结果集合并。
GROUP BY:用于对查询结果进行分组。
HAVING:用于对分组后的数据进行筛选。
ORDER BY:用于对查询结果进行排序。
LIMIT:用于限制查询结果的数量。
主键是一种用于唯一标识表中每一行数据的标识符。在Mysql中,主键可以是一个或多个列的组合,但是必须满足以下条件:
外键是一个表中的一列或多列,其值必须匹配另一个表中的主键值或唯一值
约束:约束是对表中数据进行限制的规则。约束可以是列级别或表级别。列级别约束只对单个列起作用,而表级别约束则对整个表起作用。
索引:索引是一种特殊的数据结构,它提供了快速访问表中特定行的方法。索引可以在单个列上创建,也可以在多个列上创建。
any,all,exist,in
in关键字主要用于查找属性值是否属于指定的集合,属于比较常用的一个
any关键字用来表示父查询满足子查询结果的任意一个值,可以和比较运算符进行
all关键字用来表示父查询满足子查询结果的所有值,可以和比较运算符进行
关键字exists用来判断子查询是否返回结果集
break:跳出当前循环。
continue:跳过当前迭代,继续下一次迭代。
使用标签(label)和break:跳出嵌套循环中的一层循环。
Java中的异常分为两大类:编译时异常和运行时异常,也被称为受检异常和非受检异常。所有的RuntimeException类及子类都被称为运行时异常,其他的异常都是编译时异常
编译时异常:必须显示处理,否则程序会发生错误,无法通过编译;
运行时异常:无需显示处理,也可以通过编译时异常一样处理;
finally:一般用于资源释放,断开连接,关闭管道流等
一般搭配try -- catch --finally 或者 try --- finally
一般来说无论try中是否抛出异常,都会执行finally。
final:
1.final 是一个关键字,用于声明不可变的特性。
2.当应用于类时,final 表示该类不能被继承,即它是一个最终类,不能有子类。
3.当应用于方法时,final 表示该方法不能被子类重写。
4.当应用于变量时,final 表示该变量是一个常量,只能被赋值一次,之后不能再修改
finally:
1.finally 是一个关键字,用于结构化异常处理,通常与 try 和 catch 结合使用。
2.无论是否发生异常,finally 代码块中的代码都会被执行。
3.它通常用于确保资源(如文件、数据库连接等)被正确关闭,以防止资源泄漏。
总结:
final 用于声明不可变性,可以应用于类、方法和变量。
finally 用于结构化异常处理,确保代码块中的代码得到执行,通常用于资源管理和清理。
public、protected、default(无修饰符,默认)、private
JDK用于开发Java应用程序,JRE用于运行Java应用程序。
JDK和JRE都可以单独安装,若不需要开发Java程序,只需要运行的话,那么,只用安装JRE即可。
Spring Boot自动装配原理: Spring Boot的自动装配原理是基于Spring的IoC和依赖注入的机制。当引入一个Spring Boot Starter依赖时,它会自动扫描并加载相关的配置类和组件,完成对应的配置和初始化工作。
Spring AOP是一种面向切面编程的思想,用于将横切关注点与核心业务逻辑解耦。它通过切面定义通知和切点,在特定连接点上执行相应的业务逻辑,实现日志记录、事务管理、异常处理等功能。
切面是AOP中的模块化横切关注点,包含一系列通知和切点的定义。切面通过将横切关注点应用到特定连接点上,实现与核心业务逻辑的解耦,提高代码的可重用性和可维护性。
总的来说,Spring Boot的自动装配原理和Spring AOP思想及切面的概念都是为了实现代码的模块化、可重用和易于维护。它们在Spring框架中起到了重要的作用。
在使用linux时,经常需要进行文件查找。其中查找的命令主要有find和grep。两个命令是有区的。
区别:
(1)find命令是根据文件的属性进行查找,如文件名,文件大小,所有者,所属组,是否为空,访问时间,修改时间等。
(2)grep是根据文件的内容进行查找,会对文件的每一行按照给定的模式(patter)进行匹配查找。
Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。包含在 java.lang.annotation 包中。
String,字符串 Hash,散列 List,列表 Set,集合 Sorted set
方式一:编写一个类,直接继承Thread类并重写run()方法
方式二:编写一个类,实现Runnable接口并重写run()方法
方式三:实现Callable接口(JDK8新特性)
方式四:使用线程池技术
关系:PreparedStatement继承自Statement,都是接口
区别:PreparedStatement可以使用占位符,是预编译的,批处理比Statement效率高
1、String类型的字符串对象是不可变的,一旦String对象创建后,包含在这个对象中的字符序列是不可以改变的,直到这个对象被销毁。
2、StringBuilder和StringBuffer类型的字符串是可变的,不同的是StringBuffer类型的是线程安全的,而StringBuilder不是线程安全的
3、如果是多线程环境下涉及到共享变量的插入和删除操作,StringBuffer则是首选。如果是非多线程操作并且有大量的字符串拼接,插入,删除操作则StringBuilder是首选。
46.jdbc的使用过程((Java Database connect))
1、加载JDBC驱动程序;
2、基于JDBC连接的URL,创建数据库的连接;
3、创建数据库操作对象,如Statement对象,执行SQL语句进行CURD操作;
4、关闭JDBC对象,释放资源。
MySQL是一种开源的关系型数据库管理系统,具有跨平台、高性能、可扩展、数据安全性、多语言支持、强大的功能等优势。它被广泛应用于各种Web应用和企业级应用中。
反射是Java语言提供的一种机制,允许程序在运行时检查和操作类、方法、字段等元数据。通过反射,代码可以在运行时获取类的信息,创建实例,调用方法和访问字段。
反射的应用场景包括:
总体来说,反射提供了一种在运行时操作类和对象的能力,使程序更加灵活和通用,但使用反射也需要注意性能和安全性的问题。
多线程:多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务。
总结一下,对于JDK 8版本,在Java中实现锁机制可以使用以下几种方式:
这些是在JDK 8版本中常用的锁机制。它们可以用于实现同步和互斥,保证多线程访问共享资源的安全性。在使用锁机制时要注意锁的粒度和避免死锁等问题。