(标黑粗体为重点)
1.get和post的请求方式的区别?
NO.1、url可见性:
get,参数url可见;
post,url参数不可见
NO.2、数据传输上:
get,通过拼接url进行传递参数;
post,通过body体传输参数
NO.3、缓存性:
get请求是可以缓存的
post请求不可以缓存
NO.4、后退页面的反应:
get请求页面后退时,不产生影响
post请求页面后退时,会重新提交请求
NO.5、传输数据的大小:
get一般传输数据大小不超过2k-4k(根据浏览器不同,限制不一样,但相差不大)
而post请求传输数据的大小根据php.ini 配置文件设定,也可以无限大。
NO.6、安全性:
这个也是最不好分析的,原则上post肯定要比get安全,毕竟传输参数时url不可见,但也挡不住部分人闲的没事在那抓包玩。安全性个人觉得是没多大区别的,防君子不防小人就是这个道理。对传递的参数进行加密,其实都一样。
2.多线程:
NO.1 创建线程有几种方式?(重点)
1. 继承Thread类,可以直接调用Thread类的方法,使用方便,但是不能再继承别的类,可扩展性较差。
2. 实现Runable接口,不能直接调用Thread类的方法,但是还可以继承其他类,可扩展性较强;而且Runable接口是多线程的最高父类接口,主要是用来封装任务的,Thread类也是通过实现Runable接口来实现的。
3. 实现Callable接口,同上。
4. 还可以通过线程池创建。
NO.2 继承Thread类和实现Runable接口方式区别?(常问)
1、java是单继承,继承Thread后不能继承别的类,有局限性,但是java可以多实现,通过实现Runabel接口后还可以实现别的接口,可以**间接实现多继承
2.Runable接口是多线程中的上帝,主要就是用来封装任务,Thread类也是通过实现它而来;
3、使用Runable接口可以很方便对共享资源进行传入;
NO.3 线程状态有几种?(常问,一般答出几种状态即可)
1.新建(new):新建了一个线程,但是还没有调用开启线程的start()方法;
2.可运行(runable):调用了开启线程的start()方法,但是还没有获得到CPU的执行权,处于等待获取执行权状态;
3. 运行(running):已经获得到了CPU执行权,并处于正常执行状态;
4.死亡(dead):线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。
5. 阻塞(blocked):这种状态是指处于运行状态时因为某种原因放弃了使用CPU执行权,暂时停止了运行,需要后续某些 *** 作后方可再次进入可运行状态,进而才有机会再次转到运行状态,一般阻塞情况分三种(了解即可):
(一).等待阻塞 :运行(running)的线程执行o.wait()方法,JVM会把该线程放入等待队列(waitting queue)中,当别的线程执行了notify或者notifyAll后可对其进行唤醒进入锁池,让该线程处于抢锁状态,进而有机会重新转入可运行(runnable)状态。
(二). 同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。
(三). 其他阻塞:运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。
当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。
NO.4 多线程中的 run()和 start()区别 ?
run()方法它其实只是一个封装任务的普通方法,调用run()并不会开启线程,start()方法会开启线程,底层会调用run()方法。
NO.5 wait()与 sleep()的区别?(了解)
1、调用对象不同:wait()、notify()、notifyAll()等都是 Object 上的方法,任何对象都可以作为锁对象进行调用;sleep()、join()、yield()、interrupted()等都是属于Thread类的静态方法;
2、是否释放锁:sleep()方法不会释放锁,只让出了CPU执行权,但是wait()会释放锁,而且会加入到等待队列中。
3、使用位置:sleep()方法可以在任何地方使用;wait()方法则只能在synchronized同步方法或同步块中使用;
4、重运行机制:sleep()过了指定睡眠时间从阻塞状态自动回到可运行状态,wait()方法需要手动调用notify()或者notifyAll()方法手动进行唤醒,然后进入锁池等待。
NO.6 什么情况下需要进行线程同步?
多个线程 *** 作共享资源,会造成共享资源安全问题场景下。
3、多线程锁相关:(常问)NO.1 Sychronized是公平锁还是非公平锁?(常问)
非公平!
NO.2 Synchronized 1.6之后做了哪些优化?
自适应的CAS自旋、锁消除、锁粗化、偏向锁、轻量级锁
NO.3 锁有哪些用法?锁对象分别是什么?(常问)
1、同步代码块:锁对象为括号中的对象
2、同步方法:锁对象为当前对象 this
3、静态同步方法:锁对象为class字节码文件对象
NO.4 什么是AQS? 什么是CAS?
AQS:
java.util.concurrent.locks.AbstractQueuedSynchronizer 抽象类,简称 AQS ,是一个用于构建锁和同步容器的队列同步器,它是整个JUC包下Lock体系的核心,如ReentrantLock、ReentrantReadWriteLock、CountDownLatch、Semaphore都是基于它来实现的,它 解决了在实现同步容器时设计的大量细节问题,它的核心构成部分为:使用一个 先进先出的FIFO 的队列存储排队等待锁的线程,使用一个用volatile修饰的int类型的state同步状态来记录当前是否有线程持有锁**,0表示没有线程获得锁,1表示有,上锁state就加1,释放锁就对应减1,有重入锁现象,这个值就大于1,然后需要逐级去释放。
CAS:(常问)
CAS其实就是乐观锁的一种实现方式,而悲观锁比较典型的就是Java中的synchronized。
CAS全称compare and swap—就是 "比较并替换",保证对数据更改的原子性,它是并发条件下修改数据的一种机制,然后它还有三个 *** 作数:
> 需要修改的数据的内存地址(V);
> 对这个数据的旧预期值(A);
> 需要将它修改为的值(B);
CAS的 *** 作步骤如下:
1、修改前记录数据的内存地址V;
2、读取数据的当前的值,记录为A;
3、需要修改值时查看地址V下的值是否仍然为A,若为A,则用B替换它;若地址V下的值不为A,表示在自己修改的过程中,其他的线程对数据进行了修改,则不更新变量的值,而是重新从步骤2开始执行,这被称为自旋;
总结:CAS 就是贯穿于整个AQS体系,是AQS实现的基础。
4. 框架系列:
1. 独立运行 Spring 项目Spring Boot 可以以 jar 包形式独立运行,运行一个 Spring Boot 项目只需要通过 java -jar xx.jar 来运行。
2. 内嵌 Servlet 容器
Spring Boot 可以选择内嵌 Tomcat、Jetty 或者 Undertow,这样我们无须以 war 包形式部署项目。
第 2 点是对第 1 点的补充,因为在 Spring Boot 未出来的时候,大多数 Web 项目,是打包成 war 包,部署到 Tomcat、Jetty 等容器。
3. 提供 Starter 简化 Maven 配置Spring 提供了一系列的 starter pom 来简化 Maven 的依赖加载。
4. 自动配置 Spring Bean:Spring Boot 检测到特定类的存在,就会针对这个应用做一定的配置,进行自动配置 Bean ,这样会极大地减少我们要使用的配置。
5. 无代码生成和 XML 配置**:Spring Boot 没有引入任何形式的代码生成,它是使用的 Spring 4.0 的条件 @Condition 注解以实现根据条件进行配置。
NO.2 Spring Boot 和 Spring MVC 和 Spring 有什么区别?Spring 的完整名字,是 Spring framework 。它提供了多个模块,Spring IoC、Spring AOP、Spring MVC 等等。所以,Spring MVC 是 Spring framework
众多模块中的一个。而 Spring Boot 是构造在 Spring framework(Spring) 之上的 Boot 启动器,旨在更容易的配置一个 Spring 项目。
NO.3 什么是SpringCloud?
首先SpringCloud是一款微服务框架 可以说是目前微服务架构的最好的选择,涵盖了基本我们需要的所有组件,所以也被称为全家桶, Spring Cloud 是构建在 Spring Boot 基础之上,用于快速构建分布式系统的通用模式的工具集。或者说,换成大家更为熟知的,用于构建微服务的技术栈。
NO.4 Spring Cloud 主要提供了哪些功能?(如果英文太长,记住中文名字即可)
-
Distributed/versioned configuration 分布式/版本化的配置管理
-
Service registration and discovery 服务注册与服务发现
-
Routing 路由
-
Service-to-service calls 端到端的调用
-
Load balancing 负载均衡
-
Circuit Breakers 断路器
-
Global locks 全局锁
-
Leadership election and cluster state 选举与集群状态管理
-
Distributed messaging 分布式消息
Spring Cloud的 组件相当繁杂,拥有诸多子项目。如下脑图所示:
我们最为熟知的,就是 Spring Cloud Netflix ,它是 Netflix 公司基于它们自己的 Eureka、Hystrix、Zuul、Ribbon 等组件,构建的一个 Spring Cloud 实现技术栈。
虽然Spring Cloud的组件很多,但是开发中常用的五大组件还是要记住:
SpringCloud常用的五大组件(重点):
作用:实现服务治理(服务注册与发现)
简介:Spring Cloud Eureka是Spring Cloud Netflix项目下的服务治理模块。
由两个组件组成:Eureka服务端和Eureka客户端。
Eureka服务端用作服务注册中心。支持集群部署。
Eureka客户端是一个java客户端,用来处理服务注册与发现。
在应用启动时,Eureka客户端向服务端注册自己的服务信息,同时将服务端的服务信息缓存到本地。客户端会和服务端周期性的进行心跳交互,以更新服务租约和服务信息。
作用:断路器,保护系统,控制故障范围。
简介:为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的原因,服务并不能保证100%可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。
作用:api网关,路由,负载均衡等多种作用
类似nginx,反向代理的功能,不过netflix自己增加了一些配合其他组件的特性。
在微服务架构中,后端服务往往不直接开放给调用端,而是通过一个API网关根据请求的url,路由到相应的服务。当添加API网关后,在第三方调用端和服务提供方之间就创建了一面墙,这面墙直接与调用方通信进行权限控制,后将请求均衡分发给后台服务端。
spring-cloud-loadbalancerSpring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。spring-cloud-loadbalancer
作用:服务调用
简介:Feign是一个声明式WebService客户端。使用Feign能让编写Web Service客户端更加简单,它的使用方法就是定义一个接口,然后在上面添加注解,同时也支持JAX-RS标准的注解。Feign也支持可插拔式的编码器和解码器。SpringCloud对Feign进行了封装,使其支持了Spring MVC标准注解和HttpMessageConverters。Feign可以与Eureka和Ribbon组合使用以支持负载均衡。
-
Spring Boot 专注于快速方便的开发单个个体微服务。
-
Spring Cloud 是关注全局的微服务协调整理治理框架以及一整套的落地解决方案,它将 Spring Boot 开发的一个个单体微服务整合并管理起来,为各个微服务之间提供:配置管理,服务发现,断路器,路由,微代理,事件总线等的集成服务。
-
Spring Boot 可以离开 Spring Cloud 独立使用,但是 Spring Cloud 离不开 Spring Boot ,属于依赖的关系。
总结:
-
Spring Boot 专注于快速,方便的开发单个微服务个体。
-
Spring Cloud 关注全局的服务治理框架。
5.数据库(MySQL) :
NO.1什么是索引(Index)?
本质上是帮助MySQL高效获取数据的数据结构,MySql中主要应用的索引数据结构为B+Tree。
NO.2 索引结构类型有哪些?
Mysql存储引擎主要有MySIAM、InnoDB。而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等
NO.3 存储数据结构?
MySIAM、InnoDB两种存储引擎都是基于B+树数据结构存储表数据的。不同之处是:
MySIAM的B+树只存储了索引key值地址,真正的数据存储在别的地方
InnoDB 存储引擎中的B+树既存储了索引也存储了数据
NO.4 什么是聚集索引、非聚集索引?
1.聚集索引:
又叫主键索引,是指数据库表行中数据的物理存储顺序与数据的逻辑顺序相同,一张表中只允许存在一个聚集索引,对于mysql来说一般就是主键,若无主键则为表中第一个非空的唯一索引,还是没有,就采用InnoDB存储引擎为每行数据内置的ROWID 作为聚集索引 ;
(扩展部分:)聚集索引就是按照每张表的主键构造一颗B+树,同时叶子节点中存放的即为整张表的记录数据。
聚集索引的叶子节点称为数据页,聚集索引的这个特性决定了索引组织表中的数据也是索引的一部分。
2.非聚集索引:
又叫辅助索引、二级索引。是指除了聚集索引外的其他索引,该索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同,一个表中可以拥有多个非聚集索引。数据的逻辑顺序可能相邻,但是数据的实际存储物理地址可能相差十万八千里 ;非聚集索引的叶子节点存储主键
3.覆盖索引(了解):
这个概念就是指select的数据列只用从索引中就能够取得,不必从聚集索引中的叶子结点数据项中读取,换句话说查询列要被所使用的索引覆盖。 索引是高效找到行的一 个方法,当能通过检索 索引就可以读取想要的数据,那就不需要再到数据表中读取行了。如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫做覆盖索引。在mysql中只能使用BTree索引做覆盖索引、Hash索引不行 如果实现了覆盖索引,在explain的Extra列可以看到“Using index”的信息
NO.5 mysql优化:1.优化SQL语句层面(理解透彻):
1、 尽量避免使用select *;
2、规范sql语句大小写,sql是有缓存的,避免每次都需要解析;
3、使用exsits代替in,要更高效;
4、mysql sql解析执行过程从右至左,基于这个规则,from后面能过滤掉更多数据的基础表放后面,where后面能过滤掉更多数据的查询条件放后面;
5、查询条件中用相同类型去查询,比如避免数值列用字符串查询条件;
6、合理使用索引(
1、为合适的列添加索引(主键、唯一索引、组合索引);
2、尽量建立联合索引,也省空间成本;
3、尽量使用覆盖索引;
3、避免以下会使索引失效的 *** 作(了解大概即可):
(1)、索引列有null值不走索引
(2)、使用is null或is not null不走索引
(3)、各种负向查询not ,not in, not like ,<> ,!= ,!> ,!< 不会使用索引
(4)、like将%放左边不走索引
(5)、查询条件的数据类型做了隐式转换
(6)、使用in或union代替or,or两侧有非索引列就不会走索引
(7)、尽量保持索引列干净,不在索引列上使用函数转换、运算
(8)、联合索引要遵循最左匹配原则,如建立联合索引(A,B,C),查询顺序如下:
ABC会走索引,AB会走索引,A也会走索引,但是不能断开 如AC|CA|BC|CB|B|C都不会走索引
(9)、使用比较运算或between会使联合索引从使用比较运算的下一个索引处断开
)
2. 优化架构方面(了解)
在数据达到一定量级以后,需要对数据库从主从、分库分表数据分片方面进行优化:
1.读写分离:主节点写,从节点读
2.分库:根据业务或者其他维度把数据存放到不同数据库
3.分表:1、水平分表:字段都一样,分多张表存放不同时间范围或不同维度的数据,如实时数据表、历史数据表。 2.垂直分表:将不同字段放在多张表,使用外键关联。
NO.6 mysql事务(理解透彻)1.事务有哪些特性?
原子性:事务中所有 *** 作要么全部提交成功,要么全部失败回滚,不能出现一部分失败,一部分成功的现象;
一致性:指在事务的执行前后保持数据库的一致性;
隔离性:一个事务所做的修改在最终提交之前,对其他事务是不可见的;
永久性:一旦事务提交,它所做的修改将会永久保存到数据库中,及时系统发生崩溃,事务执行结果也不会丢失;
2. 哪几种事务隔离级别,会出现的问题?
否
3. 什么是脏读、不可重复读、幻读 ?
-
脏读:一个事物读到了另一个事务尚未提交的数据,不符合事务的隔离性。
-
不可重复读:同一个事务中针对同一行记录两次读出来的结果不一样,原因就是第二次读到了其他事务修改提交的数据。
幻读:同一个事务中针对同一范围内的数据两次读出来的结果不一样,原因就是第二次读到了其他事务新增提交 的数据。
4.char和vachar区别 ?
char列长度固定,为创建表时声明的长度,长度值范围是1到255,当char值未填满指定长度时,其他空间会用空格进行填充,检索CHAR值时需删除尾随空格
vachar长度为可变的,实际使用多少空间就占多少空间
6. Redis相关 NO. 1 支持哪几种数据类型 ?1. 支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
NO.2 为什么读写速度很快 ?(也可以作为优点方面来答)1. redis完全基于内存
2. 数据结构简单
3. 采用单线程,避免了加锁、释放锁、死锁、线程间切换等消耗
4. 使用多路I/O复用模型,非阻塞IO
NO.3 在你们项目有哪些应用场景 ?
计数器**:对 string 进行自增自减运算,从而实现计数器功能。redis 内存型数据库的读写性能非常高,很适合存储频繁读写的计数量。如每日登录次数计数。
热点数据缓存:将热点数据放到内存中。如首页排行榜数据,具有很大访问频次,使用zset可以实现基于score分数排序;。
会话缓存:用redis统一存储多台应用服务器的会话信息。当应用服务器不再存储用户的会话信息,也就不再具有状态,一个用户可以请求任意一个应用服务器,从而更容易实现高可用性以及可伸缩性。
取数据交集、并集:基于redis set 的特性可以对共同好友进行很方便的查询。
分布式事务锁的使用:基于set lock requestId nx ex time 模式可以很方便编写分布式事务锁
NO.4 Redis是基于什么协议的?1. Redis 的通信协议是 Redis Serialization Protocol,翻译为 Redis 序列化协议,简称 RESP
-
在 TCP 层
-
是二进制安全的
-
基于请求 - 响应模式
-
简单、易懂
第一种:RDB,即 Redis 的内存快照,默认持久化机制,它是在某一个时间点将 Redis 的内存数据全量写入一个临时文件,当写入完成后,用该临时文件替换上一次持久化生成的文件,这样就完成了一次持久化过程,默认的文件名为dump.rdb。
NO.6 Redis的缓存穿透,缓存击穿,缓存雪崩,以及对应的解决方案 ?(这里初中级应该问不到,大家了解即可):1.缓存穿透:是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。
缓存穿透解决方案:(1.接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;
2. 从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击啦;
3. 引入布隆过滤器,过滤一些异常的请求!)
2. 缓存击穿:这个是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。
缓存击穿解决方案:(
1、设置热点数据不过期;
2、第一时间去数据库获取数据填充到redis中,但是这个过程需要加锁,防止所有线程都去读取数据库,一旦有一个线程去数据库获取数据了,其他线程取锁失败后可设置一个合理睡眠时间之后再去尝试去redis中获取数据;)
3. 缓存雪崩:缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同的是,缓存击穿指并发查同一条数据,缓存雪崩是大批量数据都过期了,大量数据都从redis中查不到,从而查数据库。
解决方案:(
1、缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
2、如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中。
3、允许的话,设置热点数据永远不过期。
4、要保证redis的高可用,可以使用主从+哨兵或redis cluster,避免服务器不可用;
5、使用redis的持久化RDB+AOF组合策略,防止缓存丢失并且可以快速恢复数据;
)
本文章就写到这里了,祝大家早日找到高新任职,在工作的同志就祝你们步步高升!完结撒花!看在一万字的面子上,姥爷们给个赞行不行~
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)