面试题(杭州)

文章目录

杭州马面试题

1.常见的集合有哪些?都有什么区别:

List集合:
ArrayList:数组结构,线程不安全,执行查询效率块,增删改慢
LinkList:链表结构,对元素执行增删改效率高
Set集合:
HashSet:要保证元素唯一性,需要覆盖掉Object中的equals和hashCode方法
(因为底层是通过这两个方法来判断两个元素是否是同一个)
TreeSet:以二叉树的结构对元素进行存储,可以对元素进行排序
Map集合:元素是成对出现的,以健值对的方式体现,健保证唯一性
HashMap:线程不安全,允许存放null键null值
HashTable:线程安全,不允许存放null键null值
TreeMap:可以对键进行排序,

2.HashMap的底层原理:

是以数组和链表的形式存储元素

3.sleep和wait的区别

  1. wait来自Object类,sleep来之Thread类
  2. 调用sleep方法,线程不会释放对象锁,而调用wait方法线程会释放对象锁
  3. sleep睡眠后不出让系统资源,wait让其他线程可以占用cup
  4. sleep需要一个指定睡眠时间,时间一到会自动唤醒,而wait需要配合notify方法或者notifyAll方法使用

4.run方法和start方法的区别:

run方法:当前普通方法的方式调用,程序还是顺序执行,还是要等待run方法体执行完毕后才会继续执行下面的代码

start方法:用来启动线程,真正实现了多线程运行,无序等待run方法体执行完毕后才执行下面的代码

5.Threadlocad的作用:

提供线程内部的局部变量,并且这些变量依靠线程独立存在,可以在多个线程中互不干扰的进行存储数据和修改数据,通过set,get和remove方法。每个线程都是独立操作

原理:在不同的线程中访问一个对象,获取的值是不一样的,因为内部会从各个线程取出一个数组,
	  通多对应的下标,查找对应的值

6.solr查询出的数据放在哪:

本地 磁盘中

8.支付宝的支付流程:

先是生成商户系统一笔未支付的订单,获得商户订单ID(商户系统生成)和订单的一些其他信息,然后再调用支付宝的SDK提供的数字签名方法,将需要传给支付宝的信息进行加签,然后把加签后的字符串返回给APP。APP拉起支付宝APP,再把这个加签的字符串传给支付宝,完成支付。APP接收到同步通知后,还需要再次调用商户后台的接口(虽然同步通知也有付款情况,但需要以后台通知为准),校验订单最终的付款情况。按照支付宝API上所说,当完成支付后,支付宝会做2个操作,一个是同步返回信息给APP,一个是异步通知商户后台返回支付状态等信息,并且最终的支付结果是以异步通知为准。所以我们还需要考虑到一点,就是当用户支付成功之后,商户系统暂时没有接收到支付宝的异步通知时。我们需要拿着这个商户订单ID主动调用SDK支付宝的查询接口,去获取该订单的支付情况,并最终返回给APP

当点击支付的时候将一笔未支付的订单信息(包含商家,商品以及用户的信息)给支付宝,当输入支付密码支付宝调用SDK加签再给支付宝,当支付完成后,支付宝会做2个操作,一个是同步返回信息给APP,一个是异步通知商户后台返回支付状态等信息,并且最终的支付结果是以异步通知为准

11线程池工作原理:

先启动若干数量的线程,并让这些线程都处于睡眠状态,当客户端有一个新请求时,就会唤醒线程池中的某一个睡眠线程,让它来处理客户端的这个请求,当处理完这个请求后,线程又处于睡眠状态

22.Hashmap的底层原理?

HashMap底层是通过数组加链表的结构来实现的HashMap 的实例有两个参数影响其性能
:“初始容量” 和 “加载因子”HashMap 根据键的 hashCode 值存储数据,大多数情况
下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序却是不确定的。
HashMap 最多只允许一条记录的键为 null ,允许多条记录的值为 null 。
HashMap 非线程安全,即任一时刻可以有多个线程同时写 HashMap,可能会
导致数据的不一致。如果需要满足线程安全,可以用 Collections的
synchronizedMap 方法使 HashMap 具有线程安全的能力,或者使用ConcurrentHashMap。
在JDK1.8之前,它的底层结构是数组+链表,而在JDK1.8之后,为了查询效率的优化
(主要是当哈希碰撞较多的时候),它的底层结构变成了数组+链表+红黑树

23.有对hashmap初始容量进行修改过吗?修改原理初始容量?

当我们设置了初始化容量,HashMap就会按照我们设置的容量进行设置吗?
答案是不一定。当你设置的初始化容量是2的n次方时,就会按照你设置的容量设置
;当你设置的初始化容量不是2的n次方时,就会按照大于你设置的那个值但是最接近
你设置的那个值的2的n次方进行设置其中size是HashMap中添加键值对的数量,
而threshold是容量加载因子(capacity * load factor)得出的值,
也是就当我们的容量是16,加载因子是0.75时,当键值对的数量大于160.75=12时
,HashMap会进行扩容操作

24.多线程中使用的集合有哪些是线程安全的?

ConcurrentHashMap是Java5中新增加的一个线程安全的Map集合
ConcurrentSkipListSet是线程安全的有序的集合,适用于高并发的场景
LinkedBlockingQueue是一个线程安全的阻塞队列,它实现了BlockingQueue接口
,BlockingQueue接口继承自java.util.Queue接口,并在这个接口的基础上增加了
take和put方法,这两个方法正是队列操作的阻塞版本。
CopyOnWriteArrayList是ArrayList 的一个线程安全的变体,
其中所有可变操作(add、set等等)都是通过对底层数组进行一次新的复制来实现的
Vector和HashTable实现了线程安全的数组和散列表;在java1.2版本中他们就已经不再使用了
,取而代之是ArrayList和HashMap这些集合类不是线程安全但是他们可以通过集合库中提供的
同步包装器使其变成线程安全的;

28.线程的生命周期?

New(初始化状态)
Runnable(可运行/运行状态)
Blocked(阻塞状态)
Waiting(无时间限制的等待状态)
Timed_Waiting(有时间限制的等待状态)
Terminated(终止状态)
1.New(初始化状态):指的是在高级语言,比如Java。在Java层面的线程被创建了,而在操作系统中的
线程其实是还没被创建的,所以这个时候是不可能分配CPU执行这个线程的!所以这个状态是高级语言独
有的,操作系统的线程没这个状态。我们New了一个线程,那时候它就是这个状态。
2.Runnable(可运行/运行状态):这个状态下是可以分配CPU执行的,在New状态时候我们调用start()方法后线程就处于这个状态。
3.Blocked(阻塞状态):这个状态下是不能分配CPU执行的,只有一种情况会导致线程阻塞,就是synchronized
!我们知道被synchronized修饰的方法或者代码块同一时刻只能有一个线程执行,而其他竞争锁的线程就从
Runnable到了Blocked状态!当某个线程竞争到锁了它就变成了Runnable状态。注意并发包中的Lock,是
会让线程属于等待状态而不是阻塞,只有synchronized是阻塞。(感觉是历史遗留问题,没必要多一个阻塞状态和等待没差啊)。
4.Waiting(无时间限制的等待状态):这个状态下也是不能分配CPU执行的。有三种情况会使得Runnable状态到waiting状态
调用无参的Object.wait()方法。等到notifyAll()或者notify()唤醒就会回到Runnable状态。
调用无参的Thread.join()方法。也就是比如你在主线程里面建立了一个线程A,调用A.join(),那么你的主线程是得等A执行完了才会继续执行,这是你的主线程就是等待状态。
调用LockSupport.park()方法。LockSupport是Java6引入的一个工具类Java并发包中的锁都是基于它实现的,再调用LocakSupport.unpark(Thread thread),就会回到Runnable状态。
5.Timed_Waiting(有时间限制的等待状态):其实这个状态和Waiting就是有没有超时时间的差别,这个状态下也是不能分配CPU执行的。有五种情况会使得Runnable状态到waiting状态
Object.wait(long timeout)。
Thread.join(long millis)。
Thread.sleep(long millis)。注意 Thread.sleep(long millis, int nanos) 内部调用的其实也是Thread.sleep(long millis)。
LockSupport.parkNanos(Object blocked,long deadline)。
LockSupport.parkUntil(long deadline)。
6.Terminated(终止状态):在我们的线程正常run结束之后或者run一半异常了就是终止状态!
注意有个方法Thread.stop()是让线程终止的,但是这个方法已经被废弃了,不推荐使用,因为比如你这个线程得到了锁,你stop了之后这个锁也随着没了,其它线程就都拿不到这个锁了!这不玩完了么!所以推荐使用interrupt()方法。
interrupt()会使得线程Waiting和Timed_Waiting状态的线程抛出 interruptedException异常,使得Runnabled状态的线程如果是在I/O操作会抛出其它异常。
如果Runnabled状态的线程没有阻塞在I/O状态的话,那只能主动检测自己是不是被中断了,使用isInterrupted()。

29.说下Ioc Aop 和项目中用到的地方?

ioc,控制反转,这个指的就是我们获取对象的方式进行反转了,改变了。在使用spring之前是需要手
动new出来的,是我们主动获取的。使用spring之后,是将这个获取的过程交给spring来管理,我们只需
要告诉spring你需要什么就行了,它就会把东西给你。比如:在没有电商的时候,我们去上街买东西,需
要考虑到这东西有没有,价钱多少,怎么搬回来,去有多远……等等无数个和主要的业务逻辑(买东西)无
关的问题。这样就会扰乱主业务逻辑。当我们有了电商平台后,买东西时只需要两步。注册账号(装载bean)
,告诉电商你要的东西名字(通过名字获取Bean),然后就可以在门口收到东西了。这就是ioc。
aop,面向切面。在谈这个之前需要了解几个词:切面,切入点,织入,目标对象,通知。
我先解释下名字的意思,再讲故事。
切面:就是你要准备增强的那些方法。
切入点:就是具体织入的方法,定义了地点
织入:动词,就是将切面织入的过层
目标对象:被增强的类
通知:就是什么时候增强,定义了时间
好了,了解清楚上面的几个词的意思后,再听故事就容易多了。
aop的功能就是用来增强,在执行主业务的通知也顺带执行其他业务。如:老李上街办点事儿,走啊走,走到了老王家门前(切入点),老王看见老李问:去哪啊!
老李:上街办点事儿(目标类)
老王:那帮我顺便把这封信投到邮筒里吧。(切面),等到10点的时候邮局开门了去柜台投。(通知)
老李:好嘞。然后老李接过信。(织入)
老李继续走啊走,继续上街办事(增强后的目标类)。办完事后老李回家了。
以上就是aop。aop一般用来处理权限控制,日志记录,加载事务等非主要业务逻辑的事情。底层是采用cglib和jdk的动态代理实现的。

34.项目登录功能实现过程?token怎么生成的?登录是用的框架还是自己直接写的?

获取前端登录的数据(验证码,用户名,密码等),先验证验证码是否正确,再验证用户名和密码(加不加密随意)是否正确,正确与否都要做出提示,然后再设置一个Cookie机制用来保存用户登录的信息,如果勾选了保存密码,就可以对Cookie设置有效期之类的。也可以生成token。 token(分为三部分,header密文,payload密文,签名),将荷载payload,以及Header信息进行Base64加密,形成密文payload密文,header密文,将形成的密文用句号链接起来,用服务端秘钥进行HS256加密,生成签名,将前面的两个密文后面用句号链接签名形成最终的token返回给服务端。 登录用了框架/自己写(视自己的情况说)。

40.Nginx的作用?

一、静态http服务器,Nginx是一个HTTP服务器,可以将服务器上的静态文件(如HTML、图片)通过HTTP协议展现给客户端。二、反向代理服务器,客户端本来可以直接通过HTTP协议访问某网站应用服务器,网站管理员可以在中间加上一个Nginx,客户端请求Nginx,Nginx请求应用服务器,然后将结果返回给客户端。三、负载均衡,Nginx可以通过反向代理来实现负载均衡。四、虚拟主机,有的网站,由于访问量太小,需要节省成本,将多个网站部署在同一台服务器上。
40微服用户信息如何获取?
用dubbox搭建的微服各模块注册信息从zookeeper注册中心获取,用springcloud搭建的微服各模块注册信息从eureka注册中心获取。

41Sprongboot常用注解?

@Service: 注解在类上,表示这是一个业务层bean
@Controller:注解在类上,表示这是一个控制层bean
@Repository: 注解在类上,表示这是一个数据访问层bean
@Component: 注解在类上,表示通用bean ,value不写默认就是类名首字母小写
@Autowired:按类型注入
@Resource: 按名称装配
@Configuration:注解在类上,表示这是一个IOC容器,
@Bean: 注解在方法上,声明当前方法返回一个Bean
@Scope:注解在类上,描述spring容器如何创建Bean实例。
@Value:注解在变量上,从配置文件中读取。
@ConfigurationProperties: 赋值,将注解转换成对象。
@EnableAutoConfiguration启用 Spring 应用程序上下文的自动配置,试图猜测和配置您可能需要的bean。
@SpringBootApplication=@ComponentScan+@Configuration+@EnableAutoConfiguration:约定优于配置
@ComponentScan:注解在类上,扫描标注了@Controller等注解的类,注册为bean 。
@RestController @RestController 是一个结合了 @ResponseBody 和 @Controller 的注解
@Responsebody:表示该方法的返回的结果直接写入 HTTP 响应正文(ResponseBody)中,一般在异步获取数据时使用,通常是在使用 @RequestMapping后,返回值通常解析为跳转路径,加上@Responsebody 后返回结果不会被解析为跳转路径,而是直接写入HTTP 响应正文中。
@PathVariable、@RequestParam:两者的作用都是将request里的参数的值绑定到contorl里的方法参数里的,区别在于,URL写法不同。
@EnablCaching:pring framework中的注解驱动的缓存管理功能。
@suppresswarnings: 抑制警告
@Modifying :增,改,删加注解

