1、@PostConstruct的用法
@PostConstruct该注解被用来修饰一个非静态的void()方法。被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器执行一次。PostConstruct在构造函数之后执行,init()方法之前执行。
spring bean初始化执行顺序:
Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的方法)
应用:在项目初始化bean的时候执行相关的方法,此在服务启动成功之前执行缓存加载,可以避免在kafka开始消费,缓存还没加载的问题。
2、String 工具:
(1)StringUtils.split(typeAndrst, "|");
3、Guava:提供核心JAVA类库,有新的集合类型、不可变的集合
应用:不可变的集合、字符串的处理、本地缓存。
(1)不可变集合:任何人改变不了、可以多线程、节省空间
(2)新的集合类型:以前的集合要for循环遍历数个数,新的可以用Multiset直接统计元素个数。还有交集、差集、并集等功能计算。
https://blog.csdn.net/pzjtian/article/details/106739606相关资料:https://blog.csdn.net/pzjtian/article/details/106739606
(3)本地缓存Cache(企业应用--实时监控点击流量):与ConcurrentMap相似,会一直保存添加的数据,但ConcurrentMap要自己主动remove;Cache会自动回收(节省内存)
应用:空间换时间、某些被经常查询的数据
某些经常被查的数据:因为传统关系型数据库的数据在硬盘,读取速度比在内存慢,把热点数据缓存到内存。代码实现:
a.build
@Test
public void cacheCreateTest(){
Cache<String,String> cache = CacheBuilder.newBuilder()
.maximumSize(100) //设置缓存最大容量
.expireAfterWrite(1,TimeUnit.MINUTES) //过期策略,写入一分钟后过期
.build();
cache.put("a","a1");
String value = cache.getIfPresent("a");
}
b.LoadingCache
实时流量监控:cache中 没有值 or 需要更新的值,要从数据库拿数据并缓存下来,调用load方法获取结果并将放入指标度量工具Metrics,进行监控。
定义的CacheLoader没有声明任何检查型异常,则可以通过 getUnchecked(K) 查找缓存
4、Metrics指标度量工具(做监控、统计)
应用:每秒请求数(TPS)、平均请求处理时间、请求处理最长耗时、等待处理的请求队伍长度、缓存命中率、平均查缓存的时间
(1)maven:
<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-core</artifactId>
<version>${metrics.version}</version>
</dependency>
(2)核心类:MetricRegistry
类:存放所有metrics的容器。每一个metrics都有自己的名字
MetricRegistry.name(Queue.class, "requests", "size")
MetricRegistry.name(Queue.class, "responses", "size")
即:com.example.Queue.requests.size
(3)数据展示 形式:JMX, console, SLF4J, 和 CSV
(4)五种类型
支持五种metric类型:Gauges、Counters、Meters、Histograms和Timers。
a.Gauges 只有一个简单的返回值
计算有多少个在等待的队列
public class MetricsTest {
public static Queue<String> q = new LinkedList<String>();
public static void main(String[] args) throws InterruptedException {
MetricRegistry metricRegistry = new MetricRegistry();
metricRegistry.register(MetricRegistry.name(MetricsTest.class, "queue", "size"),
new Gauge<Integer>() {
public Integer getValue(){
return q.size();
}
});
ConsoleReporter reporter = ConsoleReporter.forRegistry(metricRegistry).build();
reporter.start(1, TimeUnit.SECONDS);
while (true){
Thread.sleep(1000);
q.add("JOB-20220212");
}
}
}
结果:
-- Gauges ----------------------------------------------------------------------
com.jane.metrics.MetricsTest.queue.size
value = 15
b.counter 【inc+1,dec-1】
public class CounterTest {
public static Queue<String> q = new LinkedBlockingQueue<String>();
public static Counter countJobs;
public static Random random = new Random();
public static void addJob(String job){
countJobs.inc();
q.offer(job);
}
public static String takeJob(){
countJobs.dec();
return q.poll();
}
public static void main(String[] args) throws InterruptedException {
MetricRegistry metricRegistry = new MetricRegistry();
ConsoleReporter reporter = ConsoleReporter.forRegistry(metricRegistry).build();
reporter.start(1, TimeUnit.SECONDS);
countJobs=metricRegistry.counter(MetricRegistry.name(CounterTest.class,"queue","jobSize"));
int num=1;
while (true){
Thread.sleep(200);
if(random.nextDouble()>0.7){
String job = takeJob();
System.out.println("take job:"+job);
}else{
String jobNum="job"+num;
addJob(jobNum);
System.out.println("add job:"+jobNum);
}
num++;
}
}
}
c.meters 速率,比如TPS
public class MetersTest {
public static Random random = new Random();
public static void request(Meter meter){
System.out.println("request");
meter.mark();
}
public static void request(Meter meter,int n){
while (n>0){
request(meter);
n--;
}
}
public static void main(String[] args) throws InterruptedException {
MetricRegistry metricRegistry = new MetricRegistry();
ConsoleReporter reporter = ConsoleReporter.forRegistry(metricRegistry).build();
reporter.start(1, TimeUnit.SECONDS);
Meter register = metricRegistry.meter(MetricRegistry.name(MetersTest.class, "request", "tps"));
while (true){
request(register,random.nextInt(5));
Thread.sleep(1000);
}
}
运行结果:
com.jane.metrics.MetersTest.request.tps
count = 6
mean rate = 1.20 events/second
1-minute rate = 1.20 events/second
5-minute rate = 1.20 events/second
15-minute rate = 1.20 events/second
5、属性值相关的注释
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)//插入时,自动加上当前时间
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
6、truncate用法
作用:清空某张表中的所有行;会重置自增值。
用法:truncate table tbl_name truncate tbl_name
@Delete("truncate table t_insight_lead_card")
void deleteAll();
drop:删除表的结构
delete:删除部分数据
11、时间相关
Calendar.getInstance()可以进行时间的计算、时区的指定 setTime before
new Date()创建了UTC格式的date对象
Calendar nowTime = Calendar.getInstance();
nowTime.setTime(now);
nowTime.before(endTime)//endtime之前是nowtime
nowTime.after(beginTime)//begintime之后是nowtime
System.currentTimeMillis() 得到当前毫秒
12、单元测试
MyService service = spy(MyService);
doThrow(new Exception(ResultCodeEnum.INVALID_PARAM,"oops!")).when(service).validateDivisor(anyDouble());
verify(service).validateDivisor(0);
doNothing().when(service).pushActivity(any());//方法没有返回值
when(SDao.getById(123L)).thenReturn(null);//方法有返回值
doReturn(Arrays.asList(dto)).when(service).listo(anyList());//方法有返回值
Assert.assertEquals(null,GroupDto);
13、@Primary注解
一个方法有多个实现类,自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常
@SneakyThrows注解:抛出异常
14、Redis
五大类型:
String(key-value:粉丝数、微博数、cookie[key-value eg:project-234:xka])
Hash(key-field-value:用户id-姓名tag/年龄tag-姓名data/年龄data 部分变更的数据、用户星系) List(key-value 不会去重 粉丝列表)
Set(key-value 会自动去重关注的人、粉丝-》共同好友(list))
zset(有优先级 key-value-score score可以是成绩、时间等 排行榜topn )
对于zset:Spring提供了TypedTuple接口(可以获得value和score),它定义了两个方法,并且Spring还提供了其默认的实现类DefaultTypedTuple:
zset代码展示:
@Test
public void test() {
Set<ZSetOperations.TypedTuple<String>> typedTupleSet = new HashSet<>();
//创建set
for(int i=0;i<10;i++){
double score=i;
ZSetOperations.TypedTuple<String> typedTuple
=new DefaultTypedTuple<String>("value"+i,score);
typedTupleSet.add(typedTuple);
}
//插入集合
redisTemplate.opsForZSet().add("zset1",typedTupleSet);
//集合操作
BoundZSetOperations<String, String> zset1 = redisTemplate.boundZSetOps("zset1");
RedisZSetCommands.Range range = new RedisZSetCommands.Range();
Set<String> set = zset1.rangeByScore(2, 6);
for (String str:set){
System.out.println("结果为:"+str);
}
}
BoundValueOperations就是一个绑定key的对象,我们可以通过这个对象来进行与key相关的操作。比如:添加元素value、按分数排序、定义范围排序、删除元素value
ZSetOperations<String,Long> op = redisTemplate.opsForZSet();
long cnt=op.count(key,minScore,maxScore);
在minScore和maxScore之间的数量
15、sql
(1)odps:建表分区PARTITIONED BY (ds STRING COMMENT '日期分区 yyyymmdd')
(2)with t1 as (select 1 as key ,),t2 as(select 1 as key)....insert overwrite table xx select xxx on t1.key=t2.key
(3)select get_json_object(jsonData,'$.ID') from test
(4)建表时:a.主键Id bigint(20) unsigned
b.`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
c.ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COMMENT=
16、for和foreach
list.forEach(e -> {channelEntity.setId(e.getId());});
- 如果只是遍历集合或者数组,用foreach好些,快些。
- 如果对集合中的值进行修改,确定循环次数就要用for循环了
17、线程池
所有超级接口:Executor
所有已知子接口:ScheduledExecutorService
所有已知实现类:AbstractExecutorService, ScheduledThreadPoolExecutor, ThreadPoolExecutor
方法:shutdown、submit()、submit(Runable或者是callable):
Future<String> future = threadPool.submit(()->"创建了一个线程");
18、yml配置和config配置类
config配置类需要加相关注解:
@Configuration
@ConfigurationProperties(prefix = "xxx.xxx.xxx-xxx")
@Data
18、Mybatis
(1)@InsertProvider 批量插入
在mapper中添加
@InsertProvider(
type = Mapper.Factory.class,
method = "insertKey"
)
void insertKey(User user)
public static class Factory{
public static String insertKey(Map<String,Object> param){
StringBuilder stringBuilder = new StringBuilder();
User user= (User )param.get("user");
stringBuilder.append("<script> INSERT INTO role_table \n");
stringBuilder.append("(user) \n");
stringBuilder.append("values (\n");
stringBuilder.append("#{user.roleName} \n");
stringBuilder.append(") \n");
//UPDATE时间
stringBuilder.append("ON DUPLICATE KEY UPDATE \n");
stringBuilder.append("role_name = values(role_name) \n");
stringBuilder.append("</script>\n");
return stringBuilder.toString();
}
}
19、yml list结构 - map结构:
20、kafka+eruka
21、CountDownLatch
应用:异步 如:websocket
常用方法:countDown和await
22、Arrays.copyOfRange(bytes,offset,lenth)复制数组
23、
EQ 就是 EQUAL等于`
`NE就是 NOT EQUAL不等于`
`GT 就是 GREATER THAN大于 `
`LT 就是 LESS THAN小于`
`GE 就是 GREATER THAN OR EQUAL 大于等于`
`LE 就是 LESS THAN OR EQUAL 小于等于