不定期随笔记02

1.SQL相关

1.1 SQL基础

1.时间函数 date_format(dateTime,'%Y%m%d')
2.索引失效的情况:
	select * from user where id=20 (id是primary key)
	2.1 索引字段使用函数,导致索引失效,全表查询all ★★
		eg:select * from user where trim(id) =20 
	2.2 对索引字段进行数学运算
    	eg:select * from user where id+5 =20 
    2.3 使用反向查询,导致索引失效(!=not likenot in)
    	eg:select * from user where id !=20 
    2.4 索引字段频繁的修改
    	会造成b+tree频繁的维护(16kb页的分裂等)
3. 关于分组group by
	user:id age  name  sex
	eg:
	select sex,* from user group by sex;是错误的,一般group by 要结合聚合函数处理数据,此处的*默认展示第一行记录,无意义的数据;
	如果仅仅是为了获取分组后的字段,eg:
	select sex from user group by sex;
	强烈建议sql改为:select distinct sex from user
4.业务分析通透后再落地SQL ★★★★
	2:8定律;

1.2 业务分析

1.拿到需求,然后独立分析(第一次确认);
	任务交接方会提供一些需求文档:需求说明书、产品原型等
2.独立分析后,把潜在的问题(有歧义的问题)整理下,集中找相关负责人对接,做开发需求的二次确认;
	这个过程会加深对需求的了解;
	甚至在探讨的过程中负责人会给你一些建设性的开发建议;
3. 拆解业务,SQL分步骤落地;
	sql先在客户端运行,然后复制到xml中;

1.3 业务举例说明

-- 以周k线展示功能为例分析
-- 业务概述:周k线就是统计过去每周产生的数据,形成的K线图
-- 包含的数据:周1的开盘价、周五的收盘价、一周内的最价、一周内的最低价、股票的code等;
-- SQL分析:
-- 1.先根据周进行分组,分组后获取周1开盘的时间点、周五收盘的时间点、max最高价、min最低价等;
-- 2.将步骤1的开盘和收盘时间点结合股票的code查询出对应的价格,就是一周内的开盘价和收盘价;
-- 具体SQL:
-- 步骤1SQL:
				SELECT
                    stock_code,
                    DATE_FORMAT(cur_time,'%Y-%u') AS week,
                    MAX(cur_time) AS mxTime,//收盘时间点,对应的价格,就是收盘价格
                    MIN(cur_time) AS miTime,//开盘时间点,对应的价格,就是开盘价
                    MAX(cur_price) AS maxPrice,
                    MIN(cur_price) AS minPrice,
                    AVG(cur_price) AS avgPrice
                FROM stock_rt_info
                WHERE stock_code=#{stockCode} and cur_time between #{startTime} and #{endTime}
                GROUP BY week
# 步骤2:将步骤1的结果作为一张表与股票流水表关联查询即可   
        SELECT tmp.stock_code,tmp.maxPrice,tmp.minPrice,tmp.avgPrice,s1.cur_price AS openPrice,s2.cur_price AS closePrice,
               DATE_FORMAT(tmp.mxTime,'%Y%m%d') AS mxTime FROM
            (
                SELECT
                    stock_code,
                    DATE_FORMAT(cur_time,'%Y-%u') AS week,
                    MAX(cur_time) AS mxTime,
                    MIN(cur_time) AS miTime,
                    MAX(cur_price) AS maxPrice,
                    MIN(cur_price) AS minPrice,
                    AVG(cur_price) AS avgPrice
                FROM stock_rt_info
                WHERE stock_code=#{stockCode} and cur_time between #{startTime} and #{endTime}
                GROUP BY week
            ) AS tmp LEFT JOIN stock_rt_info AS s1 ON s1.stock_code=tmp.stock_code AND s1.cur_time=tmp.miTime
                     LEFT JOIN stock_rt_info AS s2 ON s2.stock_code=tmp.stock_code AND s2.cur_time=tmp.mxTime ORDER BY mxTime ASC
# 正常情况下,股票的数据肯定是有的,没必有左外连接查询的,但是如果防止关联查询时,表中无数据,则可使用外连接查询;                     

2.数据采集

1.Spring提供的模拟浏览器请求行为的模板对象:RestTemplate
	核心API:
		getForObject
		getForEntity
		postForObject
		postForEntity
2.解析采集的数据的思路
	2.1 如果采集的数据是标准的json格式,直接借助jackson\fastson\gson等工具,直接解析
		甚至RestTemplate本身也可直接解析;
	2.2 如果是复杂的非标准的格式,先以String接收,然后分析数据的格式,结合一些正则的框架技术做解析处理;
3.采集后的数据保存问题
	采集数据Io开销比较大,且操作比较耗时;
	思路:将采集的数据partion分区分片,然后再--逐次--保存;
	多线程+线程池异步并发采集数据,并操作;	

3.多线程和线程池

1.构建线程对象的几种方式?
	1.1 集成Thread类
	1.2 实现Runable接口
	1.3 实现Callable接口
	1.4 从线程池获取(底层也实现了Runable接口的)