44sleep和wait区别 原理不同

sleep是Thread类的静态方法,是线程用来控制自身流程的,它会使此线程暂停执行指定的时间,而把执行机会让给其他的线程,等到计时时间到,此线程会自动苏醒.
wait是Object类的方法,用于线程间的通信,这个方法会使当前拥有该对象锁的进程等待,直到其他线程调用notify方法才醒来,也可以指定时间自己醒来.
 对锁的处理机制不同
由于sleep方法的主要作用是让线程休眠指定一段时间,在时间到时自动恢复,不涉及线程间的通信,因此,调用sleep方法并不会释放掉锁.
但是调用wait方法的时候,线程会释放掉它所占用的锁,从而使线程所在对象中的其他synchronized数据可以被其他线程使用.
 使用的区域不同
由于wait方法的特殊含义,所以它必须放在同步控制方法或者同步语句块中使用,而sleep方法则可以放在任何地方使用.
 异常的捕获
sleep方法必须捕获异常,而wait,notify以及notifyall不需要捕获异常,在sleep的过程中,有可能别其他对象调用其interrupt(),产生InterruptedException异常.
sleep不会释放锁标志,容易导致死锁的发生,所以一般情况下,不推荐使用sleep方法,而是使用wait方法.

52.JDK、JRE、JVM是什么

JDK:Java开发工具包,是整个JAVA开发的核心,包括了JRE,JAVA基本类库和一堆JAVA工具(比如说编译器等等)
JRE:Java运行时环境,包含了JVM和JAVA运行时基本类库
JVM:Java虚拟机,它是Java实现跨平台最核心的部分,所有的java文件被编译成.class文件后,通过JVM进行识别执行

54. IO与NIO的区别

IO是面向流的,NIO是面向缓冲区的:IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方
IO是阻塞的,NIO是不阻塞的:如果在一次读写数据调用时数据还没有准备好,或者目前不可写,那么读写操作就会被阻塞直到数据准备好或目标可写为止。Java NIO则是非阻塞的,每一次数据读写调用都会立即返回,并将目前可读(或可写)的内容写入缓冲区或者从缓冲区中输出,即使当前没有可用数据,调用仍然会立即返回并且不对缓冲区做任何操作。这就好像去超市买东西,如果超市中没有需要的商品或者数量还不够,那么Java IO会一直等直到超市中需要的商品数量足够了就将所有需要的商品带回来,Java NIO则不同,不论超市中有多少需要的商品,它都会立即买下可以买到的所有需要的商品并返回,甚至是没有需要的商品也会立即返回。

55.如何实现多线程

1.继承Thread类,重写run()方法
2.实现Runnable接口并实例化一个线程
3.使用ExecutorService、Callable、Future实现有返回结果的多线程
应用场景: 需要让异步执行的线程在执行完成后返回一个值给当前的线程,当前的线程需要依赖这个值做一些其他的业务操作,这个时候就需要实现有返回结果的多线程

56.如何防止死锁

1.设置加锁顺序
如果一个线程需要锁,那么就需要按照锁的顺序来获得锁
比如说,线程1占据着锁A,,线程2和线程3只有在获取锁A后才能获取到锁B(锁A是锁B的必要条件),所以线程2或3需要等待线程A释放锁之后才可以进行加锁操作
缺点:按照顺序加锁是一个很有效的死锁预防机制,但是按序加锁也就意味着需要清楚所有可能用到的锁以及锁之间的先后顺序
2.设置加锁时长
若一个线程在给定的时间内没有成功的获取到所需要的锁,则会进行回退并释放其所占用的的锁,然后等待一段随机的时间后在进行尝试
缺点:有些线程可能需要花很长时间去执行任务而导致了锁的超时,所以并不能确定一定发生了死锁
3.设置死锁检测
当一个线程获取锁后,会对其进行记录,记录在数据结构中,如果有线程对某锁进行请求,也会进行记录。当一个线程请求锁失败后,这个线程会去遍历锁的关系图,如果发现发生了死锁,线程则会进行回退和等待,当然,也有可能发生回退后大量线程抢占同一批锁的情况,继而又发生了死锁,这里可以对线程设置优先级,让部分线程先进行回退操作

57. 消息队列

1.为什么要用消息队列?
解耦:A系统调用B系统、C系统,传统的调用是直接调用,但是当B系统说我不需要你提供数据了,这时候A需要改代码,C系统说我不需要某个字段了,这时候A也要改代码,如果又多了一个D系统,A又要写代码。为了实现解耦,引入消息队列,A将产生的数据丢到消息队列中,哪个系统需要,哪个系统就去取;
异步:A系统调用B系统,B系统由于某个需要调用第三方接口超时,导致A系统响应速度慢,而B系统的好坏又不会影响业务逻辑,所以可以改为A异步调用B,A将消息丢到消息队列中,B系统订阅消息,实现A的快速响应;
削峰:当大量流量请求到系统A时,由于数据库的处理能力有限,造成数据库连接异常。使用消息队列,大量请求先丢到消息队列中,系统A使用按批拉数据的方式,批量处理数据,生产中,高峰期短暂的消息积压是允许的。
2.使用消息队列有什么缺点
系统复杂性增加:需要考虑消息的处理,包括消息幂等性(重复消费问题),消息保序性(一个订单多条消息问题),以及消息中间件本身的持久化和稳定性可靠性
系统的可用性降低:解耦后,多个系统通过消息中间件交互,消息中间件挂了整个系统就挂了
3.各种MQ的比较
ActiveMQ:
优点: 技术成熟,功能齐全,历史悠久,有大量公司在使用
缺点: 偶尔会有较低概率丢失数据,而且社区已经不怎么维护5.15.X版本
适用场景: 主要用于系统解耦和异步处理,不适用与大数据量吞吐情况。互联网公司很少适用
rabitMQ:
优点: 吞吐量高,功能齐全,管理界面易用,社区活跃,性能极好
缺点: 吞吐量只是万级,erlang难以二次开发和掌控;集群动态扩展非常麻烦
适用场景: 吞吐量不高而要求低延迟,并且不会频繁调整和扩展的场景。非常适合国内中小型互联网公司适用,因为管理界面非常友好,可以在界面进行配置和优化/集群监控
rocketMQ
优点: 支持百千级大规模topic。吞吐量高(十万级,日处理上百亿)。接口易用。,分布式易扩展,阿里支持。java开发易于掌控
缺点: 与阿里(社区)存在绑定。不兼容JMS规范
适用场景: 高吞吐量
Kafka
优点: 超高吞吐量,超高可用性和可靠性,分布式易扩展
缺点: topic支持少,MQ功能简单,消息可能会重复消费影响数据精确度
适用场景: 超高吞吐量场景而数据精确度没那么高,天然适合大数据实时计算和日志采集场景

58. 内存溢出

内存溢出的情形:
1.java堆内存溢出: 当出现java.lang.OutOfMemoryError:Java heap space异常时,就是堆内存溢出了
发生场景:1.设置的jvm内存太小,对象所需内存太大,创建对象时分配空间,就会抛出这个异常。2.流量/数据峰值,应用程序自身的处理存在一定的限额,比如一定数量的用户或一定数量的数据。而当用户数量或数据量突然激增并超过预期的阈值时,那么就会峰值停止前正常运行的操作将停止并触发java . lang.OutOfMemoryError:Java堆空间错误
解决方法:首先,如果代码没有什么问题的情况下,可以适当调整-Xms和-Xmx两个jvm参数,使用压力测试来调整这两个参数达到最优值。其次,尽量避免大的对象的申请,像文件上传,大批量从数据库中获取,这是需要避免的,尽量分块或者分批处理,有助于系统的正常稳定的执行。最后,尽量提高一次请求的执行速度,垃圾回收越早越好,否则,大量的并发来了的时候,再来新的请求就无法分配内存了,就容易造成系统的雪崩
2. 垃圾回收超时内存溢出:
发生场景: 当应用程序耗尽所有可用内存时,GC开销限制超过了错误,而GC多次未能清除它,这时便会引发java.lang.OutOfMemoryError。当JVM花费大量的时间执行GC,而收效甚微,而一旦整个GC的过程超过限制便会触发错误(默认的jvm配置GC的时间超过98%,回收堆内存低于2%)
解决方法:减少对象生命周期,尽量能快速的进行垃圾回收

59 内存溢出的原因和解决方法

原因:
1.内存中加载的数据量过于庞大,如一次从数据库取出过多数据;
  2.集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;
  3.代码中存在死循环或循环产生过多重复的对象实体;
  4.使用的第三方软件中的BUG;
  5.启动参数内存值设定的过小;
解决方法:
第一步,修改JVM启动参数,直接增加内存。(-Xms,-Xmx参数一定不要忘记加。)
  第二步,检查错误日志,查看“OutOfMemory”错误前是否有其它异常或错误。
  第三步,对代码进行走查和分析,找出可能发生内存溢出的位置。

61设计模式以及原理?

1、工厂模式:创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。应用实例: 1、您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。使用场景: 1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。 2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。 3、设计一个连接服务器的框架,需要三个协议,“POP3”、“IMAP”、“HTTP”,可以把这三个作为产品类,共同实现一个接口。
2、单例模式:创建型模式,这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。应用实例:一个班级只有一个班主任。使用场景:1、要求生产唯一序列号。2、WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。3、创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等
3、代理模式:结构型模式,在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。应用实例:Windows 里面的快捷方式。使用场景:按职责来划分,通常有以下使用场景: 1、远程代理。 2、虚拟代理。 3、Copy-on-Write 代理。 4、保护(Protect or Access)代理。
4、MVC模式:Model-View-Controller(模型-视图-控制器)模式,这种模式用于应用程序的分层开发,Model(模型) - 模型代表一个存取数据的对象或 JAVA POJO。它也可以带有逻辑,在数据变化时更新控制器;View(视图) - 视图代表模型包含的数据的可视化;Controller(控制器) - 控制器作用于模型和视图上。它控制数据流向模型对象,并在数据变化时更新视图。它使视图与模型分离开。

62、分布式和集群的区别?

多台服务器合起来跑的才是一套完整代码,这就叫分布式;多台服务器跑的都是一套完整的代码,这就叫集群

63微服框架?

微服务架构是一种架构模式或者说是一种架构风格,它将单一应用程序划分一组小的服务,每个服务运行在其独立的自己的进程中,服务之间按照一定的方式进行通信。

66、Jdk 1.8新出了什么功能?

1、default关键字
2、Lambda 表达式
3、函数式接口
4、方法与构造函数引用
5、局部变量限制
6、Date Api更新;
7、流

68、内连接和左外连接的区别?

内连接:显示两个表中有联系的所有数据;左链接:以左表为参照,显示所有数据,右边表数据数据少了补NULL值,数据多了不显示。

69、Zookeeper原理、作用?

ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务。 功能:主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。 原理:Zookeeper的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和 leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态。

70、Dubbo特点和springcloud区别?

SpringCloud和Dubbo都是现在主流的微服务架构,
区别:1、Dubbo是阿里系的分布式服务框架;SpringCloud是Apache旗下的Spring体系下的微服务解决方案;
2、服务的调用方式:Dubbo使用的是RPC远程调用,而SpringCloud使用的是 Rest API; 3、服务的注册中心:Dubbo使用了第三方的ZooKeeper作为其底层的注册中心,SpringCloud使用Eureka实现注册中心
4、服务网关:Dubbo并没有本身的实现,只能通过其他第三方技术的整合,而SpringCloud有Zuul路由网关,作为路由服务器,进行消费者的请求分发;
5、SpringCloud还支持断路器,与git完美集成分布式配置文件支持版本控制,事务总线实现配置文件的更新与服务自动装配等等一系列的微服务架构要素

71.如何保证线程安全

1、使用线程安全的类;
2、使用synchronized同步代码块,或者用Lock锁;
3、多线程并发情况下,线程共享的变量改为方法局部级变量

73 单例模式的作用

1、控制资源的使用,通过线程同步来控制资源的并发访问;
2、控制实例产生的数量,达到节约资源的目的。
3、作为通信媒介使用,也就是数据共享,它可以在不建立直接关联的条件下,让多个不相关的两个线程或者进程之间实现通信。

74.数据库优化的方法

1、选取最适用的字段属性
2、使用连接(JOIN)来代替子查询(Sub-Queries)
3、使用联合(UNION)来代替手动创建的临时表
4、事务
5、锁定表
6、使用外键
7、使用索引
8、优化的查询语句

  1. finally final finaize的区别
  • final是修饰符,修饰类、方法和变量,意为不可修改的。当修饰类的时候不可以派生出新的子类,因此一个类的修饰符不可以既是final和abstract;修饰方法的时候该方法不可以被重载;修饰变量的时候需要给变量赋初值,在接下来只能对其读取不可以重新赋值。

  • finally是在异常处理时提供finally块来执行任何清除操作的,如果try语句中发生了catch块中的异常,则跳转到catch中进行异常处理,而finally中的内容则是无论异常是否发生都要执行的。如果finally中有return,则会先执行finally再执行return,如果此时try中也有return,则try中的return不会执行,但是,如果只有try中有return也是先执行finally中的语句再执行return;

  • finalize是方法名,在垃圾回收器将对象从内存中清理出去之前做的必要工作。是由垃圾回收器在确定这个对象没有被引用的时候调用的,它是在Object中定义的,子类重写finalize方法整理系统资源或其他清理工作finalize方法是在垃圾收集器删除对象之前调用的。

    连接池的作用是什么?

