java面试 - 对java的基础数据结构和算法进行复习和练习

本文详细介绍了JVM内存模型、Java集合类、多线程处理、Spring框架及Hibernate的相关概念和技术细节,帮助读者深入理解Java核心机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

jvm的内存模型

java虚拟机内存运行时分为几块区域:方法区和堆是线程共有的,虚拟机栈、本地方法栈、程序计数器是线程私有的。
方法区的作用:用来存放加载类的信息、常量、静态变量、即时编译后的代码等数据。
堆的作用:存放实例对象。
虚拟机栈的作用:描述的是java方法执行的内存模型,存储的是局部变量、操作数栈、动态链接、方法出口等信息。每一个方法从开始执行到结束都对应着一个栈帧从入栈到出栈的过程。
本地方法栈的作用:和虚拟机栈的作用类似,本地方法栈是为了虚拟机的native方法服务。
程序计数器的作用:可以看做是当前线程执行的字节码的行号指示器。通过改变计数器来确定吓一跳执行的字节码命令。

2、java内存溢出的种类 java堆溢出、虚拟机栈和本地方法栈溢出、方法区和运行时常量池溢出、本机直接内存溢出。

3、jvm参数配置 -Xmx –Xms:指定最大堆和最小堆
-Xmn 设置新生代的大小
-XX:NewRatio 设置两个新生代Eden和老年代的比值
-XX:SurvivorRatio 设置两个幸存带和eden代的比值

-XX:PermSize -XX:MaxPermSize 设置永久区的厨师空间和最大空间

-Xss设置栈空间的大小,通常只有几百k

static

(1)、静态方法
静态方法不依赖于任何对象就能访问,所以在静态方法中不能访问类的非静态成员变量和非静态成员方法。但是非静态方法可以访问静态方法和变量。

(2)、静态代码块
static关键字还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次 (3)、静态变量 static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响

多线程问题

(1)、synchronized和lock的区别:
synchronized是一个关键字,lock是一个类 ,lock比synchronized更加灵活。如果使用synchronized关键字,则不需要用户去手动释放锁,方法或者代码执行完毕后系统会让线程自己释放锁。Lock则必须需要用户去释放锁,如果没有及时释放锁,就会造成死锁现象。
lock可以让等待的线程中断响应,synchronized却不能。
lock可以知道有没有成功获取到锁。
lock可以提高多个线程的操作效率。
(2)、synchronized的使用方法和原理 synchronized可以修饰普通的方法,修饰静态方法和代码块 实现原理:每个对象都有一个监视器,当monitor被占用时就会处于锁定状态。线程执行开始时,如果monitor获取到的值为0,则进入到该monitor,即该线程为monitor的所有者,如果检测到其他线程占用monitor则会阻塞,等待monitor的进入数为0,再尝试获取monitor的所有权。

java的集合类:

1、ArrayList和LinkedList的区别:
ArrayList是基于动态数组的数据结构,LinkedList是基于链表的数据结构 对于随机的get和set操作,ArrayList要优于LinkedList,因为LinkedList要移动指针 对于删除和新增来说,LinkedList要优于ArrayList。

2、hashset和hashmap的区别 (1)HashSet是set的一个实现类,hashMap是Map的一个实现类,同时hashMap是hashTable的替代品(为什么后面会讲到). (2)HashSet以对象作为元素,而HashMap以(key-value)的一组对象作为元素,且HashSet拒绝接受重复的对象.HashMap可以看作三个视图:key的Set,value的 Collection,Entry的Set。 这里HashSet就是其实就是HashMap的一个视图。 HashSet内部就是使用Hashmap实现的,和Hashmap不同的是它不需要Key和Value两个值。 往hashset中插入对象其实只不过是内部做了
3、hashmap和hashtable的区别
(1)、hashtable继承的是dictonary类,hashmap继承的是map类
(2)、hashtable是线程安全的,hashmap是非线程安全的
(3)、hashtable中不允许有空值。hashmap可以将null作为key,而且只有一个。

spring相关

1、什么是IOC
控制反转,是将原本在程序中手动创建的对象的控制权,交给spring管理。包括构造器注入、注解注入和setter注入。

2、spring框架中五种bean的作用域:

singleton : bean在每个Spring ioc 容器中只有一个实例。 prototype:一个bean的定义可以有多个实例。 request:每次http请求都会创建一个bean,该作用域仅在基于web的Spring ApplicationContext情形下有效。 session:在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。 global-session:在一个全局的HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。

3、AOP:面向切面,是一种编程思想,OOP的延续。将系统中非核心的业务提取出来,进行单独处理。比如事务、日志和安全等。 AOP是面向切面编程,是通过动态代理的方式为程序添加统一功能,集中解决一些公共问题

4、spring的bean的生命周期
(1)、bean定义,在配置文件中用去定义
(2)、bean初始化,有两种方式,一种是通过init-method实现,还有是通过实现org.springframwork.beans.factory.InitializingBean接口
(3)、bean调用 有三种方式调用bean实例
(4)、bean销毁 两种方式,destroy-method实现,还有实现org.springframwork.beans.factory.DisposeableBean接口

hibernate相关

1.什么是延迟加载

延迟加载是真正用到数据的时候才会加载数据,避免一些无谓的性能开销。

springmvc

1、springmvc和struts2的区别 springmvc的入口是一个DispatcherServlet即前端控制器,strut2的入口是一个filter。

数据库 

