LeetCode 2673. 频率跟踪器
原题链接
题目描述
请你设计并实现一个能够对其中的值进行跟踪的数据结构,并支持对频率相关查询进行应答。
实现 FrequencyTracker 类:
FrequencyTracker():使用一个空数组初始化 FrequencyTracker 对象。
void add(int number):添加一个 number 到数据结构中。
void deleteOne(int number):从数据结构中删除一个 number 。数据结构 可能不包含 number ,在这种情况下不删除任何内容。
bool hasFrequency(int frequency): 如果数据结构中存在出现 frequency 次的数字,则返回 true,否则返回 false。
示例 1:
输入
["FrequencyTracker", "add", "add", "hasFrequency"]
[[], [3], [3], [2]]
输出
[null, null, null, true]
解释
FrequencyTracker ...
Debian中vi编辑器键盘错乱
在安装完Debian后,vi编辑器键盘不能正常使用,使用下面方法解决:
编辑文件/etc/vim/vimrc.tiny,将 compatible改成nocompatible非兼容模式;
并添加一句:set backspace=2(注:主要看最后几行)
cat /etc/vim/vimrc.tiny
" Vim configuration file, in effect when invoked as "vi". The aim of this
" configuration file is to provide a Vim environment as compatible with the
" original vi as possible. Note that ~/.vimrc configuration files as other
" configuration files in the runtimepath are still sourced.
" When Vim is invoked d ...
Git
Git
分布式版本管理工具。
分布式版本控制系统没有“中央服务器”,每个人电脑都是一个完整的版本库,这样在工作的时候就不需要联网了,多人协作只需要各自的修改推广给对方,就可以看到对方的修改了。
安装
Git - Downloads (git-scm.com),在官网下载,然后安装就可以了。
如果选择自解压,需要配置环境变量。
打开控制台窗口,输入git --version,成功输出版本号就意味着成功安装。
安装完成后,首先要做的事情是设置用户名和邮箱,每次Git提交都会使用该用户信息。
git config --global user.name "username"
git config --global user.email "example@example.com"
如果已经设置过,再次输入就可以覆盖之前设置的。
查看配置信息:
git config --global user.name
git config --global user.email
使用
获取本地仓库
要使用Git对代码进行版本控制,首先需要获得本地仓库。在需要管理的 ...
JVM篇
JVM组成
什么是程序计数器
线程私有的,内部保存的字节码行号。用于记录正在执行的字节码指令的地址。
堆
线程共享的区域:主要用来存储对象、数组等,当堆中没有内存空间可分配给实例,也无法扩展时,则会抛出OOM异常。
堆由年轻代和老年代组成。年度又分为Eden区和两个大小一致的Survivor区,老年代主要保存生命周期长的对象。
1.7对中有一个方法区/永久代,存储的是类信息、静态变量、常量、编译后的代码。1.8移除了1.7中的方法区/永久代,把数据存储到了本地内存的元空间中,防止内存溢出。
虚拟机栈
每个线程运行时需要的内存被称为虚拟机栈。
每个栈由多个栈帧组成,对应着每次方法调用时所占用的内存。
每个线程只能由一个活动的栈帧,对应着当前正在执行的那个方法。
垃圾回收是否涉及栈内存?
垃圾回收主要是针对堆,当栈栈弹栈后,内存就会被释放。
栈内存分配越大越好嘛?
不一定,默认的栈内存通常为1024k。
栈帧过大会导致线程数变少。机器总内存512M,目前能活动的线程数则为512个,若给栈内存改为2048K,那么活动栈帧就会减半。
方法内的局部变量释放线程安全?
如果方法内局 ...
并发编程篇
线程的基础知识
线程和进程的区别
进程的正在运行程序的实例,一个进程包含了多个线程,每个线程执行不同的任务。
不同的进程使用不同的内存空间,当前进程下的线程可以共享内存空间。
线程更加轻量,线程上下文切换成本一般会比进程的上下文切换低。
并行与并发的区别
如果是单核CPU,只有并发,没有并行。
并发是在单位时间内交替运行多个线程。
并行是在单位时间内同时运行多个线程。
创建线程的方式有哪些
继承Thread类
重写run方法,调用start方法启动线程。
实现Runnable接口
与第一种一样。
实现Callable接口
实现Callable接口,需要传入一个泛型。
实现call方法,call方法返回类型就是传入的泛型。
创建Callable实现类的对象a。
创建FutureTask对象b,将对象a传入。
创建Thread对象c,将对象b传入。
调用c对象的start()方法启动线程。
可以使用b.get()获取线程执行结果。
线程池创建
使用Executors.newFiexdThreadPool()创建一个线程池,然后调用submit ...
集合篇
Collection
单列集合
List
有序可重复
Vector
数组结构,线程安全
ArrayList
数据结构,非线程安全
ArrayList底层的实现原理是什么?
底层是用动态数组实现的。
初始容量为0,当第一次添加数据的时候才会初始化容量为10。
进行扩容的时候是原来的1.5倍,每次扩容都需要拷贝数组。
添加数据时候:
确保size + 1后能存储下下一个数据。
计算数组容量,如果size + 1大于当前的数组容量,调用grow方法扩容。
确保新增的数据有地方存放后,则将新元素加到对应的位置上。
放回true。
ArrayList list = new ArrayList(10)中的list扩容了几次?
答:没有扩容,只是指定了一个容量为10的Object数组。
如何实现数组与List之间的转换
List转数组
使用List.toArray(T[] a): T[]。
数组转List
Arrays.asList(T ... a): List<T>。
使用Arrays.asList转List后,修改数组内容,List受影响吗?
受影响。他 ...
消息中间件篇
消息中间件使用场景
异步发送(验证码,短信,邮件)
MySQL和Redis,ES之间的数据同步
分布式事务(最终一致性)
作为发布/订阅系统实现一个微服务系统间的观察者模式。
连接流计算任务和数据。
用于将消息广播给大量的接收者,数据同步。
流量控制(削峰填谷)
错峰与流控。
问题:如何避免过多的请求压垮系统?
设计思路:使用消息队列隔离网关和后端服务,以达到流量控制和保护后端服务的目的。
代价:
增加系统调用的链路,导致总体的响应时间变成。
同步调用变成了异步调用,增加系统的复杂度。
成本问题,MQ的高性能和高可用。
常见的限流算法:
固定窗口算法
滑动窗口算法
漏桶算法
令牌桶算法:有一个程序,在单位时间内只发放固定的令牌到令牌桶中,规定服务在处理请求之前必须先从令牌桶中先获取一个令牌,如果令牌桶中没有令牌,则拒绝请求。这样就可以保证单位时间内,能处理的请求不超过发放令牌的数量。
服务解耦
微服务的通信模式:
调用链模式:A -> B -> C
聚合器模式:有点像DDD中和聚合。
基于事件的异步模式:有点像DDD中的事件。
分布式事务
产生的原 ...
微服务篇
Spring Cloud
Spring Cloud组件有哪些?
注册中心:Eureka/Nacos。
负载均衡:Ribbon。
服务熔断:Hystix/Sentinel。
远程调用:Feign。
服务网关:Zuul/Gateway。
服务注册和发现
eureka
服务注册:服务提供者需要把自己的信息注册到eureka,由eureka来保存这些信息。例如服务名称、IP、端口等。
服务发现:消费者向eureka拉起服务列表的信息,如果服务提供者有集群,则消费者利用负载均衡算法选择一个服务发起调用。
服务监控:服务提供者每隔30秒向eureka发送心跳,报告监控状态,若eureka90秒还没收到心跳,从eureka剔除该服务。
nacos
nacos与eureka大体相同。
不同点
nacos支持服务端主动监测提供者状态:临时实例采用心跳检查,非临时实例采用主动检测模式。
临时实例心跳不正常会被剔除,非临时实例不正常不会被剔除。
nacos支持服务列表变更的消息推送模式,服务列表更新及时。
nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式,而eureka只 ...
MyBatis篇
执行流程
读取MyBatis配置文件:mybaits-config.xml加载运行环境和配置文件。
创建会话工厂SqlSessionFactory。
会话工厂创建SqlSession对象。(包含了执行SQL语句的所有方法)。
操作数据库的接口,Executor执行器,同时负责查询缓存的维护。
Executor接口的执行方法中有一个MapperStatement类型的参数,封装了映射信息。
输入参数的映射。
输出结果的映射。
延迟加载
需要用的时候才加载数据,不需要用到就不加载。
MyBatis支持一对一、一对多关联的延迟加载。
是否支持延迟加载?
支持,但是默认关闭。
全局:全局配置文件中的lazyLoadingEnable=true。
局部:fetchType=lazy。
原理
使用CGLIB创建目标代理对象。
当调用getXXX()方法的时候,进入拦截器invoke方法,判断xxx属性是否为空,如果为则执行sql,从数据库中获取数据
获取到数据后,调用setXXX()为xxx属性赋值,接着完成getXXX()方法的调用。
一二级缓存
本地缓存:PerpetualCa ...
Spring篇
Spring
Bean线程安全问题
Spring中的Bean默认是单例的。可以使用@Scope注解设置将属性设置成prototype变成多例。
Spring中的Bean不是线程安全的。
Spring Bean并没有可改变状态(例如Service类和Mapper类),所以在某种程度上说Spring的单例Bean是线程安全的。如果在bean中定义了可修改的成员变量,是要考虑线程安全问题的,可以使用多例或者加锁来解决。
AOP
AOP被称为面向切面编程,用于将那些与业务无关,但却会影响多个对象的公共代码和逻辑抽取并封装成为一个可重用的模块,这个模块被命名为”切面“(Aspect),减少系统中重复的代码,降低了模块之间的耦合度,同时提高系统的可维护性。
常见场景
记录操作日志。
缓存处理。
Spring中内置事务处理。
事务原理
编程式事务:需要使用TransactionTemplate来实现。
声明式事务:AOP。
事务失效
异常捕获处理:方法内部给异常捕获了,会导致声明式事务感受不到异常。解决:在catch中再抛一个异常出去。
抛出检查异常:使用throws抛出异常。 ...