连接池是将已经创建好的连接保存在池中,当有请求来时,直接使用已经创建好的连接对数据库进行访问。这样省略了创建连接和销毁连接的过程。这样性能上得到了提高。

88.除了SSM还用过什么框架

十大常用框架:一、SpringMVC。二、Spring三、Mybatis。四、Dubbo。五、Maven。六、RabbitMQ。七、Log4j。八、Ehcache。九、Redis。十、Shiro。
什么会说什么,不会不要说

90.springIOC和AOP原理

IoC(Inversion of Control)
(1). IoC(Inversion of Control)是指容器控制程序对象之间的关系,而不是传统实现中,由程序代码直接操控。控制权由应用代码中转到了外部容器,控制权的转移是所谓反转。 对于Spring而言,就是由Spring来控制对象的生命周期和对象之间的关系;IoC还有另外一个名字——“依赖注入(Dependency Injection)”。从名字上理解,所谓依赖注入,即组件之间的依赖关系由容器在运行期决定,即由容器动态地将某种依赖关系注入到组件之中。
(2). 在Spring的工作方式中,所有的类都会在spring容器中登记,告诉spring这是个什么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。
(3). 在系统运行中,动态的向某个对象提供它所需要的其他对象。
(4). 依赖注入的思想是通过反射机制实现的,在实例化一个类时,它通过反射调用类中set方法将事先保存在HashMap中的类属性注入到类中。 总而言之,在传统的对象创建方式中,通常由调用者来创建被调用者的实例,而在Spring中创建被调用者的工作由Spring来完成,然后注入调用者,即所谓的依赖注入or控制反转。 注入方式有两种:依赖注入和设置注入; IoC的优点:降低了组件之间的耦合,降低了业务对象之间替换的复杂性,使之能够灵活的管理对象。
AOP(Aspect Oriented Programming)
(1). AOP面向方面编程基于IoC,是对OOP的有益补充;
(2). AOP利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了 多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的 逻辑或责任封装起来,比如日志记录,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。
(3). AOP代表的是一个横向的关 系,将“对象”比作一个空心的圆柱体,其中封装的是对象的属性和行为;则面向方面编程的方法,就是将这个圆柱体以切面形式剖开,选择性的提供业务逻辑。而 剖开的切面,也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹,但完成了效果。
(4). 实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。
(5). Spring实现AOP:JDK动态代理和CGLIB代理 JDK动态代理:其代理对象必须是某个接口的实现,它是通过在运行期间创建一个接口的实现类来完成对目标对象的代理;其核心的两个类是InvocationHandler和Proxy。 CGLIB代理:实现原理类似于JDK动态代理,只是它在运行期间生成的代理对象是针对目标类扩展的子类。CGLIB是高效的代码生成包,底层是依靠ASM(开源的java字节码编辑类库)操作字节码实现的,性能比JDK强;需要引入包asm.jar和cglib.jar。 使用AspectJ注入式切面和@AspectJ注解驱动的切面实际上底层也是通过动态代理实现的

91自己写会怎么写IOC,AOP

IOC:准备配置文件、由IOC容器进行解析元数据、实例化IOC容器
AOP:一是采用动态代理技术,二是采用静态织入的方式

93在二班的课程大于3个的学生

SELECT name from student WHERE class=2 GROUP BY name HAVING count(lesson)>3

web.xml的作用

web.xml文件是用来初始化配置信息, 一个web中可以没有web.xml文件,也就是说,web.xml文件并不是web工程必须的。
web.xml常用的一些标签元素及其功能:
1、 指定欢迎页面
2、 命名与定制URL。
3、 定制初始化参数:可以定制servlet、JSP、Context的初始化参数,然后可以再servlet、JSP、Context中获取这些参数值。
4、 指定错误处理页面,可以通过“异常类型”或“错误码”来指定错误处理页面
5、 设置过滤器:比如设置一个编码过滤器,过滤所有资源
6、 设置监听器
7、 设置会话(Session)过期时间,其中时间以分钟为单位

ArrayList和LinkedList区别

ArrayList:
0.ArrayList默认的初始缓冲空间是10个
1.ArrayList的底层的数据结构采用的数组结构。(结构)
2.存储数据的顺序和取出数据的顺序是一致的。(读写性质)
3.ArrayList在处理读取和添加数据的效率非常高。(强项)
4.ArrayList在执行插入和删除的操作时效率比较低,因为底层实现采用的 (弱项)是数组结构,所有每删除个元素n 则n元素之后的元素的下标都会向前移动一次。
使用注意事项:
集合的元素的类型不能是基本数据类型,只能是引用数据类型。

LinkedList:
0.LinkedList默认的初始缓冲空间是01.LinkedList的底层的数据结构采用的是链表结构。
2.LinkedList插入和删除效率比较高,因为删除元素值,只需要修改当前删除元素的前一个指针指向当前删除元素的下一个元素。
3.读取的效率相对于ArrayList比较低。

重写注意点,怎么看调用的是父类还是子类,权限要求

重写是在子类中出现和父类同名的方法。
1.子类重写父类方法的方法范围必须大于等于父类类型,但是不能是private类型。
2.父类私有的方法是不能被子类重写。
3.子类中的同名方法除了范围修饰符不同,其他的都必须相同。

重载的返回值要求

重载与返回值无关;2.只有返回值类型不同的方法,不构成重载

115mybatis中的#和 的 区 别 , 的区别, 的区别,的应用场景

一、恒生电子面试题 4

1、JVM原理

内容见<面试必问之JVM原理>,参考地址
JVM->java虚拟机,解释器,负责将程序员编写的.java文件编译为多平台通用的字节码(.class)文件,最终将字节码解释给计算机执行
[JVM内存区域主要划分为“线程共享区”“非线程共享区”,比如,Method Area(方法区,non-heap)与Heap(堆),Direct Memory(运行时数据区域)是线程共享的,VM Stack(java方法栈,虚拟机栈),Native Method Stack(本地方法栈)和Program Counter Register(程序计数器)是非线程共享的]

工作过程::JVM运行时初始分配方法区与堆,遇到线程时,分配程序计数器,虚拟机栈,本地方法栈,线程终止时,三者的内存空间会被释放(生命周期==所属线程生命周期),这也是为什么GC机制只会发生在“线程共享区”的原因。

2、事务如何主动回滚?

在spring框架的声明式事务处理中,只要抛出的异常是属于运行时异常的,spring的异常处理机制会自动回滚事务.
↑所属情景:java中的框架处理
如果是数据库中的事务,在你commit提交前执行rollback命令就好了,如果是已经commit的事务就不好恢复了。

3、dubbo的优点

首先Dubbo 是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成。
1.远程通讯: 提供对多种基于长连接的NIO框架抽象封装,包括多种线程模型,序列化,以及“请求-响应”模式的信息交换方式。
2.软负载均衡及容错机制: 提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持.可在内网替代F5等硬件负载均衡器,降低成本,减少单点
3.服务自动注册与发现: 基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器
4.提供完善的管理控制台dubbo-admin与简单的控制中心dubbo-monitor
5.Dubbo提供了伸缩性很好的插件模型,很方便进行扩展(ExtensionLoader)
6.支持多协议
使用方法:
Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载。

太长不看,背不下来的建议回答如下:
Dubbo,作为阿里的优秀开源框架,确实比较好用,跟spring兼容度也不错,它本身有很多优点,比如负载均衡跟容错之类做的都比较好,但我觉得最好的一点是它提供了伸缩性很好的插件模型,这点可以让你很方便的进行扩展,给了我们更多的可能性。

4. dubbo中消费者调用提供者原理

Provider:暴露服务方称之为“服务提供者”
Consumer:调用远程服务方称之为“服务消费者”
Registry:服务注册与发现的中心目录服务称之为“服务注册中心”
Monitor:统计服务的调用次调和调用时间的日志服务称之为“服务监控中心”
Provider发布后会在Registry中注册,Consumer从Registry订阅服务,一旦注册中心提供了Provider, Consumer就可以异步得到通知,从而调用Provider的功能,这两者都会在Monitor监控中心中被记录调用的信息.

看起来绕口,其实描述不如画图↓↓↓↓↓

4、spring作用

Spring框架主要用于与其他技术(struts,hibernate等)进行整合,可将 应用程序中的Bean组件实现低耦合关联.最终可以提高系统扩展和维护 性.将来我们利用Spring框架管理系统的各个组件(Action,Service,DAO)采 用Spring的IOC和AOP机制实现各组件的关联.从而实现了低耦合调用. 增强了系统可维护性和扩展性.
降低组件耦合性,实现程序各层解耦;
主流框架集成,如XXX;
低侵入式设计,不影响代码;
最主要的还是IOC与AOP,让我们更加方便快捷的进行开发。
主要解释IOC与AOP:
IOC:依赖注入(控制反转),将所需要用到的类以注解或配置文件的方式提供给spring,由spring生成(默认为单例)对象,更简单的实现业务对象。 [注入方式有两种,第一种是设置注入,比较直观,自然。第二种是构造注入,可以在构造器中指定依赖关系顺序]
(底层实现基本就是反射机制那一套,熟的可以BB两句)
AOP:切面编程,基于OOP面向对象的一种补充。主要是提供一个更好更方便的事务管理方式,同时也支持我们自定义切面。[面向对象是将程序分解为各个层次的对象,面向切面是将程序运行过程分解为各个切面。] [OOP是静态的抽象,AOP是动态的,对应用执行过程中的步骤进行抽象,从而获得步骤之间的逻辑划分。]
(*主要特性) AOP以步骤划分,各个步骤之间有非常好的隔离型,并且与源代码没有什么关联性。你可以很方便的在某个步骤前后加上自己想要的操作。

5、事务ACID

ACID,指数据库事务正确执行的四个基本要素的缩写。包含:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。一个支持事务(Transaction)的数据库,必须要具有这四种特性,否则在事务过程(Transaction processing)当中无法保证数据的正确性,交易过程极可能达不到交易方的要求。
原子性:要么不谈,要谈就要结婚。
一致性:恋爱时,什么方式爱我;结婚后还得什么方式爱我;
隔离性:闹完洞房后,是俩人的私事。
持久性:一旦领了结婚证,无法后悔。

6、最近在看什么书?

<JVM虚拟机原理><java设计模式><重构>
Java高并发编程模式与原则

7、最近学会什么技术?

Shiro框架,还了解了一些SpringCloud体系的Eureka, Config, Bus,Hadoop生态圈MapRecude,HBASE,Spark,Kafka的知识点,正准备深入
SpringCloud:
Q:什么是springcloud?
A:springcloud是一套完整的微服务解决方案,基于springboot框架。但准确来说,它并不是一个框架,而更像是一个大的容器,将市面上成型比较好的微服务框架集成进来,简化了开发者的代码;
Q:spring核心组件:
A:分两类
一类是融合在微服务中,依赖其他组件并为其提供服务:
Ribbon客户端负载均衡;
Hystrix客户端容错保护;
Feign声明式服务调用,本质上是Ribbon+Hystrix;
Stream 消息驱动;
Bus消息总线;
Sleuth分布式服务追踪
第二类是独自启动,不需要依赖其他组件的:
Eureka 服务注册中心;
Dashboard Hystrix仪表盘;
Zuul API服务网关
Config 分布式配置中心

8、消费者调用提供者如果网络断了怎么办?

三种方案1,dubbo部署集群,当前网络中断可在集群中匹配到其它提供者实现,如果没有找到其它提供者, 服务提供者和服务消费者仍能通过本地缓存通讯,直到网络恢复.2 消费者在调用过程中如果得不到提供者的回馈则设定时间取消操作,事务进行回滚处理.保证事务完整性3将请求消息放入消息队列中,提示用户操作,当提供者正常服务后进行消费,从而保证事务完整性.
如果是客户网断的情况大多不用担心,根据当前环境判断是否回滚,给出通知让用户上线后知道刚才做了什么,保留了什么,业务进行到哪。
如果是服务器断网(环境肯定是分布式了)
判断是否有集群,有则直接切换。没有集群的话消费者读取本地缓存,继续提供服务,实在获取不到服务的情况下,为了保证数据安全,消费者将在设定时间后进行事务回滚,除此之外,请求消息可暂时放入消息队列,在提供者上线后再进行操作。

二、软通动力面试题

1、说几个线程安全的类

Timer,TimerTask,Vector,Stack,HashTable,ConcurrentHashMap,StringBuffer

2、介绍springMVC