1.索引是通过B树和变形的B+树实现的。

2、创建索引的注意事项: (1).索引不与表放在同一个表空间内 (2).一个表的索引不要过多 (3).对于大而使用频繁的表,在生产时不要添加索引,因为表的索引会加大删除修改增加的开销。 (4).使用组合条件查询的适合简历组合索引。 (5).查询时不要对索引的列进行处理,如对此列使用函数,否则索引相当于无效。

3.索引的优缺点 优点:索引可以保证每一行数据的唯一性。 可以大大加快数据的检索速度 可以加快表与表之间的链接 在查询的过程中使用优化隐藏器,提高系统性能 缺点:创建索引和维护索引会随着数据量的增加引发更多的消耗 索引会占用物理空间 当表中的数据进行维护时,索引也会维护。

4.mysql优化 在where和 order by涉及的列上加索引 会导致全表扫描: 尽量避免在where的字句中使用 != 或<>操作符,否则会不使用索引对全表进行扫描。 尽量不使用null进行控制判断,可以设置成默认值为0进行查询。 尽量不使用or来链接where条件 in和not in也要少用 在where字句中使用参数也会导致全表扫描

并发的悲观锁和乐观锁

悲观锁(Pessimistic Lock): 每次获取数据的时候,都会担心数据被修改,所以每次获取数据的时候都会进行加锁,确保在自己使用的过程中数据不会被别人修改,使用完成后进行数据解锁。由于数据进行加锁,期间对该数据进行读写的其他线程都会进行等待。

乐观锁(Optimistic Lock): 每次获取数据的时候,都不会担心数据被修改,所以每次获取数据的时候都不会进行加锁,但是在更新数据的时候需要判断该数据是否被别人修改过。如果数据被其他线程修改,则不进行数据更新,如果数据没有被其他线程修改,则进行数据更新。由于数据没有进行加锁,期间该数据可以被其他线程进行读写操作。 写入频繁用悲观锁,读取频繁使用乐观锁。

transient关键字的使用:

1)一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。

2)transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口。

3)被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。

注解的原理:

 注解本质是一个继承了Annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类。而我们通过反射获取注解时,返回的是Java运行时生成的动态代理对象$Proxy1。通过代理对象调用自定义注解(接口)的方法,会最终调用AnnotationInvocationHandler的invoke方法。该方法会从memberValues这个Map中索引出对应的值。而memberValues的来源是Java常量池

java web response和request的区别:

request是客户端向服务器端发送的请求。主要包括了自己浏览器的信息,http变量,保存在cookie中的信息 response是服务器对客户端的相应。主要包括了页面的信息,和cookie。 cookie就是保存在客户端上的一些信息,可以用来验证用户信息,提高用户的相应速度。

tcp黏包拆包

1、发送端给每个数据包添加包首部,首部中应该至少包含数据包的长度,这样接收端在接收到数据后,通过读取包首部的长度字段,便知道每一个数据包的实际长度了。

2、发送端将每个数据包封装为固定长度(不够的可以通过补0填充),这样接收端每次从接收缓冲区中读取固定长度的数据就自然而然的把每个数据包拆分开来。

3、可以在数据包之间设置边界,如添加特殊符号,这样,接收端通过这个边界就可以将不同的数据包拆分开。

1.算法是程序的灵魂,优秀的程序在对海量数据处理时,依然保持高速计算,就需要高效的数据结构算法支撑。2.网上数据结构算法的课程不少,但存在两个问题:1)授课方式单一,大多是照着代码念一遍,数据结构算法本身就比较难理解,对基础好的学员来说,还好一点,对基础不好的学生来说,基本上就是听天书了2)说是讲数据结构算法,但大多是挂羊头卖狗肉,算法讲的很少。 本课程针对上述问题,有针对性的进行了升级 3)授课方式采用图解+算法游戏的方式,让课程生动有趣好理解 4)系统全面的讲解了数据结构算法, 除常用数据结构算法外,还包括程序员常用10大算法:二分查找算法(非递归)、分治算法、动态规划算法、KMP算法、贪心算法、普里姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法、马踏棋盘算法。可以解决面试遇到的最短路径、最小生成树、最小连通图、动态规划等问题及衍生出的面试题,让你秒杀其他面试小伙伴3.如果你不想永远都是代码工人,就需要花时间来研究下数据结构算法。教程内容:本教程是使用Java来讲解数据结构算法,考虑到数据结构算法较难,授课采用图解加算法游戏的方式。内容包括: 稀疏数组、单向队列、环形队列、单向链表、双向链表、环形链表、约瑟夫问题、栈、前缀、中缀、后缀表达式、中缀表达式转换为后缀表达式、递归与回溯、迷宫问题、八皇后问题、算法的时间复杂度、冒泡排序、选择排序、插入排序、快速排序、归并排序、希尔排序、基数排序(桶排序)、堆排序、排序速度分析、二分查找、插值查找、斐波那契查找、散列、哈希表、二叉树、二叉树与数组转换、二叉排序树(BST)、AVL树、线索二叉树、赫夫曼树、赫夫曼编码、多路查找树(B树B+树B*树)、图、图的DFS算法BFS、程序员常用10大算法、二分查找算法(非递归)、分治算法、动态规划算法、KMP算法、贪心算法、普里姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法马踏棋盘算法。学习目标:通过学习,学员能掌握主流数据结构算法的实现机制,开阔编程思路,提高优化程序的能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值