JAVA:
1.哈希表为数组加链表结构,把hashcode放入数组初始化的16个“桶”中,当链表超过8位时转变为红黑树,提高查询效率,map也是数组加链表结构,先通过key的hashcode找到数组的index,再通过key的equals再链表中得到value。
2.hashset中使用add方法时,会根据equals和hashcode判断元素是否相同,所以在使用hashset存储元素时需要重写hashcode和equals方法来保证元素唯一性。
3.new String(“a”)中做了2步操作:在堆中new一个新对象,把地址给栈里的元素,并在常量池中建立此string,方便下次调用。
java集合排序
实现comprable接口,重写compareTo方法.用collection调用
或者传new Comparator()重写
4.hashcode不同,2个元素肯定不相同,hashcode相同,再判断equals是否相同。
5.对于Map里面的键和值是否可以为空的问题,答案是:不一定。对于HashMap来说,可以存放null键和null值,而HashTable则不可以。HashTable是线程安全,方法上添加了synchronized同步修饰,HashMap非线程安全
Collections.synchronizedSet(Sets.newHashSet())是set的安全集合
6.编译行异常必须处理,运行时异常可处理可不处理。
7.子类重写父类方法时抛出的异常必须比父类的少。
8. 自定义异常解析:
public class BizException extends Exception {
// 定义版本id
private static final long serialVersionUID = 1L;
// 异常id
private String exceptionID = "";
// 错误代码
private String errorCode = "";
// 异常等级枚举类
private ExceptionLevel exceptionLevel;
// 内部异常
private Exception innerException;
// 跟踪id
private String trackID;
// 方法
private String method;
// 应用名
private String applicationName;
// 服务id
private String serviceID;
public String getTrackID() {
return this.trackID;
}
public String getMethod() {
return this.method;
}
// 得到栈追踪信息
public String getStackTraceString() {
String s = "";
StringWriter sw = new StringWriter();
this.printStackTrace(new PrintWriter(sw));
s = sw.toString().replaceFirst(this.getMessage(), "[" this.errorCode "]" this.getMessage());
if (this.innerException != null) {
if (this.innerException.getClass().equals(SysException.class)) {
s = s ((SysException)this.innerException).getStackTraceString();
} else {
sw = new StringWriter();
this.innerException.printStackTrace(new PrintWriter(sw));
s = s sw.toString();
}
}
return s;
}
public String getExceptionID() {
return this.exceptionID;
}
public String getErrorCode() {
return this.errorCode;
}
protected void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
public Exception getInnerException() {
return this.innerException;
}
public String getApplicationName() {
return this.applicationName;
}
public String getServiceID() {
return this.serviceID;
}
public ExceptionLevel getExceptionLevel() {
return this.exceptionLevel;
}
public BizException(String trackID, String method, ExceptionLevel exceptionLevel, Exception e, String message, String... paras) {
super(message);
this.exceptionLevel = ExceptionLevel.Error;
this.innerException = null;
this.trackID = "";
this.method = "";
this.applicationName = "";
this.serviceID = "";
this.exceptionID = KeyIDFactory.INSTANCE.NewKeyID("LogDB", "LogException");
this.errorCode = this.errorCode;
this.exceptionLevel = exceptionLevel;
this.innerException = e;
this.trackID = trackID;
this.method = method;
}
public BizException(String trackID, String method, String message, Exception e) {
super(message);
this.exceptionLevel = ExceptionLevel.Error;
this.innerException = null;
this.trackID = "";
this.method = "";
this.applicationName = "";
this.serviceID = "";
this.exceptionID = KeyIDFactory.INSTANCE.NewKeyID("LogDB", "LogException");
this.trackID = trackID;
this.innerException = e;
this.exceptionLevel = ExceptionLevel.Error;
this.method = method;
this.writeLog();
}
public void writeLog() {
ILogger loggerException = LogFactory.getLoggerException();
ExceptionLog logO1 = (ExceptionLog)loggerException.getLog();
logO1.setException(this);
loggerException.log();
}
}
9.controller层默认为单列模式
10.多线程安全问题是因为有该线程失去cpu执行权,却已经进入判断条件而出现的错误。单列模式是把构造方法私有化。
11.volatile保证了线程的可见性,有序性(保证操作不能被打断),但不能保证原子性(要么全部失败,要么全部成功),要保证原子性,可以加锁,用原子类。
12.同步非静态方法的锁对象是当前对象,静态方法时当前对象的字节码对象,锁的原理,给共享资源加一个锁,没有线程访问时,锁就是空的,别的线程访问就等着,是同步的,与乐观锁相比减少了不必要的请求,但会出现死锁,可以像zk一样设置过期时间解决。
13.线程池的使用
// 获取线程池
ExecutorService executorService = Executors.newFixedThreadPool(2);
// 创建线程任务,用线程池得到线程执行
executorService.submit(()-> System.out.println(1));
14.常用的几种线程池
(1).newCachedThreadPool
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
(2).newFixedThreadPool
创建一个指定工作线程数量的线程池。每当提交一个任务就创建一个工作线程,如果工作线程数量达到线程池初始的最大数,则将提交的任务存入到池队列中。
(3)newSingleThreadExecutor
创建一个单线程化的Executor,即只创建唯一的工作者线程来执行任务,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。如果这个线程异常结束,会有另一个取代它,保证顺序执行。
(4)newScheduleThreadPool
创建一个定长的线程池,而且支持定时的以及周期性的任务执行,支持定时及周期性任务执行。
15.怎么限制下载速度?
16.file类能够封装电脑上的文件和文件夹并对其操作
11.同步异步,阻塞非阻塞
我的理解: 普通soket中,一个用户需要等待服务器相应返回才能操作,并且多个用户得相互等待(同步阻塞),
加了多线程后,单个用户不用等待别的用户完成,但是自己必须等待自己的响应完成,单线程实现并发也是如此
(同步非阻塞)
aio是不用得带响应完成,肯定是不阻塞的。
(异步非阻塞)
(1) File 抽象、输入输出流,Socket、ServerSocket、HttpURLConnection等。交互方式是同步、阻塞的方式
(2)在 Java 1.4 中引入了 NIO 框架(java.nio 包),提供了 Channel、Selector、Buffer 等新的抽象,可以构建多路复用的、同步非阻塞 IO 程序,同时提供了更接近操作系统底层的高性能数据操作方式
(3)在 Java 7 中,NIO 有了进一步的改进,也就是 NIO 2,引入了异步非阻塞 IO 方式,也有很多人叫它 AIO(Asynchronous IO)
12.反射:将类的各个组成部分封装成其他对象
java的几个阶段:
硬盘上:源代码阶段(字节码文件) ----- 类加载器加载进内存(类对象) ----- 运行时阶段。
13.jdk中预定义的一些注解
@override: 重写
@deprecated 已过时
@surpressWarning 压制警告
注解格式:
元注解
public @interface name{}
本质上就是一个接口,改接口默认集成Annotation
四个元注解:
@Inherited
@Documented
@Retention
@Target
14. jdbc操作顺序
(1) 引包
(2) 注册驱动
(3) 获取连接对象
(4) 写sql
(5) 操作结果集
15.静态代理
代理一个类就必须写一个代理类
16.动态代理
对接口的类实现拦截加强,没有接口的类就没办法
17.cglib代理
JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢,这就需要CGLib了。CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。但因为采用的是继承,所以不能对final修饰的类进行代理。JDK动态代理与CGLib动态代理均是实现Spring AOP的基础。
加载spring容器,加载代理类,加载切面类
18.我的项目的登录逻辑:
用户访问登录网关,用accessFilter去记录登录人的方法和uri
用权限认证过滤器识别请求头里的token这个值是否存在,并且在redis是否存在,如果存在,那么写入用户信息
19.@Configuration启动容器 @Bean注册Bean,@Bean作用在方法上,把返回值注册进容器中
20.springmvc工作原理,先拦截所有请求,在用映射器找到控制器,再根据适配器来决定怎么调用控制器,是否生成modalandview
21.mysql中on和where2个地方写条件的不同
右表先通过on后面的过滤条件返回结果集为临时表,再将临时表和左表联合查询返回结果集。
22.You can’t specify target table for update in FROM clause错误的意思是说,不能先select出同一表中的某些值,再update这个表(在同一语句中)
23.每一个派生出来的表都必须有一个自己的别名
24.application/x-www-form-urlencoded
它是post的默认格式,将非ascii字符做百分号编码;将input的name、value用‘=’连接,不同的input之间用‘&’连接。
multipart/form-data
既可以上传键值对,也可以上传文件
25.Collections.sort可对里面元素排序,如果有对象实现comprable接口排序
26.连接查询中on和where的区别
其实以上结果的关键原因就是left join,right join,full join的特殊性,不管on上的条件是否为真都会返回left或right表中的记录,full则具有left和right的特性的并集。 而inner jion没这个特殊性,则条件放在on中和where中,返回的结果集是相同的。
27.线程分为守护线程(后台线程)和用户线程(前台线程),主线程挂了,守护线程也会被停止掉,设置该线程为守护线程setDaemon()
28.thread.join能先让此线程执行完毕后,才让其他线程有资格执行
29.线程的三大特性,原子性,可见性(当一个线程修改变量后,其他线程是马上可见的),有序性
30.java内存结构:堆栈方法区
31.java内存模型,每一个线程都有一个本地内存区,在对共享变量进行操作时如果不能立即通知其他线程,则会出现多线程安全问题
32.vue. n e x r T i c k 的 用 法 t h i s . v a l u e = ′ 你 好 啊 ′ ; c o n s o l e . l o g ( t h i s . nexrTick的用法 this.value = '你好啊'; console.log(this. nexrTick的用法this.value=′你好啊′;console.log(this.refs[‘hello’].innerText);
this.KaTeX parse error: Expected '}', got 'EOF' at end of input: …nsole.log(this.refs[‘hello’].innerText);
});
33.v-if和v-show都会执行所有钩子函数,但在切换时
v-if:
上一次渲染的组件销毁 符合条件的组件渲染
会依次执行 **beforeCreate(),created(),beforeMount(),beforeDestroy(),destroyed() mounted()**钩子函数
其中标黄的是上一个被销毁组件的两个钩子函数 (销毁前,销毁后)剩下的四个钩子函数是本次符合条件的组件的钩子函数
v-show:
切换时组件始终保持在 mounted()挂载完成 钩子函数
34.delete 和splice方法的区别
1)delete: 只是被删除的元素变成了 undefined 其他的元素的键值还是不变。
2) splice: 该方法会改变原始数组
35.reduce的用法
let b = a.reduce((total, v) => {
return total v;
}, 0);
36.vue中父组件传给子组件的值,子如果直接使用,值会随着父组件值的变化而变化,但是子组件不能对该值进行写操作,如果要求写操作,在子组件中用本地文件接收,如果需要实时变化,就需要监听,其实用.sync就能达到效果。
37.原子类和同步锁可以保证原子性和可见性,volite保证可见性和有序性
38.threadLocal实现原理:把当前线程当做key存进map,跟值相对应
39.单列模式为什么要加volatile?
因为在双重校验情况下,如果判断为空会直接返回空对象,但这个时候并没有实例化。
40.工厂模式:不用自己new,传名字
41.代理模式分为静态代理,jdk动态代理,chlib动态代理(后面2个不需要写代理类)
42.缓存框架的基础,封装map增加过期时间,定期清除过期数据
43.对于普通同步方法,锁是当前实例对象。
对于静态同步方法,锁是当前类的Class对象。
对于同步方法块,锁是Synchonized括号里配置的对象。
44.怎么防止表单重复提交
前端解决:请求失败和成功之后才能继续第二次点击
45.mybatis的一级缓存:基于sqlSession的,同一个sqlSession同一个语句会被缓存
46.声明式事务只有出异常时才会回滚,所以要在catch中手动回滚
47.redis做主从同步配置slaveof ip 端口号,配置哨兵文件为sentinel.conf
48.redis持久化:
rdb:以数据方式进行保存(默认rdb一段时间内修改了多少次)
aof:以日志方式保存(持续保存)
49.http之间怎么保证数据一致性?
可以用定时job每天检查发送失败的数据,重新发送,但是数据无法实时
可以用消息中间件
50.activemq使用
1.使用工厂类输入账号密码获取连接
2.开启连接
3.有链接获取session
4.由session获取队列,生产者,文本消息
消息事务开启,提交和消费都必须手动提交
51.如何保证mq的幂等性
都是为了保证mq不重复接收生产者的消息,在消费者消费完后保证mq正确删除消息
二、出现非幂等性的情况
1、生产者已把消息发送到mq,在mq给生产者返回ack的时候网络中断,故生产者未收到确定信息,生产者认为消息未发送成功,但实际情况是,mq已成功接收到了消息,在网络重连后,生产者会重新发送刚才的消息,造成mq接收了重复的消息
2、消费者在消费mq中的消息时,mq已把消息发送给消费者,消费者在给mq返回ack时网络中断,故mq未收到确认信息,该条消息会重新发给其他的消费者,或者在网络重连后再次发送给该消费者,但实际上该消费者已成功消费了该条消息,造成消费者消费了重复的消息;
三、解决办法
1、mq接收生产者传来的消息:
mq内部会为每条消息生成一个全局唯一、与业务无关的消息id,当mq接收到消息时,会先根据该id判断消息是否重复发送,mq再决定是否接收该消息。
2、消费者消费mq中的消息:
也可利用mq的该id来判断,或者可按自己的规则生成一个全局唯一id,每次消费消息时用该id先判断该消息是否已消费过。
52.vue中data为什么必须返回一个对象?因为组件被实例化后如果不返回一个对象,其中某一个实例改变了值其他的实例化都会被改变。
53.redis挂了怎么办?
先做主从同步,主服务器实现读写权限,2个从服务器分别实现读写权限,主服务器接受数据同步到从服务器,配置哨兵文件夹选举一个从服务器为主,并赋予权限,并用rdb或者aof保证数据。
54.nginx挂了怎么办?
做主从,用keepalived监听
55.分布式锁可以用redis和zk,都是把共享资源锁住,避免多个服务访问共享资源,最重要的是为了避免死锁,要设置过期时间。
56.java的内存模型
类加载器,方法区,堆,栈,本地方法栈
57.jvm调优
对于Java8来说,一般堆内存的初始容量为物理内存大小的1/64,最大内存不超过物理内存的1/4或1G
一般来说,初始内存与最大内存一致,因为申请内存浪费时间
设置内存新生代内存小,会导致gc频繁,影响效率,设置过大,会影响其他程序的使用。
新生代和老年代的比列,按持久对象的多少设置
jvm的新生代一般设置为整个堆的1/3或1/4
58.数据库三大范式
第一范式保证原子性
第二范式保证主键,消除部分依赖
第三范式去除冗余数据,消除传递依赖
59.唯一索引可以为空,主键索引必须满足唯一非空
60.只有使用%时才不会使用索引,联合索引只使用第一个会使用索引,用or不会使用索引
61.使用group by分组查询。默认分组后,还会排序,可能会降低速度。后面增加order by null就可以防止排序。
62.mysql主从复制,原理是从服务器连接主服务器,拿到二进制日志文件执行
63.const unwatch = this.$watch(“sicknessDict.length”, function(v) {
// 取消观察
unwatch();
}
64.ThreadLocal 与 Thread 同步机制的比较
同步机制采用了以时间换空间方式,通过对象锁保证在同一个时间,对于同一个实例对象,只有一个线程访问。
ThreadLocal 采用以空间换时间方式,为每一个线程都提供一份变量,各线程间同时访问互不影响。
65.js的数字转字符串,会去掉小数点最后的0
66.使用mq解决分布式事务,第一用本地消息表,第二roketmq本身自带事务,第三补偿。
67.图片的下载始终都要向服务器发出请求,要是图片的下载不用向服务器发出请求,而可以随着 HTML 的下载同时下载到本地那就太好了,而 base64 正好能解决这个问题。一般大图片不能做精灵图的图片以这样的方式,前端优化思想一般为减少请求,尽可能的一次请求把多个资源给客户端,单页面应用和cs架构应用(下载好存在本地)就是这一思想。
68.网页中引入的静态资源多了以后有什么问题?
1.网页加载速度慢,因为,我们要发起很多的二次请求
2.要处理错综复杂的依赖关系
如何解决上述两个问题
1.合并、压缩、精灵图、图片的base64编码
2.可以使用之前学过的requireJS、也可以使用webpack可以解决各个包之间的复杂依赖关系;
69.cnpm不会去识别package-lock.json,所以有时候用npm安装没问题,cnpm安装因为版本问题而报错。cnpm i xx 不会更新到package-lock.json,所以下载新的包用cnpm不会记录到package.json,别人无法重新下载安装。
70.webpack全局安装后,敲命令是调用本地版本,项目中用脚本使用的当前项目中的版本。我们是在项目中,本地安装的 webpack-dev-server,所以,无法把它当做脚本命令在 powershell 终端中直接运行;(只有那些安装在全局 -g 的工具,才能在终端中正常执行)如果要想正常运行,要求在本地项目中,必须安装 webpack,然后在package.json文件中的scripts节点上配置上 “dev”:
71.线程分为主线程,守护线程(gc线程,主线程挂掉,守护线程也会挂掉),非守护线程(用户增加创建的线程)。
72. Object.defineProperty(car, ‘price’, {
get(){
console.log(‘price属性被读取了’)
return val
},
set(newVal){
console.log(‘price属性被修改了’)
val = newVal
}
})
Object.defineProperties(obj, {
‘property1’: {
value: true,
writable: true
},
‘property2’: {
value: ‘Hello’,
writable: false
}
// etc. etc.
});
73.前端只能设置请求头,把前端发送的数据格式化,告诉后台发送的数据格式。
74.webpack对本项目打包,webpack-dev-server打虚拟包,html-webpack-plugin:我们不再需要手动处理 bundle.js 的引用路径了,因为这个插件,已经帮我们自动创建了一个合适的 script ,并且引用了正确的路径
75.Websocket是一个持久化的协议,相对于HTTP这种非持久的协议来说,Websocket是基于HTTP协议的,或者说借用了HTTP的协议来完成一部分握手
,客户端与服务端实现实时消息通讯可以使用ajax轮询或者一直等着服务器响应。其实就是,服务端不能主动联系客户端,只能有客户端发起。
76.commonjs
最基础的规范是CommonJS和AMD,CommonJS经node.js应运而生。es6模块化,是基于commonjs的再次封装,导入import,导出export。
1、定义模块
根据CommonJS规范,一个单独的文件就是一个模块。只需声明变量,导出即可
2、模块输出:module.export
3、加载模块:
加载模块使用require方法,该方法读取一个文件并执行,返回文件内部的module.exports对象
之后为了解决commonjs同步问题,不能用于浏览器端,所以AMD来解决这些问题,用define定义模块,用require引入即可使用
CMD也来解决这个问题,只是他们的运行机制不同,AMD是依赖前置,而CMD是就近依赖,两个都是异步加载模块。
77.缓存雪崩
redis里缓存数据同时集体过期,大量并发请求会打垮数据库
解决方案
缓存数据过期时间设置随机
设置永久不过期
缓存穿透
缓存数据库都没有数据
解决方案
做接口校验,拦截一部分明显不合法的请求
可以把这些取不到的数据设置短的缓存,防止直接访问数据。
缓存击穿
缓存没数据,数据库有数据,一般是缓存时间到期,可以设置热点数据永不过期,或者使用mq消峰。
78.
箭头函数让this永远指向本实例
73. 断点续传实质是文件拼接,一个英文字母占1个字节,汉字占2个字节
79.NIO.缓冲区(通常用bytebuffer),通道,io多路复用,选择器。缓冲区的limit是可用容量,读取后会变为读到的大小。缓冲区分为直接缓冲区 存放物理内存,非直接缓冲区,存放jvm内存,用直接缓冲区效率高,不用拷贝,但不安全
原生文件复制操作,流对象接收路径或者文件对象,创建一个数组读,循环里面写
nio复制方法,创建流,获取通道,创建缓冲区,接收通道里的数据,写到通道里
80.vuex的使用
首先全局注册vuex的store,在里以对象的形式放置数据,可以通过this. s t o r e . s t a t e . ∗ ∗ ∗ 直 接 获 取 也 可 以 通 过 t h i s . store.state.***直接获取 也可以通过this. store.state.∗∗∗直接获取也可以通过this.store.getters.***获取,这种获取相当于computed
store里定义
getters: {
doneTodos: state => {
return state+1
}
}
可以返回一个函数调用传参
// 使用对象展开运算符将 getter 混入 computed 对象中
…mapGetters([
‘doneTodosCount’,
‘anotherGetter’,
// …
])
如果需要修改store中的值唯一的方法就是提交mutation来修改
store定义
// …
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}
在页面的方法中调用
this.KaTeX parse error: Expected '}', got 'EOF' at end of input: …d()` 映射为 `this.store.commit(‘increment’)`
})
mutation 必须同步执行
官方并不介意我们这样直接去修改store里面的值,而是让我们去提交一个actions,用它来直接调用mutations
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit(‘increment’)
}
}
81.Service Worker,对比原生app,来实现离线访问,pwa是集合了多种web技术来让webapp有比拟原生应用最好的体验。
由以下几种技术构成:
App Manifest
Service Worker(最重要实现离线缓存,消息通知,添加到页面)
Notifications API
Push API
缓存,减少与服务器非必要的交互,不过对于离线的情况下浏览器缓存就无力了,
这样离线缓存的需求就出现了。
在vue中使用直接在主js中注册
82.BigDecimal的字符串构造函数不会丢失经度。
83.编码起初是为了加密,后面是为了传输标准
84.框架里用到的设计模式。
85.jvm常用算法.标记清除,标记压缩,复制
86.服务分布分级,分布式事务@traditionnoal的使用条件,mq的消息先后顺序机制(保证生产者mq消费者一对一对一就行了,限制异步发送,并发消费)。
87.(1)网络发送请求都是同步的,只不过开启了多个线程实现了伪异步。
(2)同步一般说的是直连形式,而阻塞一般对客户端一个请求而言,要等待别的请求完成,则是阻塞的,对于服务器而言,一直等待客户端发送消息,是阻塞的,但可以使用多线程让请求间不会相互等待,但是本质服务器得单个线程还是阻塞的,所以还可以使用通道去注册到选择器上,当数据准备完成后,选择器通知服务器,这样服务器就不用一直等待,这就是同步非阻塞,而选择器依然是同步的,可能会造成阻塞,如果选择器为异步通知,则变化为异步非阻塞。
88.mysql三表连接查询,条件写在最后面。
89.线程安全不针对对共享变量读,两个线程不可能同时获取锁。
90.scoket为长连接可以双工通信,http是短链接是tcp的封装,只能客户端访问服务器。
91.dubbo用序列化文件,用netty传输,@trasient不让序列化
92.序列化协议就是两边约定数据格式能解析。
93.socket发送数据和http发请求相比,http会把数据封装起来。
94.mq能否等一个消息消费后才发另外一条?mq消息有没有格式?mq怎么保证接受到消息的顺序
如果生产者,mq,消费者一对一对一,不会出现顺序问题
如果两条消息差个毫秒级别,顺序也不会改变
mq
95.java和js获取日期时间戳都是先转为date对象再调用getTime()
96. FileReader字符流,FileInputStream 字节输入流
InputStreamReader转字节流为字符流
下次要去文件路径就直接用字节码调getResourceAsStream()
97,java的find()方法在部分匹配时和完全匹配时返回true,匹配不上返回false;
matches()方法只有在完全匹配时返回true,匹配不上和部分匹配都返回false。
用group()方法可以得到截取的字符串,默认group(0)为整个表达式。
贪婪模式:匹配最长的匹配值
非贪婪模式:匹配最短的匹配值
加?是非贪婪模式
98.vue组件中,在style设置为scoped的时候,里面在写样式对子组件是不生效的,如果想让某些样式对所以子组件都生效,可以使用 /deep/ 深度选择器。如果不想全局污染,可以加class
99.引入js时,js有export才可以命名字,不然可以方法直接调用
100.包装类值比较时,必须用equals
101.字符串拼接调用了stringbuilder的append方法
102.promise封装了异步操作,异步操作被封装成
function test(resolve, reject) {
var timeOut = Math.random() * 2;
log('set timeout to: ' + timeOut + ' seconds.');
setTimeout(function () {
if (timeOut < 1) {
log('call resolve()...');
resolve('200 OK');
}
else {
log('call reject()...');
reject('timeout in ' + timeOut + ' seconds.');
}
}, timeOut * 1000);
}
async用来表示函数是异步的,定义的函数会返回一个promise对象,可以使用then方法添加回调函数。
把一个异步函数封装到一个函数,再把这个函数封装到promise中,再把这个promise封装到一个函数
function sleep(second, param) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(param);
}, second);
})
}
// 为了处理Promise.reject 的情况我们应该将代码块用 try catch 包裹一下
async function errorDemoSuper() {
try {
let result = await sleep(1000);
console.log(result);
} catch (err) {
console.log(err);
}
}
promise.all的用法
async function correctDemo() {
let p1 = sleep(1000);
let p2 = sleep(1000);
let p3 = sleep(1000);
await Promise.all([p1, p2, p3]);
console.log('clear the loading~');
}
103.JSON转泛型使用new TypeReference
104:Set集合怎么实现线程安全?
方案一:
和list一样,使用Colletcions这个工具类syn方法类创建个线程安全的set.
Set synSet = Collections.synchronizedSet(new HashSet<>());
105:给map排序,先获取entryset然后通过arrylist的构造方法转为list,然后用Collections.sort给entryset集合排序
106.1. “==”
基本数据类型:
它们之间使用“==”比较,比较的是它们的值。
引用数据类型:
它们之间用“==”进行比较时,比较的是他们在内存中存放的地址(堆内存首地址);
equals的话默认和==一样,但是有些对象重写了此方法。