Spring MVC框架是有一个MVC框架,通过实现Model-View-Controller模式来很好地将数据、业务与展现进行分离。从这样一个角度来说,Spring MVC和Struts、Struts2非常类似。Spring MVC的设计是围绕DispatcherServlet展开的,DispatcherServlet负责将请求派发到特定的handler。通过可配置的handler mappings、view resolution、locale以及theme resolution来处理请求并且转到对应的视图,具体的请求流程如下:
1、用户发送请求至前端控制器DispatcherServlet
2、DispatcherServlet收到请求调用HandlerMapping处理器映射器查找Handler。HandlerMapping可以根据xml配置、注解配置进行查询。
3、处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
4、DispatcherServlet通过HandlerAdapter处理器适配器调用处理器,处理器在实际开发中习惯称为controller(另一种说法处理器是后端控制器,最终调用service进行业务处理)。
5、HandlerAdapter调用处理器Handler
6、Handler执行完成返回ModelAndView,ModelAndView是springmvc的封装对象,将模型和视图封装在一个对象中。
7、HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet
8、DispatcherServlet将ModelAndView传给ViewReslover视图解析器,ViewReslover根据逻辑视图名解析View逻辑视图名:如果指定具体的jsp完整地址不方便,将完整的地址简化为逻辑的视图名(串)。view:是一个接口,接口实现了很多类型的view(比如:jstlView、pdfView、freemarker、报表的view)ViewReslover:不同的视图解析器可以解析出上边不同的view.
9、ViewReslover返回View
10、DispatcherServlet对View进行渲染视图(即将模型数据填充至request域)。
11、DispatcherServlet响应用户(将jsp转发给用户,最终由tomcat解析servlet生成html,最终响应)
它在程序中可以设置成单例,因为没有全局的数据域.

3、讲讲栈内存和堆内存

栈:主要是用来执行程序的,堆:主要用来存放对象的
栈(stack):有编译器自动分配和释放,存放函数的参数、局部变量、临时变量、函数返回地址等;
堆(heap):一般有程序员分配和释放,如果没有手动释放,在程序结束时可能由操作系统自动释放(?这个可能针对Java那样的有回收机制的语言而说的,对于c/c++,这样的必须要手动释放开辟的堆内存),稍有不慎会引起内存泄漏。

栈:只要栈的剩余空间大于所申请的空间,系统将为程序提供内存,否则将报异常提示栈溢出。
堆:在记录空闲内存地址的链表中寻找一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。另外,对于大多数系统会在这块内存空间的首地址出记录本次分配空间的大小,这样代码中的delete 才能正确释放本内存空间。系统会将多余的那部分重新空闲链表中。
栈:由系统自动分配,速度较快。但程序员是无法控制的。
堆:由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便.

4、Oracle常用函数

1.单行函数
(1)concat(str1,str2)字符串拼接函数
(2)initcap(str)将每个单词首字母大写,其他字母小写
(3)instr(x,find_string[,start][,occurrence])返回指定字符串在某字符串中的位置,可以指定搜索的开始位置和返回第几次搜索出来的结果
(4)length(str)返回表达式中的字符数
(5)lengthb(str)返回表达式中的字节数
(6)lower(str)将字符串转换为小写
(7)upper(str)将字符串转换为大写
(8)lpad(str,width[,pad_string])当字符串长度不够时,左填充补齐,可以指定补齐时用什么字符补齐,若不指定,则以空格补齐
(9)rpad(str,width[,pad_string])当字符串长度不够时,右填充补齐,原理同左填充
(10)ltrim(x[,trim_string])从字符串左侧去除指定的所有字符串,若没有指定去除的字符串,则默认去除左侧空白符
(11)rtrim(x[,trim_string])从字符串右侧去除指定的所有字符串,原理同ltrim()
(12)trim(trim_string from x)从字符串两侧去除指定的所有字符串
(13)nvl(x,value)将一个NULL转换为另外一个值,如果x为NULL,则返回value,否则返回x值本身
(14)nvl2(x,value1,value2),如果x不为NULL,返回value1,否则,返回value2
(15)replace(x,search_string,replace_string),从字符串x中搜索search_string字符串,并使用replace_string字符串替换。并不会修改数据库中原始值
(16)substr(x,start[,length])返回字符串中的指定的字符,这些字符从字符串的第start个位置开始,长度为length个字符;如果start是负数,则从x字符串的末尾开始算起;如果       length省略,则将返回一直到字符串末尾的所有字符
2.数值函数
(1)abs(value)返回value的绝对值
(2)ceil(value)返回大于等于value的最小整数
(3)floor(value)返回小于等于value的最大整数
(4)trunc(value,n)对value进行截断,如果n>0,保留n位小数;n<0,则保留-n位整数位;n=0,则去掉小数部分
(5)round(value,n)对value进行四舍五入,保存小数点右侧的n位。如果n省略的话,相当于n=0的情况
3.转换函数
(1)to_char(x[,format]):将x转化为字符串。 format为转换的格式,可以为数字格式或日期格式
(2)to_number(x [, format]):将x转换为数字。可以指定format格式
(3)cast(x as type):将x转换为指定的兼容的数据库类型
(4)to_date(x [,format]):将x字符串转换为日期
4.聚合函数
(1)avg(x):返回x的平均值
(2)count(x):返回统计的行数
(3)max(x):返回x的最大值
(4)min(x):返回x的最小值
(5)sum(x):返回x的总计值

5、数据库视图的优化,存储过程

视图是指计算机数据库中的视图,是一个虚拟表,其内容由查询定义。对于复杂的连表查询,可以利用创建视图来使SQL语句变得简单。
数据库优化方式有:
1.给适当的列加上索引。
2尽量避免全表扫描,首先应考虑在where及order by涉及的列上建立索引。
3.避免使用 select * 从数据库里读出越多的数据,那么查询就会变得越慢
4永远为每张表设置一个ID使用VARCHAR类型来当主键会使得性能下降
5使用ENUM而不是VARCHAR
sex ENUM(‘男’,‘女’)
如果一个列只含有有限树木的特定值,比如:性别、状态等,尽量采用ENUM列举出所有可能的取值作为数据类型,enum列的值都是以标识数值标识,mysql会处理的更快。
6.尽量避免在where子句中使用or来连接条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描

7.模糊查询不要以通配符开始,否则会导致索引失效而进行全表扫描
select from t_student where sName like ‘a%’
8.尽量避免在where子句中对字段进行表达式操作,这会导致引擎失效放弃使用索引而进行全表扫描。
select id from t where num/2=100
应该改为 select id from t where num=1002
9.In和not in要慎用,否则可以导致全表扫描,可以用exists代替In。
Select num from a where num in(select num from b)
用下面的语句替换
Select num from a where exists(select 1 from b where num=a.num)
10.一个表的索引最好不要超过6个,若太多则应考虑删除不常使用的索引
11.尽量避免大事务操作,提高系统并发能力
12.并不是所有索引对查询都有效,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如果一表中有字段sex,male,female几乎各一半,那么即使在sex上建了索引页会查询效率起不了太大作用

使用存储过程实现优化,因为存储过程的优点很多:

1存储过程只在创造时进行编译,以后每次执行存储过程都不需再重新编译,而一般SQL语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。
2当对数据库进行复杂操作时(如对多个表进行Update,Insert,Query,Delete时),可将此复杂操作用存储过程封装起来与数据库提供的事务处理结合一起使用。
3存储过程可以重复使用,可减少数据库开发人员的工作量。
4安全性高,可设定只有某些用户才具有对指定存储过程的使用权
如何保证接口的安全可靠,

题意不清.什么接口?如果是指HTTP接口那么有如下方式可供选择

1、选择拦截过滤器。
在请求的时候对请求方法进行一次拦截处理。比如非正常访问的方法已经注入插入可执行语句参数验证等在拦截中进行一次安全校验保证请求不是非法请求。
2、数据加密。我们知道目前大部分APP接口都是通过Http协议进行调用的容易被抓包拦截。我们可以对客户端和服务端都对数据传输的时候进行一个加密处理。常用的MD5 AES等。
3、签名
根据用户名或者用户id,结合用户的ip或者设备号,生成一个token。在请求后台,后台获取http的head中的token,校验是否合法(和数据库或者Redis中记录的是否一致,在登录或者初始化的时候,存入数据库/redis)爱旅行项目中就采用的Token方式.
4、使用第三方框架与技术整合支持比如spring的框架中的oauth模块。还有Shiro框架等.

6、常用的集合和区别

1.Collection
Collection是最基本的集合类型,所有实现Collection接口的类都必须提供两个标准的构造函数:无参数的构造函数用于创建一个共的Collection,有一个Collection参数的构造函数用于创建一个新的Collection,这个新的Collection与传入的Collection有相同的元素。若要检查Collection中的元素,可以使用foreach进行遍历,也可以使用迭代器,Collection支持iterator()方法,通过该方法可以访问Collection中的每一个元素。

Set和List是由Collection派生的两个接口.List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引的位置来访问List中的元素,类似于Java数组。List允许有相同的元素存在。
实现List接口的常用类有LinkedList、ArrayList、Vector和Stack
2.LinkedList类
LinkedList实现了List类接口,允许null元素。此外LinkedList提供额外的get、remove、insert方法在LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque)
LinkedList没有同步方法。如果多个线程想访问同一个List,则必须自己实现访问同步。
3.AyyayList类
ArrayList实现了可变大小的数组。它允许所有元素,包括null。ArrayList没有同步。size(),isEmpty(),get(),set()方法运行时间为常数。但是add()方法开销为分摊的常数,添加n个元素需要O(n)的时间。其他的方法运行时间为线性。每个ArrayList实例都有一个容量(Capactity),即用于存储元素的数组的大小。这个容量可随着不断添加新元素而自动增加,但是增长算法并没有定义。当需要插入大量元素时,在插入之前可以调用ensureCapacity()方法来增加ArrayList容量已提高插入效率
4.Vector类
Vector非常类似ArrayList,但是Vector是同步的。由Vector创建的iterator,虽然和ArrayLsit创建的iterator是同一接口,但是,因为Vector是同步的,当一个iterator被创建而且这在被使用,另一个线程改变了Vector状态,这时调用iterator的方法时将抛出ConcurrentModificationException,因此必须捕获该异常。
Stack类
Stack继承自Vector,实现了一个后进先出的堆栈。Stack提供了5个额外的方法使得Vector得以被当做堆栈使用。基本的push和pop方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,serach方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。

5.Set接口
Set是一种不包含重复元素的Collection,即任意的两个元素e1和e2都有e1.equals(e2)=false,Set最多有一个null元素。Set的构造函数有一个约束条件,传入的Collection参数不能包含重复的元素。请注意:必须小心操作可变对象。如果一个Set中的可变元素改变了自身的状态导致Object.equals(Object)=true将导致一些问题
HashSet
HashSet调用对象的hashCode(),获得哈希码,然后在集合中计算存放对象的位置。通过比较哈希码与equals()方法来判别是否重复。所以,重载了equals()方法同时也要重载hashCode();
6.TreeSet
TreeSet 继承SortedSet接口,能够对集合中对象排序。默认排序方式是自然排序,但该方式只能对实现了Comparable接口的对象排序,java中对Integer、Byte、Double、Character、String等数值型和字符型对象都实现了该接口。
7.Map接口
Map没有继承Collection接口,Map提供key到value的映射。一个Map中不能包含相同的key,每个key只能映射一个value。Map接口提供了3中集合的视图,Map的内容可以被当作一组key集合,一组value集合,或者一组key–value映射。
HashTable类
HashTable继承Map接口,实现了一个key–value映射的哈希表。任何非空的对象都可作为key或者value。添加数据使用put(key,value),取出数据使用get(key),这两个基本操作的时间开销为常数。 HashTable通过initial caoacity和load factor两个参数调整性能。通常缺省的load factor 0.75较好地实现了时间和空间的均衡。增大了load factor可以节省空间但相应的查找时间将增大,这会影响像get和put这样的操作.HashTable是同步的.
HashMap类
HashMap和HashTable类似,不同之处在于HashMap是非同步的,并且允许null,即null value和null key,但是将HashMap视为Collection时,其迭子操作时间开销和HahMap的容量成比例。因此,如果迭代操作的性能相当重要的话,不要将HashMap的初始化容量设的过高,或者load factor过低

7、gc如何调用
通过System.gc()方法可以进行调用垃圾回收器(GC),但Java的GC是由JVM自行调动的,在需要的时候才执行,上面的指令只是告诉JVM尽快GC一次,但不会立即执行GC。也可以通过对需要回收的对象通过close()或者赋值成null,通知GC尽快回收.
8、多表连接注意事项
.在数据库中,通常可以通过查看执行计划了解sql语句的执行顺序,以及花费的时间等,但在使用left join时,需要特别注意的是,如果第二张表有筛选条件,应该将连接条件写在join里面,而不是写在where后面.

9、视图优缺点