2.线程池专题
	2.1 线程池核心参数
			核心线程数  最大线程数 任务队列 存活时间大小 存活时间的单位  拒绝策略 线程工厂treadFactory
	2.2 线程池拒绝策略有哪些?
    		AbortPolicy:抛出异常,终端执行
    		DiscardPolicy:丢掉任务,不抛出异常
    		DiscardOldestPolicy:淘汰老的任务
    		CallerRunsPolicy:将处理不了的任务交给主线程处理,给主线程一个正向的反馈,如果主线在执行任务时也阻塞了,那么就不会接收新的任务,这样任务线程就有时间缓慢处理当前的任务;
    		自定义任务的拒绝策略
    			实现RejectedExecutionHandler接口下的rejectedExecution;
    2.3 线程池的工作机制(工作流程)
    	1)线程池初始化时,核心线程数是多少?
    		零,线程是比较重的对象,构建对象时需要与系统底层交互,所以尽量按需加载(懒加载)
    	2)当前线程数< 核心线程数,此时如果有新的任务进来,会线程复用么?
    		不会
    	3)当前线程数=核心线程数,此时并发任务数小于等于核心线程数+任务列队长度,会构建新的线程么?
        	不会,超过核心线程的任务会要入任务队列中,异步处理;
        4)并发任务数 >核心线程数+工作队列长度 ,但是 小于等于 最大线程数+工作队列长度,会构建新的线程么?			会构建新的线程(临时线程),但是这些临时线程一旦空闲,就是回收;
        5)并发任务数 > 最大线程数+工作队列长度,线程池又是如何处理的?
        	此时已经达到最大的线程数,同时队列已满,会触发拒绝策略;
3.线程池参数设置的原则
	3.1 先确定线程池使用场景:
			CPU密集型(计算型的业务场景:数据加密解密、数据压缩、解压等)
				如果是CPU密集型的场景,那么线程会高频的占用CPU,这样线程数尽量不要设置过大,因为线程设置过大,会导致多线程竞争CPU资源,这样会导致线程上下文的切换,带来的开销相对比较大,所以一般建议核心线程数=Cpu核数+1
			IO密集型(比较常见)
				网络IO、磁盘IO等,比较耗时,但是cpu大多数时间是处于空闲状态的,所以为了更加高效利用CPU,核心线程数=2*cpu核心+1

4.分库分表

1.sharding-jdbc框架
1.1 相关名词
	物理表(数据库中真实存在的表)
	逻辑表(逻辑上操作的,是为了方便sharding-jdbc操作物理表而存在的表)
	分片键(物理表中的某个字段)
	节点(物理库.物理表)
	广播表(公共表特点:数据量少,但是各个数据库都会用到)
	动态表(对着某种规则而动态生成的表,比如:股票流水,我们是按照年分库,月分表,但是2023年的月中也有对应的表,但是这表是随着时间,而动态生成)
1.2 sharding-配置
	分库分表的数据源
		指定分库的片键和分表的片键
	默认数据源
		不指定片键的操作,默认就会操作指定的默认数据源
	公共表配置
    	广播表:broadcast
2.如果根据业务分析项目中分库分表的策略?
	根据数据量和维护性的角度,选择选择是否水平分库分表;
	根据冷热数据 垂直分表;
	eg:以股票相关数据为例,分析:
	大盘、板块每年产生的数据不大,但是股票的数据是以时间为维度动态生成的,考虑的维护成本,我们是按照年为单位维护,方便维护;
	但是对于股票流水表,每个月产生的数据动辄800w左右,所以需要水平分表,同时也是按照年分库;
	代码落地思路:
		都是按照年分库,所以可以将年分库的算法公共提取
		其它的分片算法,可自定义;
		同时应该选择时间作为数据分片的片键,因为查询大量关系到时间;

5.权限相关

1.SpringSecurity
	核心的类:
		UserDetailService方法:loadUserByName(name)
		UserDetail:封装了用户的名称 密码 权限集合等信息
		UsernamePasswordAuthentionFilter:内置认证(登录)过滤器
	权限定义的2中方式:
    	方式1:基于配置类配置资源对应的权限
    			eg:antMatcher("资源路径").hasAuthorty("xxxx")
    									.permitAll()
    	方式2:基于注解
        	@PreAuthority("hasAuthorty("xxxx")")
        	@PostAuthroty(xxxx)
2.自定义认证过滤器和授权过滤器
	定义了2个过滤器:
		认证过滤器:模拟UsernamePasswordAuthentionFilter自定实现一套;
		授权过滤器:继承了OnecePerRequestFilter,自定义过滤器
		实现UserDetailService接口方法
		重写权限拒绝策略:AccessDenyHandler接口
		
3.RBAC模型
	核心表结构:5张表
		用户 用户-角色 角色  角色-权限  权限表
	RBAC 两层意思?
    	基于角色的权限控制,问题:角色改动后,代码要做调整,维护性差
    	基于资源的权限控制,维护较好;
5.前端展示需要菜单栏
	菜单栏是树状结构,逻辑层通过递归查询数据,并组装
		id<--->pid	

6.部署

1.nginx
	核心命令:
		nginx 启动
		nginx -s stop 关闭 (-s作用优雅关闭nginx,如果当前nginx正处理请求,则暂时不关闭,如果有新的请求过来,则不处理,直到当前没有要处理的任务,则关闭)
		nginx -t 测试nginx.conf文件的正确性
		nginx -v
		nginx -s reload 重新加载nginx.conf文件
2.nginx的作用?
	2.1 部署静态资源(前后端分离后,前端的静态资源)
		nginx的优势在于静态资源的处理和反向代理,对于动态的请求则交给tomcat处理(动静分离)
	2.2 反向代理
		要说出与正向代理的区别:
			正向代理是客户端知道要访问什么服务器,但是通过代理服务器代理执行;
			反向代理:客户端不知道代理服务帮助我们做了什么处理,说着说客户端任务代理服务器就是处理的服务器;
	2.3 负载均衡(面试)
		1.轮询(默认)
		2.权重
		3.ip-hash
		4.url-hash(第三方)
        5.least-connection
        6.fair
3.项目部署
	理解基于脚本部署的意义和简单使用;	
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值