1、项目中,有遇到过哪些比较大的问题,怎么解决的?
腾杰项目问题:
1、页面假死情况,因为刚接触不久,对线程,api都不太了解;假死的原因也就当执行了一个非常耗时的事件,页面呈现无法响应的情况;解决的方案就是:
1、Application.DoEvents() 做到实时刷新显示效果,但这样会影响效率;
2、开启一个线程,但必须要及时释放资源;
2、显示图片问题,如果使用自带的picturebox的话,,放大缩小都会影响效果;造成图片的显示不全,和裁剪出错;后来百度一下,发现了.Net 3.0提出了一个 wpf的东西,基于windows窗口的用户界面框架,然后一步一步的按照教程来显示图片,显示多张图片,放大缩小都正常了;这算是很大的突破吧;因为之前也没接触过这些;
3、定时事件里面,捕获异常时,catch里面加上了弹框;这是我粗心大意的结果;导致程序出错了,就无法继续使用了;后来紧急修复了;
个人项目问题:
1、 分页问题:如果不使用分页,当查询很多数据时,会造成数据查询很慢,刷新速率较低;
解决方法:
1、SQL查询使用Limit,我的项目中就是使用这种方法;但是当limit a,b 跨度太大,效率会很低;
2、使用插件PageHelper,具体操作暂且没使用过;
2、Vue 数据渲染完成之前变量显示{};
解决方法:
1、在需要锁住的标签上使用v-cloak
2、Spring IOC中的单例模式
单例模式是指
确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点。
J2EE中的ServletContext,ServletContextConfig等;Spring中的ApplicationContext、数据库连接池等。
饿汉式单例模式
饿汉式单例模式在类加载的时候就立即初始化,并且创建单例对象。它是绝对的线程安全、在线程还没出现以前就实现了,不可能存在访问安全问题。
优点:没有增加任何锁,执行效率高,用户体验比懒汉式好。
缺点:类加载的时候就初始化了,用不用都进行,浪费内存。
Spring 中IoC容器ApplocationContext本身就是典型的饿汉式单例模式
懒汉式单例模式
被外部调用才会加载,会产生不同的实例
3、Linux常用命令
进程 ps
pwd :显示工作路径
ls :查看目录中文件
mkdir 创建目录
cp复制 rm删除 find搜索
cd yum unzip rz
4、Spring AOP IOC
AOP:
可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术
主要的功能是:日志记录,性能统计,安全控制,事务处理,异常处理等等,解决代码复用。
关注点
关注点,重复代码就叫做关注点;
切面
关注点形成的类,就叫切面(类)!
面向切面编程,就是指 对很多功能都有的重复的代码抽取,再在运行的时候往业务方法上动态植入“切面类代码”。
切入点
执行目标对象方法,动态植入切面代码。
可以通过切入点表达式,指定拦截哪些类的哪些方法; 给指定的类在运行的时候植入切面类代码。
IOC:
控制反转,有时候也被称为DI依赖注入,它是一种降低对象耦合关系的一种设计思想。
它并不是一种技术实现,而是一种设计思想。在任何一个项目中,会使用很多类来描述它们特有的功能,并且通过类与类之间的相互协作来完成特定的业务逻辑。这个时候,每个类都需要负责管理与自己有交互的类的引用和依赖,代码将会变的异常难以维护和极度的高耦合。而IOC的出现正是用来解决这个问题,我们通过IOC将这些相互依赖对象的创建、协调工作交给Spring容器去处理,每个对象只需要关注其自身的业务逻辑关系就可以了。在这样的角度上来看,获得依赖的对象的方式,进行了反转,变成了由spring容器控制对象如何获取外部资源(包括其他对象和文件资料等等)。
5、Redis 数据?
- 高频数据
- 数据变化频率不高
- 非敏感数据
高频被用户使用的数据;因为redis是基于内存的,而内存是有限的,会造成内存使用太多,影响系统性能;
策略:
给每个数据行加上点击量,根据点击量来是否需要redis缓存;
Redis官方提供了两种持久化方式:RDB和AOF。
RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照。
AOF 持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。
6、项目是干嘛的,怎么实现的?
客户端 社区系统 android 便签
7、Spring IOC 实际用例
在项目中,用的是spring boot 我是以注解形式来实现ioc的;
首先就是注册bean;将类方法的返回值加载到ioc容器当中,其中里面的字符串代表注入容器Bean的名字。不写默认是方法名称;
还有一种方式是使用Component;spring boot会在启动时扫描组件,然后加到容器中管理;
使用的时候,就
@Autoward 就行;
用过的,redisTemplate配置;spring boot 都会提供各种xxxtemplate;只需要类上加上Configution就代表这是个配置类;相当于spring xml配置;然后注册bean;使用的时候就Autoward;
8、Spring AOP实现原理
spring boot拦截器就是一个aop实现的例子;
servlet
1、添加spring aop支持和AspectJ依赖
2、启用对@AspectJ的支持
3、声明切面
4、声明切入点
5、声明通知 通知分为前置、后置、异常、最终、环绕通知五类
9、TCP协议
三次握手:
1、客户端发送一个序列号的数据段给服务端,代表,我要连接你了,你要拿什么序列号的数据段回应我;
2、服务端收到消息,将一个序列号的数据段和确认标志发送给客户端,代表,我已收到请求,你可以发数据,并且以哪个序列号数据段来给我;
3、客户端收到数据段,再次发送确认标志,代表我收到你的回复了,我要传输数据了。
四次挥手:
- 当主机A完成数据传输后,将控制位FIN置1,提出停止TCP连接的请求。
- 主机B收到FIN后对其作出响应,确认这一方向上的TCP连接将关闭,将ACK置1。
- 由B 端再提出反方向的关闭请求,将FIN置1。
- 主机A对主机B的请求进行确认,将ACK置1,双方向的关闭结束。
TCP:面向连接的,可靠的字节流服务;传输之前,先要确定TCP连接,确认后才能开始传输,并且可以超时重新发送,检验重复数据检验数据,流量控制,保证一端向另一端进行安全传输;
UDP:简单的面向数据报的运输层协议;不提供可靠性;不能保证数据是否到达了目的地,由于没有连接确认机制,和超时重发,所以传输速度很快;
简要:
不同:报头不同,协议不同,特点不同;
UDP 8个字节报头;TCP 20字节报头
10、GC回收机制
JVM内存空间包含:方法区、java堆、java栈、本地方法栈,程序计数器。
方法区是各个线程共享的区域,存放类信息、常量、静态变量。
JVM中程序计数器、虚拟机栈、本地方法栈3个区域随线程而生随线程而灭。
栈帧随着方法的进入和退出做入栈和出栈操作,实现了自动的内存清理。它们的内存分配和回收都具有确定性。
因此,GC垃圾回收主要集中在堆和方法区,在程序运行期间,这部分内存的分配和使用都是动态的。
如何判断对象存活
判断对象常规有两种方法:引用计数算法和可达性分析算法
引用计数算法:给对象添加一个引用计数器,每当有一个地方引用它时计数器加1,引用释放时计数减1,当计数器为0时可以回收。
可达性分析算法:基本思想是通过一系列称为“GC Root”的对象(如系统类加载器、栈中的对象、处于激活状态的线程等)作为起点,基于对象引用关系,开始向下搜索,所走过的路径称为引用链,当一个对象到GC Root没有任何引用链相连,证明对象是不可用的。
在Java中,可作为GC Root的对象包括以下几种:
- 虚拟机栈(栈帧中的本地变量表)中引用的对象
- 方法区中类静态属性引用的对象
- 方法区中常量引用的对象
- 本地方法栈中JNI(即一般说的Native方法)引用的对象
回收算法:
标记清除算法 / 复制算法 / 标记整理算法 / 分代收集算法
标记 : 首先标记出所有需要回收的对象,在标记完成后统一回收掉所有被标记的对象。
复制算法: 将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当一块内存用完了,就将还存活着的对象复制到另外一块上,然后清理掉前一块。
标记整理: 标记过程与“标记-清除”算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。
分代收集算法,基本思路:将Java的堆内存逻辑上分成两块,新生代和老年代,针对不同存活周期、不同大小的对象采取不同的垃圾回收策略。
而在新生代中大多数对象都是瞬间对象,只有少量对象存活,复制较少对象即可完成清理,因此采用复制算法。而针对老年代中的对象,存活率较高,又没有额外的担保内存,因此采用标记整理算法。
11、如何查询教师的课程
设计表:教师表,课程表,中间表
查询表:
SELECT course.courseName FROM teachercourse
LEFT JOIN course on teachercourse.courseid=course.ID
where teachercourse.teacherid=(select ID from teacher where NAME='李永琪')
12、线程
生命周期:创建----------就绪----------运行------------阻塞--------------死亡销毁
四种创建线程:1、继承Thread;2、实现Runnable接口;3、实现Callable接口;4、线程池;
Sleep和Wait:
Sleep定义在Thread上,Wait定义在Object上;
Sleep不会释放锁;Wait会释放锁;
Sleep能在任意段执行;Wait在同步代码中;
线程安全的理解:
当多个线程访问一个对象时,如果不用进行额外的同步控制或者额外的协调;调用这个对象的行为都可以获得正确的结果,就称这个对象是线程安全的;
13、异常
Throwable------------>Exception/Error
Exception--------------> RunntimeException/非运行时异常
Throw 作用于方法内,抛出异常;
Throws 作用于方法声明,声明该方法有可能抛出异常
14、类加载机制
1、核心类---bootstrapclassLoader
2、扩展类---extclassloader
3、项目中的类---appclassloader
双亲委托,父类拥有的类,子类好像没有用;
15、servlet-----Java+html
生命周期:创建--初始化--service--doxxx--销毁
称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容。
16、jsp------Html+java
动态网页技术
JSP将Java代码和特定变动内容嵌入到静态的页面中,实现以静态页面为模板,动态生成其中的部分内容。
17、防SQL注入
采用预处理对象
jdbc使用:prepardStatement而不是用Statement
mybatis: 用# 号不用 ¥;
18、事务的特点
ACID
原子性:要么成功,要么失败全部;
隔离性:并发,事务之间相互隔离,互不干扰
一致性:100块钱,转账之后总额还是100;
持久性:事务一旦提交,便是永久,就算迭机也可以通过事务日志完成持久化;还可以通过日志进行数据修复;
19、三层架构
- Web交互层:Controller spring mvc
- 业务逻辑层:Service spring
- 数据访问层:Interface mybatis
20、序列化
把对象写入数据库或者磁盘中;
怎么写入文件:
1、序列化
2、ObjectOutputStream
序列化ID的作用:
会根据这个类对象的结构生成一个序列化版本号ID
反序列化的时候 会比较磁盘上的序列化版本号ID是否和这个对象序列化版本号ID一致
一致则反序列化成功,反之,不成功
= = = = = = = = = = = = = = = = = = = = = = = =
1、锁
什么是锁:
将某种资源私有化的物品;Java里面的锁也有这种特性;他可以让某个方法,某个变量或者某个通道在某个时刻下只能被一个线程占用;只有当这个锁被释放了,另外的线程才能使用;
临界区:
多线程访问共享资源;防止出现数据不一致情况;引入了临界区;临界区是一个用来访问共享资源的代码块,同一时间只能一个线程进行访问;
有几种锁?
synchronized 非公平锁 :效率比较低,不够灵活,不可中断,无法感知获取锁
ReentrantLock 重入锁(公平,非公平锁):效率较高,灵活,可感知获取锁,可公平可非公平,可中断
ReadWriteLock 非公平锁 :读写分离控制(读多写少),读读并行,读写串行,写写串行
什么是死锁:
死锁是指两个或者两个以上进程在执行过程中;由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力的作用下;他们都无法推进下去;此时称系统状态处于死锁状态;这些永远相互等待的进程称为死锁进程;
死锁的原因:
- 系统资源不足;
- 程序执行顺序有问题;
- 程序资源分配不当;
死锁的四个必要条件:
- 互斥条件;一个资源只能被一个进程使用;
- 请求与保持条件;一个进程因请求资源而阻塞时,对已获得的资源保持不放;
- 不剥夺条件;进程已获得的资源,在未使用完之前,不能强行剥夺;
- 循环等待条件;若干进程之间形成一条头尾相接的循环等待资源关系;
如何解决死锁:
了解了死锁的四个必然条件,就可以最大化的避免、预防、解除死锁。
在系统设计,进程调度等方面注意如何不让这四个条件成立,如何确定资源的合理分配算法,避免进程永久占据系统资源;也要防止进程处于等待状态的情况下占用资源。因此,需要对资源进行合理的分配;
数据库死锁
数据库要修改一条数据时,会给他加上锁,保证数据的一致性;
而死锁发生在多个进程访问同一数据库时,其中每个进程所用的锁是其它进程所需的,由此造成每个进程无法继续下去;
简单地说就是:进程A等待进程B释放她的锁;进程B等待进程A释放她的锁;相互等待,就形成了死锁;
降低死锁:
- 同一顺序访问对象;
- 避免事务中用户交互;
- 保持事务简短并在一个批处理中;
- 使用低隔离级别;
- 使用绑定连接;
2、进程通信
3、网络模型
4、TCP
在TCP的连接中,数据流必须以正确的顺序送达对方。TCP的可靠性是通过顺序编号和确认(ACK)来实现的。
TCP在开始传送一个段时,为准备重传而首先将该段插入到发送队列之中,同时启动时钟。
其后,如果收到了接受端对该段的ACK信息,就将该段从队列中删去。如果在时钟规定的时间内,ACK未返回,那么就从发送队列中再次送出这个段。
TCP在协议中就对数据可靠传输做了保障,握手与断开都需要通讯双方确认,数据传输也需要双方确认成功,
在协议中还规定了:分包、重组、重传等规则;而UDP主要是面向不可靠连接的,不能保证数据正确到达目的地。
评论区