1.视图的优点:
第一点:使用视图,可以定制用户数据,聚焦特定的数据。
解释:在实际过程中,公司有不同角色的工作人员,我们以销售公司为例的话,采购人员,可以需要一些与其有关的数据,而与他无关的数据,对他没有任何意义,我们可以根据这一实际情况,专门为采购人员创建一个视图,以后他在查询数据时,只需select * from view_caigou 就可以啦。
第二点:使用视图,可以简化数据操作。
解释:我们在使用查询时,在很多时候我们要使用聚合函数,同时还要显示其它字段的信息,可能还会需要关联到其它表,这时写的语句可能会很长,如果这个动作频繁发生的话,我们可以创建视图,这以后,我们只需要select * from view1就可以啦,这样很方便。
第三点:使用视图,基表中的数据就有了一定的安全性因为视图是虚拟的,物理上是不存在的,只是存储了数据的集合,我们可以将基表中重要的字段信息,可以不通过视图给用户,视图是动态的数据的集合,数据是随着基表的更新而更新。同时,用户对视图,不可以随意的更改和删除,可以保证数据的安全性。
第四点:可以合并分离的数据,创建分区视图
随着社会的发展,公司的业务量的不断的扩大,一个大公司,下属都设有很多的分公司,为了管理方便,我们需要统一表的结构,定期查看各公司业务情况,而分别看各个公司的数据很不方便,没有很好的可比性,如果将这些数据合并为一个表格里,就方便多啦,这时我们就可以使用union关键字,将各分公司的数据合并为一个视图。
2.视图的缺点:
1)性能差
数据库必须把视图查询转化成对基本表的查询,如果这个视图是由一个复杂的多表查询所定义,那么,即使是视图的一个简单查询,数据库也要把它变成一个复杂的结合体,需要花费一定的时间。
2)修改限制
当用户试图修改试图的某些信息时,数据库必须把它转化为对基本表的某些信息的修改,对于简单的试图来说,这是很方便的,但是,对于比较复杂的试图,可能是不可修改的。
10、用户登录注销之后要做什么事
通常清除用户会话状态, 视业务需求而定是否在客户写入端cookie信息在数据保存注销时间等业务.

11、Linux 命令

ls  显示文件或目录
mkdir 创建目录
cd 切换目录
touch 创建空文件
echo 创建带有内容的文件。
cat 查看文件内容
cp 拷贝
mv 移动或重命名
rm 删除文件
find 在文件系统中搜索某文件
wc 统计文本中行数、字数、字符数
grep 在文本文件中查找某个字符串
rmdir 删除空目录
tree 树形结构显示目录,需要安装tree包
pwd 显示当前目录
ln 创建链接文件
more、less 分页显示文本文件内容
head、tail 显示文件头、尾内容
stat 显示指定文件的详细信息,比ls更详细
who 显示在线登陆用户
whoami 显示当前操作用户
hostname 显示主机名
uname 显示系统信息
top 动态显示当前耗费资源最多进程信息
ps 显示瞬间进程状态 ps -aux
du 查看目录大小 du -h /home带有单位显示目录信息
df 查看磁盘大小 df -h 带有单位显示磁盘信息
ifconfig 查看网络情况
ping 测试网络连通
netstat 显示网络状态信息
man 命令不会用了,找男人如:man ls
clear 清屏
alias 对命令重命名如:alias showmeit=“ps -aux”
kill 杀死进程,可以先用ps 或 top命令查看进程的id
tar: 打包压缩
shutdown 关机重启
halt 关机
reboot 重启
sudo dpkg -i tree_1.5.3-1_i386.deb 安装软件
sudo dpkg -r tree 卸载软件
sudo apt-get install tree 安装tree
sudo apt-get remove tree 卸载tree
sudo apt-get update 更新软件
sudo apt-get upgrade
vim三种模式:命令模式、插入模式、编辑模式。使用ESC或i或:来切换模式。
命令模式下:
:q 退出
:q! 强制退出
:wq 保存并退出
:set number 显示行号
:set nonumber 隐藏行号
yyp 复制光标所在行,并粘贴
passwd root 给root设置密码
/etc/profile 系统环境变量
bash_profile 用户环境变量
.bashrc 用户环境变量
su user 切换用户,加载配置文件.bashrc
su - user 切换用户,加载配置文件/etc/profile ,加载bash_profile
sudo chown [-R] owner[:group] {File|Directory}更改文件的用户及用户组
sudo chmod 777 filename 更改权限三、公司面试题
1、说说你项目中为什么使用Springboot,dubbo,redis,activeMQ?

1.Spring Boot作为微服务的入门级微框架,有四点好处

Spring Boot使编码变简单
Spring Boot使配置变简单
Spring Boot使部署变简单
Spring Boot使监控变简单
Dubbo是一种服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和Spring框架无缝集成。
在项目中使用redis,主要是从两个角度去考虑:性能和并发。当然,redis还具备可以做分布式锁,消息队列等其他功能,但还有其他中间件(如zookpeer,activeMQ等)代替,并不是非要使用redis。因此,主要从性能和并发两个角度出发去考虑的。
(一)性能
在碰到需要执行耗时特别久,且结果不频繁变动的SQL,就特别适合将运行结果放入缓存。这样,后面的通过请求就去缓存中读取放入到activeMQ,使得请求能够迅速响应。
(二)并发
在大并发的情况下,所有的请求直接访问数据库,数据库会出现连接异常。这个时候,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问数据库。
ActiveMQ的特性主要管理消息的事务,以及消息持久化,即使在出错时也不会漏掉一条消息。消息服务器需要进行信息持久化,一个服务器集群可以提高其可用性,ActiveMQ正式这样的一个高可用性的消息服务器,典型的情况就是当一个Server Node掉线的时候,它上面的所有消息都会被保存下来,以便在它重新上线时继续处理。ActiveMQ的的另一个特性是高性能的数据分发,主要关注的是消息的吞吐率以及高效的消息投递路由,中心思想就是在一个大的网络中尽可能快的传递大量的并且快速改变的消息数据。鉴于大量的数据和频繁的数据数据交换负荷很高,所以这种情况下很少使用数据持久化,在失败时丢失几条数据也是可以接受的因为老的数据通常都不再被需要了,最新的数据才是真正我们关心的.
2、Redis 持久化的原理
由于Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能,将数据保存到磁盘上,当redis重启后,可以从磁盘中恢复数据。redis提供两种方式进行持久化,一种是RDB持久化(原理是将Reids在内存中的数据库记录定时dump到磁盘上的RDB持久化),另外一种是AOF(append only file)持久化(原理是将Reids的操作日志以追加的方式写入文件)。RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。相比于AOF机制,如果数据集很大,RDB的启动效率会更高。
3、IOC的原理
Spring Bean的创建是典型的工厂模式,这一系列的Bean工厂,也即IOC容器为开发者管理对象间的依赖关系提供了很多便利和基础服务,在Spring中有许多的IOC容器的实现供用户选择和使用,其中BeanFactory作为最顶层的一个接口类,它定义了IOC容器的基本功能规范,在容器初始化时创建程序所需的对象,实现控制反转,就是把原先我们代码里面需要实现的对象创建、依赖的代码,反转给容器来帮忙实现。那么必然的我们需要创建一个容器,同时需要一种描述来让容器知道需要创建的对象与对象的关系,这就IoC 容器:最主要是完成了完成对象的创建和依赖的管理注入等这个描述最具体表现就是我们可配置的文件。
4、如何反射生成一个对象?
反射是java特有的一种机制,可以在程序运行的过程中,动态的获取类的属性和方法,可以通过类的全限定名,对象本身,类本身获取字节码对象。通过字节码对象获取构造器,字段,方法等对象。

会用什么开发软件?
IDE :IDEA,Eclipse,MyEclipse,NetBean,DreamWare
Server:Tomcat,WebLogic,Jetty,
OS:Linux,Ubuntu,Centos,Windows
DB:mysql ,Oracle,SQL Server
5、spring注解开发了解一下
springboot是纯以注解开发的,基础的springmvc注解有
@Configuration把一个类作为一个IoC容器,它的某个方法头上如果 注册了@Bean,就会作为这个Spring容器中的Bean。
@Scope注解作用域
@Lazy(true) 表示延迟初始化
@Service用于标注业务层组件、
@Controller用于标注控制层组件(如struts中的action)
@RestController 相当于Controller+@ResponseBody
@Repository用于标注数据访问组件,即DAO组件。
@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
@Scope用于指定scope作用域的(用在类上)
@PostConstruct用于指定初始化方法(用在方法上)
@PreDestory用于指定销毁方法(用在方法上)
@DependsOn:定义Bean初始化及销毁时的顺序
@Primary:自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常
@Autowired 默认按类型装配,如果我们想使用按名称装配,可以结合@Qualifier注解一起使用。如下:
@Autowired @Qualifier(“personDaoBean”) 存在多个实例配合使用
@Resource默认按名称装配,当找不到与名称匹配的bean才会按类型装配。
@PostConstruct 初始化注解
@PreDestroy 摧毁注解默认单例启动就加载
@Async异步方法调用
6、前端获取数据有几种方式
1通过URL发送请求,可以POST或GET形式,获得服务器响应
2 服务器响应的方式可以是xml格式,JSON 格式,如果使用的模板引擎还可以是JAVA对象。前端通过JS处理数据
3 也可以通过cookies的形式保存在客户端由前端通过JS解析
7、Jquery
jQuery 是一个 JavaScript 库,极大地简化了 JavaScript 编程。jQuery 很容易学习,以面向对象的形式进行操作,做为后端开发常用的方法有html(),append(),val(),click(),ready(),ajax(),get(),getJson()等等。
8、盒子模型
盒子模型,英文即box model。无论是div、span、还是a都是盒子。但是,图片、表单元素一律看作是文本,它们并不是盒子。这个很好理解,比如说,一张图片里并不能放东西,它自己就是自己的内容。盒子中的区域主要的属性就5个:width、height、padding、border、margin:
width和height:内容的宽度、高度(不是盒子的宽度、高度)。
padding:内边距。
border:边框。
margin:外边距。
9、锁的用法还有注意事项
一旦用到锁,就说明这是阻塞式的,所以在并发度上一般来说都会比无锁的情况低一点。因此需要注意锁的优化。锁优化,是指在阻塞式的情况下,如何让性能不要变得太差。但是再怎么优化,一般来说性能都会比无锁的情况差一点。
锁优化的思路和方法总结一下,有以下几种。
1.减少锁持有时间
只用在有线程安全要求的程序上加锁,减少其他线程等待的时间
2.减小锁粒度
将大对象(这个对象可能会被很多线程访问),拆成小对象,大大增加并行度,降低锁竞争。降低了锁的竞争,偏向锁,轻量级锁成功率才会提高。
3.锁分离
最常见的锁分离就是读写锁ReadWriteLock,根据功能进行分离成读锁和写锁,这样读读不互斥,读写互斥,写写互斥,即保证了线程安全,又提高了性能
4.锁粗化
通常情况下,为了保证多线程间的有效并发,会要求每个线程持有锁的时间尽量短,即在使用完公共资源后,应该立即释放锁。只有这样,等待在这个锁上的其他线程才能尽早的获得资源执行任务。但是,凡事都有一个度,如果对同一个锁不停的进行请求、同步和释放,其本身也会消耗系统宝贵的资源,反而不利于性能的优化
5.锁消除
锁消除是在编译器级别的事情。在即时编译器时,如果发现不可能被共享的对象,则可以消除这些对象的锁操作。
四、有赞面试题

1、redis常用命令:

1)连接操作命令
quit:关闭连接(connection)
auth:简单密码认证
help cmd:查看cmd帮助,例如:help quit
2)持久化
save:将数据同步保存到磁盘
bgsave:将数据异步保存到磁盘
lastsave:返回上次成功将数据保存到磁盘的Unix时戳
shundown:将数据同步保存到磁盘,然后关闭服务
3)远程服务控制
info:提供服务器的信息和统计
monitor:实时转储收到的请求
slaveof:改变复制策略设置
config:在运行时配置Redis服务器
4)对value操作的命令
exists(key):确认一个key是否存在
del(key):删除一个key
type(key):返回值的类型
keys(pattern):返回满足给定pattern的所有key
randomkey:随机返回key空间的一个
keyrename(oldname, newname):重命名key
dbsize:返回当前数据库中key的数目
expire:设定一个key的活动时间(s)
ttl:获得一个key的活动时间
select(index):按索引查询
move(key, dbindex):移动当前数据库中的key到dbindex数据库
flushdb:删除当前选择数据库中的所有key
flushall:删除所有数据库中的所有key
5)String
set(key, value):给数据库中名称为key的string赋予值value
get(key):返回数据库中名称为key的string的value
getset(key, value):给名称为key的string赋予上一次的value
mget(key1, key2,…, key N):返回库中多个string的value
setnx(key, value):添加string,名称为key,值为value
setex(key, time, value):向库中添加string,设定过期时间time
mset(key N, value N):批量设置多个string的值
msetnx(key N, value N):如果所有名称为key i的string都不存在
incr(key):名称为key的string增1操作
incrby(key, integer):名称为key的string增加integer
decr(key):名称为key的string减1操作
decrby(key, integer):名称为key的string减少integer
append(key, value):名称为key的string的值附加value
substr(key, start, end):返回名称为key的string的value的子串
6)List
rpush(key, value):在名称为key的list尾添加一个值为value的元素
lpush(key, value):在名称为key的list头添加一个值为value的元素
llen(key):返回名称为key的list的长度
lrange(key, start, end):返回名称为key的list中start至end之间的元素
ltrim(key, start, end):截取名称为key的list
lindex(key, index):返回名称为key的list中index位置的元素
lset(key, index, value):给名称为key的list中index位置的元素赋值
lrem(key, count, value):删除count个key的list中值为value的元素
lpop(key):返回并删除名称为key的list中的首元素
rpop(key):返回并删除名称为key的list中的尾元素
blpop(key1, key2,… key N, timeout):lpop命令的block版本。
brpop(key1, key2,… key N, timeout):rpop的block版本。
rpoplpush(srckey, dstkey):返回并删除名称为srckey的list的尾元素,并将该元素添加到名称为dstkey的list的头部
7)Set
sadd(key, member):向名称为key的set中添加元素member
srem(key, member) :删除名称为key的set中的元素member
spop(key) :随机返回并删除名称为key的set中一个元素
smove(srckey, dstkey, member) :移到集合元素
scard(key) :返回名称为key的set的基数
sismember(key, member) :member是否是名称为key的set的元素
sinter(key1, key2,…key N) :求交集
sinterstore(dstkey, (keys)) :求交集并将交集保存到dstkey的集合
sunion(key1, (keys)) :求并集
sunionstore(dstkey, (keys)) :求并集并将并集保存到dstkey的集合
sdiff(key1, (keys)) :求差集
sdiffstore(dstkey, (keys)) :求差集并将差集保存到dstkey的集合
smembers(key) :返回名称为key的set的所有元素
srandmember(key) :随机返回名称为key的set的一个元素
8)Hash
hset(key, field, value):向名称为key的hash中添加元素field
hget(key, field):返回名称为key的hash中field对应的value
hmget(key, (fields)):返回名称为key的hash中field i对应的value
hmset(key, (fields)):向名称为key的hash中添加元素field
hincrby(key, field, integer):将名称为key的hash中field的value增加integer
hexists(key, field):名称为key的hash中是否存在键为field的域
hdel(key, field):删除名称为key的hash中键为field的域
hlen(key):返回名称为key的hash中元素个数
hkeys(key):返回名称为key的hash中所有键
hvals(key):返回名称为key的hash中所有键对应的value
hgetall(key):返回名称为key的hash中所有的键(field)及其对应的value

2、你了解hashMap吗? 底层实现方式?线程安全吗?如何实现安全?CocurrentHashMap了解吗?

了解一点,HashMap的主干是一个Entry数组。Entry是HashMap的基本组成单元,每一个Entry包含一个key-value键值对。 HashMap中有一个静态内部类Entry。所以,HashMap的整体结构简单来说,HashMap由数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的,如果定位到的数组位置不含链表(当前entry的next指向null),那么对于查找,添加等操作很快,仅需一次寻址即可;如果定位到的数组包含链表,对于添加操作,其时间复杂度为O(n),首先遍历链表,存在即覆盖,否则新增;对于查找操作来讲,仍需遍历链表,然后通过key对象的equals方法逐一比对查找。所以,性能考虑,HashMap中的链表出现越少,性能才会越好。HashMap有4个构造器,其他构造器如果用户没有传入initialCapacity 和loadFactor这两个参数,会使用默认值。initialCapacity默认为16,loadFactory默认为0.75。是线程不安全的。如果需要安全就选择HashTable或者CocurrentHashMap,这两个都是安全的。

3、如何创建多线程?线程池的作用?

在JDK1.5之前,创建线程就只有两种方式,即继承java.lang.Thread类和实现java.lang.Runnable接口;而在JDK1.5以后,增加了两个创建线程的方式,即实现java.util.concurrent.Callable接口和线程池。
1继承Thread类
2实现Runnable接口
3实现Callable接口
相较于实现Runnable 接口的实现,方法可以有返回值,并且抛出异常。

4、线程池

线程池提供了一个线程队列,队列中保存着所有等待状态的线程。避免了创建与销毁额外开销,提高了响应速度。
java.util.concurrent.Executors提供了一个 java.util.concurrent.Executor接口的实现用于创建线程池,多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中执行任务的时间,T3 销毁线程时间。如果:T1 + T3 远大于 T2,则可以采用线程池,以提高服务器性能。
一个线程池包括以下四个基本组成部分:
1、 线程池管理器(ThreadPool):用于创建并管理线程池,包括创建线程池,销毁线程池,添加新任务;

2、 工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;

3、 任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;

4、任务队列(taskQueue):用于存放没有处理的任务。提供一种缓冲机制。
线程池技术正是关注如何缩短或调整T1,T3时间的技术,从而提高服务器程序性能的。它把T1,T3分别安排在服务器程序的启动和结束的时间段或者一些空闲的时间段,这样在服务器程序处理客户请求时,不会有T1,T3的开销了。线程池不仅调整T1,T3产生的时间段,而且它还显著减少了创建线程的数目。

5、 Object类的常用方法

Object类是一个特殊的类,是所有类的父类,如果一个类没有用extends明确指出继承于某个类,那么它默认继承Object类。Object类中的常用方法:
1.取得对象信息的方法:toString()
2.对象相等判断方法:equals()
3.对象签名:hashCode()
4.获得字节码对象方法:getClass();
5.等待方法:wait()
6.唤醒方法:notify()
7.唤醒所有其它方法:notifyAll()

五、海康威视面试题

1、Arraylist 调用方法注意事项

ArrayList实现了可变大小的数组。它允许所有元素,包括null。ArrayList没有同步。size(),isEmpty(),get(),set()方法运行时间为常数。但是add()方法开销为分摊的常数,添加n个元素需要O(n)的时间。其他的方法运行时间为线性。每个ArrayList实例都有一个容量(Capactity),即用于存储元素的数组的大小。这个容量可随着不断添加新元素而自动增加,但是增长算法并没有定义。当需要插入大量元素时,在插入之前可以调用ensureCapacity()方法来增加ArrayList容量已提高插入效率,

2、支付过程中断网怎么办

从单服务应用程序断网角度分析
1在用户还没输入密码之前:网络原因支付失败
2用户输入密码过程中:网络原因支付失败
3密码已经输入,第三方支付服务器已经接收到正确密码并且确认支付成功。这时,第三方支付服务器确认支付成功,通知应用程序,但应用程序断网,此时需要在连接后主动或手动读取第三方支付服务器的信息进行后续处理。
在分布式集群中的部署可以在其中某台主机断网时匹配集群中其它应用进行处理。但很多时候,一个请求,会调用很多service服务,如果service之间是串行的话,那么一个service超时,很可能会引起连锁反应,所以在调用别的接口的时候(不管是第三方支付接口,还是分布式接口),都需要加一个超时时间,超过这个时间,就不在等待了,视作失败,或者处理中,然后再后续处理。

3、一个项目如何支持两个数据库通用,修改哪些部分的代码

mybatis框架3.1以上版本支持多数据库兼容操作,只要修改spring的数据源配置代码或者或者mybatis的databaseIdProvider 节点和mapper映射文件代码,项目中以一种数据库为主, 如MySQL为主, Oracle则是某些模块使用, 即写mapper的xml时, 一般都直接不写databaseId, 唯有Oracle那个模块才写上 databaseId=”oracle” . 而另一种情况则是, 整个项目都需要兼容, 那修改量就相对大一些, 需要2个statement分别标明不同的databaseId.

4、Hibernate 和mybstis 差异性

myBatis加载的字段很干净,没有太多多余的字段,直接映射入关联中。而hibernate则将整个表的字都会加载到对象中,其中还包括关联的user字段。hibernate这种情况下有好有坏,要看具体的场景,对于管理平台,需要展现的信息较多,并发要求不高时,hibernate比较有优势。然而在一些小活动,互联网网站,高并发情况下,hibernate的方案太不太适合,myBatis+VO则是首选。总体初观,myBatis在所有情况下,特别是插入与单表查询,都会微微优于hibernate。不过差异情况并不明显,可以基本忽略差异。差异比较大的是关联查询时,hibernate为了保证POJO的数据完整性,需要将关联的数据加载,需要额外地查询更多的数据。这里hibernate并没有提供相应的灵活性。关联时一个差异比较大的地方则是懒加载特性。其中hibernate可以特别地利用POJO完整性来进行缓存,可以在一级与二级缓存上保存对象,如果对单一个对象查询比较多的话,会有很明显的性能效益。以后关于单对象关联时,可以通过懒加载加二级缓存的方式来提升性能。最后,数据查询的性能与orm框架关无太大的关系,因为orm主要帮助开发人员将关系数据转化成对象型数据模型,对代码的深析上来看,hibernate设计得比较重量级,对开发来说可以算是重新开发了一个数据库,不让开发去过多关心数据库的特性,直接在hibernate基础上进行开发,执行上分为了sql生成,数据封装等过程,这里花了大量的时间。然而myBatis则比直接,主要是做关联与输出字段之间的一个映射。其中sql基本是已经写好,直接做替换则可,不需要像hibernate那样去动态生成整条sql语句。myBatis相对Hibernate 等封装较为严密的ORM 实现而言,因为hibernate对数据对象的操作实现了较为严密的封装,可以保证其作用范围内的缓存同步,而ibatis 提供的是半封闭的封装实现,因此对缓存的操作难以做到完全的自动化同步。以上的缓存配置测试仅为性能上的分析,没有加入可用性上的情况,因为myBatis直接配置缓存的话,可能会出现脏数据,。在关联查询数据的情况下,hiberntae的懒加载配二级缓存是个比较好的方案(无脏数据),也是与myBatis相比有比较明显的优势。此情景下,性能与myBatis持平。在真实情况下,myBatis可能不会在这个地方上配置缓存,会出现脏数据的情况,因而很有可能在此hibernate性能会更好。

5、Spring内部实现机制

Spring 从创建到销毁bean,
1.ResourceLoader 加载配置文件
2.BeanDefinitionReader 解析配置文件,并将其注册到BeanDefinitonRegistry中,此时的beanDefinition是半成品,因为此时还无法对占位符进行解析
3.BeanFactoryPostProcessor从beanDefinitionRegistry中进行进一步加工(解析占位符),并且将实现了PropertyEditor接口的bean注册到PropertyEditorRegistry中
4.通过InstantiationStrategy 和BeanWrapper 完成bean的实例化,并进行属性的注入
5.通过BeanPostProcessor对bean进行进一步加工一个完整的bean就诞生

6、Ioc和aop底层如何实现

1.IoC(Inversion of Control)
(1). IoC(Inversion of Control)是指容器控制程序对象之间的关系,而不是传统实现中,由程序代码直接操控。控制权由应用代码中转到了外部容器,控制权的转移是所谓反转。对于Spring而言,就是由Spring来控制对象的生命周期和对象之间的关系;IoC还有另外一个名字——“依赖注入(Dependency Injection)”。从名字上理解,所谓依赖注入,即组件之间的依赖关系由容器在运行期决定,即由容器动态地将某种依赖关系注入到组件之中。
(2). 在Spring的工作方式中,所有的类都会在spring容器中登记,告诉spring这是个什么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。
(3). 在系统运行中,动态的向某个对象提供它所需要的其他对象。
(4). 依赖注入的思想是通过反射机制实现的,在实例化一个类时,它通过反射调用类中set方法将事先保存在HashMap中的类属性注入到类中。总而言之,在传统的对象创建方式中,通常由调用者来创建被调用者的实例,而在Spring中创建被调用者的工作由Spring来完成,然后注入调用者,即所谓的依赖注入or控制反转。注入方式有两种:依赖注入和设置注入; IoC的优点:降低了组件之间的耦合,降低了业务对象之间替换的复杂性,使之能够灵活的管理对象。
2.AOP(Aspect Oriented Programming)
(1). AOP面向方面编程基于IoC,是对OOP的有益补充;
(2). AOP利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,比如日志记录,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。
(3). AOP代表的是一个横向的关系,将“对象”比作一个空心的圆柱体,其中封装的是对象的属性和行为;则面向方面编程的方法,就是将这个圆柱体以切面形式剖开,选择性的提供业务逻辑。而剖开的切面,也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹,但完成了效果。
(4). 实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。
(5). Spring实现AOP:JDK动态代理和CGLIB代理 JDK动态代理:其代理对象必须是某个接口的实现,它是通过在运行期间创建一个接口的实现类来完成对目标对象的代理;其核心的两个类是InvocationHandler和Proxy。 CGLIB代理:实现原理类似于JDK动态代理,只是它在运行期间生成的代理对象是针对目标类扩展的子类。CGLIB是高效的代码生成包,底层是依靠ASM(开源的java字节码编辑类库)操作字节码实现的,性能比JDK强;需要引入包asm.jar和cglib.jar。使用AspectJ注入式切面和@AspectJ注解驱动的切面实际上底层也是通过动态代理实现的。

7、注解开发代码怎么写的,问注解里面是怎么实现的?

注解的定义通过@interface符号,注解中有属性,可以设置默认值,value是特殊属性,可以在单个赋值省略。注解是用来取代配置文件的的,通过反射获取注解属性后进行操作。

8、JQuery 和ext的区别

JQuery是现在世界上使用最多的javascript库。是对JS的封装,很多前端框架是基于jQuery实现的比如,EasyUI,LayUI等,是免费的。而Ext是一套富客户端(rich client)框架,源自Yahoo UI社区。EXT完全基于JavaScript、css和HTML实现,与主流浏览器完全兼容,并且无需安装任何插件即可在常用浏览器中创建出绚丽的页面效果。商业收费版本功能更为强大。是重量级的前端框架。说的更通俗一点就是:Jquery是一款轻量级的js库,适用于前台web动态页面的设计,而ExtJS则是一款重量级的富客户端js库,更适用于类似后台管理页面的那种动态页面效果的设计。

9、Ext 能实现哪些jQuery 实现不了的

Jquery适合小型灵活的web应用,比如新闻发布系统动态页面设计,门户网站动态页面设计,SNS动态页面等web系统设计;特点是使用简单明了,可以简单快捷的实现某个效果,比如为了实现某一个动态特效,我们可以迅速定位到使用jquery的某一技术或者找到相应的插件来实现。Jquery的设计理念就是写最少的代码实现更多的功能。缺点是插件缺乏统一的管理,用户往往为了实现某一个特效而苦苦纠结与css,还有js的效果逻辑。
而Ext则提供了丰富的完整的一套UI组件,以及组件对应的CSS包(这里强调一下,是一套),就必须深入理解ext的中心思想,理解组件之间嵌套后的关系,以及理解ext生成DOM对象的顺序。特点是功能提供全,使得开发者解放于界面设计,更多的工作去实现业务逻辑方面的事情,缺点是要想灵活运用有一定的难度,尤其是当遇到Ext的Bug的时候。ExtJS适用于那些富客户端应用:比如OA系统,ERP系统,MIS系统等富客户端应用的动态页面设计。

10、Ioc通过一个注解实现依赖注入,里面代码是怎么实现的?

五步:1通过读取配置文件bean节点信息获取class
2 反射创建对象信息
3 获取字节码中的私有字段或者公有属性
4判断是否有指定注解类型
5 有指定就反射赋值

11、前端向后端可以发请求,后端怎么向前端抛消息?

看起来响应的方式有很多,但本质上只有流的形式传输,比如文件下载,XML数据响应,JSON数据,由前端JS解析数据,如果是java中还可以传输对象数据给模板引擎,由模板引擎解析数据。

六、昆山妈妈好面试题

1、线程的启动停止,如何同步

线程的启动是通过start()方法,区别与run(),停止线程的方式有四种:
1 使用stop方法强行终止,但是不推荐这个方法,因为stop()和suspend()及resume()一样都是过期作废的方法。
2 使用interrupt方法中断线程。
3 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止
4 wait(),sleep()暂时停止线程

2、保证线程同步的方式可以通过以下7种方式:

1.同步方法
即有synchronized关键字修饰的方法。
由于java的每个对象都有一个内置锁,当用此关键字修饰方法时,
内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。注: synchronized关键字也可以修饰静态方法,此时如果调用该静态方法,将会锁住整个类
2.同步代码块
即有synchronized关键字修饰的语句块。
被该关键字修饰的语句块会自动被加上内置锁,从而实现同步
注:同步是一种高开销的操作,因此应该尽量减少同步的内容。
通常没必要同步整个方法,使用synchronized代码块同步关键代码即可。
3.使用特殊域变量(volatile)实现线程同步
a.volatile关键字为域变量的访问提供了一种免锁机制,
b.使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新,
c.因此每次使用该域就要重新计算,而不是使用寄存器中的值
d.volatile不会提供任何原子操作,它不能用来修饰final类型的变量
4.使用重入锁实现线程同步
在JavaSE5.0中新增了一个java.util.concurrent包来支持同步。ReentrantLock类是可重入、互斥、实现了Lock接口的锁,
它与使用synchronized方法和快具有相同的基本行为和语义,并且扩展了其能力
5.使用局部变量实现线程同步
如果使用ThreadLocal管理变量,则每一个使用该变量的线程都获得该变量的副本,副本之间相互独立,这样每一个线程都可以随意修改自己的变量副本,而不会对其他线程产生影响。
6.使用阻塞队列实现线程同步
前面5种同步方式都是在底层实现的线程同步,但是我们在实际开发当中,应当尽量远离底层结构。使用javaSE5.0版本中新增的java.util.concurrent包的LinkedBlockingQueue来实现线程的同步将有助于简化开发。
7.使用原子变量实现线程同步
需要使用线程同步的根本原因在于对普通变量的操作不是原子的。

3、springmvc的请求流程

第一步:发起请求到前端控制器(DispatcherServlet)
第二步:前端控制器请求HandlerMapping查找 Handler (可以根据xml配置、注解进行查找)
第三步:处理器映射器HandlerMapping向前端控制器返回Handler,HandlerMapping会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象,多个HandlerInterceptor拦截器对象),通过这种策略模式,很容易添加新的映射策略
第四步:前端控制器调用处理器适配器去执行Handler
第五步:处理器适配器HandlerAdapter将会根据适配的结果去执行Handler
第六步:Handler执行完成给适配器返回ModelAndView
第七步:处理器适配器向前端控制器返回ModelAndView (ModelAndView是springmvc框架的一个底层对象,包括 Model和view)
第八步:前端控制器请求视图解析器去进行视图解析(根据逻辑视图名解析成真正的视图(jsp)),通过这种策略很容易更换其他视图技术,只需要更改视图解析器即可
第九步:视图解析器向前端控制器返回View
第十步:前端控制器进行视图渲染(视图渲染将模型数据(在ModelAndView对象中)填充到request域)
第十一步:前端控制器向用户响应结果

4、前端是否使用静态页面

是的,因为使用静态页面会提高响应的速度,为实现前后端的分离提供可能性。

5、前端框架

VUE,React,Bootstrap,Jquery,JqueryEasyUI,Ext等

6、springboot介绍

springboot是纯以注解开发的,配置文件默认application.properties/yml,
Spring Boot作为微服务的入门级微框架,有四点好处

Spring Boot使编码变简单

Spring Boot使配置变简单

Spring Boot使部署变简单

Spring Boot使监控变简单

7、web.xml的作用

web.xml文件是用来初始化配置信息:比如Welcome页面、servlet、servlet-mapping、filter、listener、启动加载级别等。当web工程没用到这些时,可以不用web.xml文件来配置的Application。也可以使用注解取代。每个xml文件都有定义它书写规则的Schema文件,也就是说javaEE的定义web.xml所对应的xml Schema文件中定义了多少种标签元素,web.xml中就可以出现它所定义的标签元素,也就具备哪些特定的功能。web.xml的模式文件是由Sun 公司定义的,每个web.xml文件的根元素为中,必须标明这个web.xml使用的是哪个模式文件。
web.xml的模式文件中定义的标签并不是定死的,模式文件也是可以改变的,一般来说,随着web.mxl模式文件的版本升级,里面定义的功能会越来越复杂,标签元素的种类肯定也会越来越多。

8、线程在非同步方法的停止方法

停止线程的方式有四种:
1 使用stop方法强行终止,但是不推荐这个方法,因为stop()和suspend()及resume()一样都是过期作废的方法。
2 使用interrupt方法中断线程。
3 使用thread.interrupt退出标志,使线程正常退出,也就是当run方法完成后线程终止
4 wait(),sleep()暂时停止线程

8、过滤器的作用

过滤器就是可以对浏览器向控制器资源发出请求和服务器回应给浏览器的内容进行过滤。这个过滤过程中可以拦截浏览器发出的请求和服务器回应给浏览器的内容。拦截之后,就可以进行查看,并且可以对拦截内容进行提取,或者进行修改。过滤器拦截请求和响应,以便查看,提取或操作客户机和服务器之间交换数据。

9、cloud

云是什么?通常云计算。云计算是分布式处、并行处理和网格计算的发展。云是云技术的意思,是分布式计算技术的一种,云技术(Cloud technology)是基于云计算商业模式应用的网络技术、信息技术、整合技术、管理平台技术、应用技术等的总称,可以组成资源池,按需所用,灵活便利。
云技术最基本的概念,是透过网络将庞大的计算处理程序自动分拆成无数个较小的子程序,再交由多部服务器所组成的庞大系统经搜寻、计算分析之后将处理结果回传给用户。透过这项技术,网络服务提供者可以在数秒之内,达成处理数以千万计甚至亿计的信息,达到和“超级计算机”同样强大效能的网络服务。
云计算技术体系结构分为4层:物理资源层、资源池层、管理中间件层和SOA构建层,如图所示。物理资源层包括计算机、存储器、网络设施、数据库和软件等。

10、数据库读写分离的实现

随着用户量的增多,数据库操作往往会成为一个系统的瓶颈所在,而且一般的系统“读”的压力远远大于“写”,因此我们可以通过实现数据库的读写分离来提高系统的性能。实现思路
通过设置主从数据库实现读写分离,主数据库负责“写操作”,从数据库负责“读操作”,根据压力情况,从数据库可以部署多个提高“读”的速度,借此来提高系统总体的性能。
要实现读写分离,就要解决主从数据库数据同步的问题,在主数据库写入数据后要保证从数据库的数据也要更新。

11、主从数据库同步的实现思路:

主服务器master记录数据库操作日志到Binary log,从服务器开启i/o线程将二进制日志记录的操作同步到relay log(存在从服务器的缓存中),另外sql线程将relay log日志记录的操作在从服务器执行。
主从数据库设置的具体步骤
首先要有两个数据库服务器配置主从关系master、slave(也可以用一个服务器安装两套数据库环境运行在不同端口,slave也可以举一反三设置多个) ,接下来的问题就是在业务代码里面实现读写分离,在配置文件配置两个具体的数据源master、slave,继承了abstractDataSource,这里面就配置了数据库连接的具体属性,然后配置了动态数据源,他将决定使用哪个具体的数据源,这里面的关键就是DataSourceSelector,接下来实现这个bean。下一步设置了数据源的懒加载,保证在数据源加载的时候其他依赖的bean已经加载完成。

七、支付宝蚂蚁金服

1、String Stringbuffer Stringbuilder

String类被final修饰,所以不可继承,String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且浪费大量优先的内存空间;
StringBuffer是可变类和线程安全的字符串操作类,任何对它指向的字符串的操作都不会产生新的对象。每个StringBuffer对象都有一定的缓冲区容量,当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自动增加容量,用于多线程操作字符串
StringBuilder是可变类和线程不安全的字符串操作类,任何对它指向的字符串的操作都不会产生新的对象。每个StringBuffer对象都有一定的缓冲区容量,当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自动增加容量,用于单线程操作字符串

2、Dubbox工作原理

通过配置中心,和每个Server/Client之间会作一个实时的心跳检测(因为它们都是建立的Socket长连接),比如几秒钟检测一次。收集每个Server提供的服务的信息,每个Client的信息,整理出一个服务列表,当某个Server不可用,那么就更新受影响的服务对应的serverAddressList,即把这个Server从serverAddressList中踢出去(从地址列表中删除),同时将推送serverAddressList给这些受影响的服务的clientAddressList里面的所有Client。如:192.168.0.3挂了,那么UserService和ProductService的serverAddressList都要把192.168.0.3删除掉,同时把新的列表告诉对应的Client,当某个Client挂了,那么更新受影响的服务对应的clientAddressLis,ConfigServer根据服务列表,就能提供一个web管理界面,来查看管理服务的提供者和使用者。新加一个Server时,由于它会主动与ConfigServer取得联系,而ConfigServer又会将这个信息主动发送给Client,所以新加一个Server时,只需要启动Server,然后几秒钟内,Client就会使用上它提供的服务Client调用服务的机器,每个Client启动时,主动与ConfigServer建立Socket长连接,并将自己的IP等相应信息发送给ConfigServer。Client在使用服务的时候根据服务名称去ConfigServer中获取服务提供者信息(这样ConfigServer就知道某个服务是当前哪几个Client在使用),Client拿到这些服务提供者信息后,与它们都建立连接,后面就可以直接调用服务了,当有多个服务提供者的时候,Client根据一定的规则来进行负载均衡,如轮询,随机,按权重等。一旦Client使用的服务它对应的服务提供者有变化(服务提供者有新增,删除的情况),ConfigServer就会把最新的服务提供者列表推送给Client,Client就会依据最新的服务提供者列表重新建立连接,新增的提供者建立连接,删除的提供者丢弃连接,Server真正提供服务的机器,每个Server启动时,主动与ConfigServer建立Scoket长连接,并将自己的IP,提供的服务名称,端口等信息直接发送给ConfigServer,ConfigServer就会收集到每个Server提供的服务的信息。

3、Nginx网段配置

通过nginx模块ngx_http_access_module的指令deny和allow控制某个uri或者一个路径不让人访问。这个模块内置在了nginx中,nginx的访问控制模块语法很简单,
allow
语法: allow address | CIDR | unix: | all;
默认值: —
配置段: http, server, location, limit_except
允许某个ip或者一个ip段访问.如果指定unix:,那将允许socket的访问.注意:unix在1.5.1中新加入的功能,如果你的版本比这个低,请不要使用这个方法。
deny
语法: deny address | CIDR | unix: | all;
默认值: —
配置段: http, server, location, limit_except
禁止某个ip或者一个ip段访问.如果指定unix:,那将禁止socket的访问.注意:unix在1.5.1中新加入的功能,如果版本比这个低,请不要使用这个方法。

4、数据表索引的必要性

索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存。如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录。表里面的记录数量越多,这个操作的代价就越高。如果作为搜索条件的列上已经创建了索引,MySQL无需扫描任何记录即可迅速得到目标记录所在的位置。如果表有1000个记录,通过索引查找记录至少要比顺序扫描记录快100倍。
索引是对数据库表中一个或多个列(例如,employee表的姓氏(lname)列)的值进行排序的结构。如果想按特定职员的姓来查找他或她,则与在表中搜索所有的行相比,索引有助于更快地获取信息。
索引提供指针以指向存储在表中指定列的数据值,然后根据指定的排序次序排列这些指针。数据库使用索引的方式与使用书的目录很相似:通过搜索索引找到特定的值,然后跟随指针到达包含该值的行。
在数据库关系图中,可以为选定的表创建、编辑或删除索引/键属性页中的每个索引类型。当保存附加在此索引上的表或包含此表的数据库关系图时,索引同时被保存。
通常情况下,只有当经常查询索引列中的数据时,才需要创建索引。索引将占用磁盘空间,并且降低添加、删除和更新行的速度。不过在多数情况下,索引所带来的数据检索速度的优势大大超过它的不足之处。然而,如果应用程序非常频繁地更新数据,或磁盘空间有限,那么最好限制索引的数量。

5、分布式不使用redis和cookie和session怎么多服务器共享用户登录状态

分布式下无法使用cookiea实现多服务器共享用户登录状态,因此分布式环境下需要一种全新的登录方式来实现多系统应用群的登录,这就是单点登录。单点登录全称Single Sign On(以下简称SSO),是指在多系统应用群中登录一个系统,便可在其他所有系统中得到授权而无需再次登录,包括单点登录与单点注销两部分,相比于单系统登录,sso需要一个独立的认证中心,只有认证中心能接受用户的用户名密码等安全信息,其他系统不提供登录入口,只接受认证中心的间接授权。间接授权通过令牌实现,sso认证中心验证用户的用户名密码没问题,创建授权令牌,在接下来的跳转过程中,授权令牌作为参数发送给各个子系统,子系统拿到令牌,即得到了授权,可以借此创建局部会话,局部会话登录方式与单系统的登录方式相同。这个过程,也就是单点登录的原理。

6、数据库存储模式

数据库系统采用三级模式结构,这是数据库管理系统内部的系统结构。
数据库系统设计员可在视图层、逻辑层和物理层对数据抽象,通过外模式、概念模式和内模式来描述不同层次上的数据特性。概念模式也称模式,是数据库中全部数据的逻辑结构和特征的描述,它由若干个概念记录类型组成,只涉及行的描述,不涉及具体的值。概念模式的一个具体值称为模式的一个实例,同一个模式可以有很多实例。
概念模式反映的是数据库的结构及其联系,所以是相对稳定的;而实例反映的是数据库某一时刻的状态,所以是相对变动的。
需要说明的是,概念模式不仅要描述概念记录类型,还要描述记录间的联系、操作、数据的完整性和安全性等要求。但是,概念模式不涉及存储结构、访问技术等细节。只有这样,概念模式才算做到了“物理数据独立性”。
描述概念模式的数据定义语言称为“模式DDL”
外模式也称用户模式或子模式,是用户与数据库系统的接口,是用户用到的那部分数据的描述。它由若干个外部记录类型组成。用户使用数据操纵语言对数据库进行操作,实际上是对外模式的外部记录进行操作。
描述外模式的数据定义语言称为“外模式DDL”。有了外模式后,程序员不必关心概念模式,只与外模式发生联系,按外模式的结构存储和操作数据。
内模式也称为存储模式,是数据物理结构和存储方式的描述,是数据在数据库内部的表示方式。需要定义所以的内部记录类型、索引和文件的组织方式,以及数据控制方面的细节。
例如,记录的存储方式是顺序存储、B树结构存储还是Hash方法存储;索引按照什么方式组织;数据是否压缩存储,是否加密;数据的存储记录结构有何规定。
需要说明的是,内部记录并不涉及物理记录,也不涉及设备的约束。比内模式更接近于物理存储和访问的那些软件机制是操作系统的一部分(即文件系统)。例如,从磁盘上读、写数据。
描述内模式的数据定义语言称为“内模式DDL”。
总之,数据按外模式的描述提供给用户;按内模式的描述存储在磁盘上;而概念模式提供了连接这两级模式的相对稳定的中间层,并使得两级中任意一级的改变都不受另一级的牵制。
数据库系统在三级模式之间提供了两级映像:模式/内模式的映像、外模式/模式的映像。这两级映射保证了数据库中的数据具有较高的物理独立性和逻辑独立性。

7、InnoDB是哪种读取类型

InnoDB给MySQL的表提供了事务处理、回滚、崩溃修复能力和多版本并发控制的事务安全。在MySQL从3.23.34a开始包含InnnoDB。它是MySQL上第一个提供外键约束的表引擎。而且InnoDB对事务处理的能力,也是其他存储引擎不能比拟的。靠后版本的MySQL的默认存储引擎就是InnoDB。
InnoDB的优势在于提供了良好的事务处理、崩溃修复能力和并发控制。缺点是读写效率较差,占用的数据空间相对较大。

8、数据库中事务锁

事务和锁的存在都是为了更好的解决并发访问造成的数据不一致性的的问题乐观锁和悲观锁都是为了解决并发控制问题,乐观锁可以认为是一种在最后提交的时候检测冲突的手段,而悲观锁则是一种避免冲突的手段。乐观锁:是应用系统层面和数据的业务逻辑层次上的(实际上并没有加锁,只不过大家一直这样叫而已),利用程序处理并发,它假定当某一个用户去读取某一个数据的时候,其他的用户不会来访问修改这个数据,但是在最后进行事务的提交的时候会进行版本的检查,以判断在该用户的操作过程中,没有其他用户修改了这个数据。开销比较小乐观锁的实现大部分都是基于版本控制实现的,除此之外,还可以通过时间戳的方式,通过提前读取,事后对比的方式实现

9、乐观锁的优势和劣势

优势:如果数据库记录始终处于悲观锁加锁状态,可以想见,如果面对几百上千个并发,那么要不断的加锁减锁,而且用户等待的时间会非常的长,乐观锁机制避免了长事务中的数据库加锁解锁开销,大大提升了大并发量下的系统整体性能表现所以如果系统的并发非常大的话,悲观锁定会带来非常大的性能问题,所以建议就要选择乐观锁定的方法,而如果并发量不大,完全可以使用悲观锁定的方法。乐观锁也适合于读比较多的场景。
劣势:但是乐观锁也存在着问题,只能在提交数据时才发现业务事务将要失败,如果系统的冲突非常的多,而且一旦冲突就要因为重新计算提交而造成较大的代价的话,乐观锁也会带来很大的问题,在某些情况下,发现失败太迟的代价会非常的大。而且乐观锁也无法解决脏读的问题
10、互联网高并发小轻快如何实现
不是很清楚,能跟我说说吗?拆分业务使用微服架构变小?使用成熟框架变轻?使用各种优化提高性能变快?

11、数据库优化

随着系统规模的不断增加,数据量和并发量不断增大,整个系统架构中最先受到冲击而形成瓶颈的,定然是数据库,因此数据库层面的优化,是一个程序员不可或缺的技能,下面就是一些优化方式:
1、索引,建立索引是数据库优化各种方案之中成本最低,见效最快的解决方案,一般来讲,数据库规模在几十万和几百万级别的时候见效最快,即便是有不太复杂的表关联,也能大幅度提高sql的运行效率,这个在我们以前的项目应用中,有非常深刻的体会,本来耗时50s的sql,在增加索引后可以提升到1-2s,而且不需要有代码改动,成本低廉,见效明显
2、分库分表分区
分库,可以按照业务分库,分流数据库并发压力,使数据库表更加有条理性,最起码更加好找吧,我们当时是把查询库和系统库(增删改比较频繁的表)分开了,这样如果有大查询,不影响系统库
分表,刚才说了,索引适合应对百万级别的数据量,千万级别数据量使用的好,勉强也能凑合,但如果是上亿级别的数据量,索引就无能为力了,因为单索引文件可能就已经上百兆或者更多了,那么,轮到我们的分表分区登场了
分区
分区的实现道理和分表一样,也是将相应规则的数据放在一起,唯一不同的是分区你只需要设定好分区规则,插入的数据会被自动插入到指定的区里,当然查询的时候也能很快查询到需要区,相当于是分表对外透明了,出现跨表数据库自动帮我们合并做了处理,使用起来比分表更加方便,但是分区也有自己的问题,每一个数据库表的并发访问是有上限的,也就是说,分表能够抗高并发,而分区不能,如何选择,要考虑实际情况

八、公司笔试题

1、多线程Hashmap死循环的操作是由于哪一步

HashMap是采用链表解决Hash冲突,因为是链表结构,那么就很容易形成闭合的链路,这样在循环的时候只要有线程对这个HashMap进行get操作就会产生死循环。 在单线程情况下,只有一个线程对HashMap的数据结构进行操作,是不可能产生闭合的回路的。那就只有在多线程并发的情况下才会出现这种情况,那就是在put操作的时候,如果size>initialCapacity*loadFactor,那么这时候HashMap就会进行rehash操作,随之HashMap的结构就会发生翻天覆地的变化。很有可能就是在两个线程在这个时候同时触发了rehash操作,产生了闭合的回路。

2、讲述一下Hashmap的实现原理

HashMap的工作原理:HashMap是基于散列法(又称哈希法hashing)的原理,使用put(key, value)存储对象到HashMap中,使用get(key)从HashMap中获取对象。当我们给put()方法传递键和值时,我们先对键调用hashCode()方法,返回的hashCode用于找到bucket(桶)位置来储存Entry对象。”HashMap是在bucket中储存键对象和值对象,作为Map.Entry。并不是仅仅只在bucket中存储值。

3、List的实现类有哪些

1、ArrayList非线程安全 基于对象数组
get(int index)不需要遍历数组,速度快;
iterator()方法中调用了get(int index),所以速度也快
set(int index, E e)不需要遍历数组,速度快
add方法需要考虑扩容与数组复制问题,速度慢
remove(Object o)需要遍历数组,并复制数组元素,速度慢
remove(int index)不需要遍历数组,需要复制数组元素,但不常用
contain(E)需要遍历数组

2、LinkedList 非线程安全 基于环形双向链表

get(int index)需要遍历链表,速度慢;
iterator()方法中调用了get(int index),所以速度也慢
set(int index, E e)方法中调用了get(int index),所以速度也慢
add方法不需要考虑扩容与数组复制问题,只需创建新对象,再将新对象的前后节点的指针指向重新分配一下就好,速度快
remove(Object o)需要遍历链表,但不需要复制元素,只需将所要删除的对象的前后节点的指针指向重新分配一下以及将所要删除的对象的三个属性置空即可,速度快
remove(int index)需要遍历链表,但不需要复制元素,只需将所要删除的对象的前后节点的指针指向重新分配一下以及将所要删除的对象的三个属性置空即可,但不常用
contain(E)需要遍历链表
3、Vector(线程安全的ArrayList)
扩容机制与ArrayList不同
4、Stack(继承于Vector)线程安全
效率低下,可采用双端队列Deque或LinkedList来实现,Deque用的较多

Redis有哪些数据类型
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
消息队列是如何进行消费的
JMS规范目前支持两种消息模型:点对点(point to point, queue)和发布/订阅(publish/subscribe,topic)在点对点模式中,消息生产者生产消息发送到queue中,然后消息消费者从queue中取出并且消费消息。消息被消费以后,queue中不再有存储,所以消息消费者不可能消费到已经被消费的消息。Queue支持存在多个消费者,但是对一个消息而言,只会有一个消费者可以消费。

4、微信支付宝银联的接入流程

使用Dobbox开发如何提供http协议的接口
Springboot如何用最简单的方法读其它的配置文件
使用注解@PropertySource@Value
Dobbox如何优化
先查看资源使用有没有出现瓶颈的地方。根据监控信息显示从以下几个方面来分析问题。
•整体环境
•CPU:
•内存:
•网络:
•线上网络利用率
•程序环境

5、Maven的操作命令你知道的有哪些

七大常用,三大生命周期,clean,compile,test,package,site,install,deploy

6、谈谈高并发的测试

通过Apache的JMetty高并发测试软件工具实现测试

7、你知道哪些算法

1.快速排序算法
归并排序(Merge sort,台湾译作:合并排序)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
二分查找算法是一种在有序数组中查找某一特定元素的搜索算法。搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。折半搜索每次把搜索区域减少一半,时间复杂度为Ο(logn) 。
BFPRT算法解决的问题十分经典,即从某n个元素的序列中选出第k大(第k小)的元素,通过巧妙的分析,BFPRT可以保证在最坏情况下仍为线性时间复杂度。该算法的思想与快速排序思想相似。
2.深度优先搜索算法(Depth-First-Search),是搜索算法的一种。
广度优先搜索算法(Breadth-First-Search),是一种图形搜索算法。简单的说,BFS是从根节点开始,沿着树(图)的宽度遍历树(图)的节点。如果所有节点均被访问,则算法中止。BFS同样属于盲目搜索。一般用队列数据结构来辅助实现BFS算法。
戴克斯特拉算法(Dijkstra’s algorithm)是由荷兰计算机科学家艾兹赫尔·戴克斯特拉提出。迪科斯彻算法使用了广度优先搜索解决非负权有向图的单源最短路径问题,算法最终得到一个最短路径树。该算法常用于路由算法或者作为其他图算法的一个子模块。
2.动态规划算法
朴素贝叶斯分类算法
使用的ORM框架有什么
hibernate全自动化ORM,ibatis,Mybatis半自动化ORM,Jfinal等

8、Mybatis分页插件有了解吗

有,PageHelper实现了通用的分页查询,其支持的数据有,mysql、Oracle、DB2、PostgreSQL等主流的数据库

9、全局异常怎么实现

springMVC中配置全局异常解析器SimpleMappingExceptionResolver即可对所有异常进行统一处理。

10、进行抢购时你们redis的键是怎么设计的

用设备来源拼接用户信息拼接商品主键拼接随机串,比如pc-2ad67f912a7a87a-1-adf5da5,用来存储用户信息和商品信息保证唯一性

  • 3
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值