202211

linux

手把手教你使用VSCode进行linux内核代码阅读和开发
https://zhuanlan.zhihu.com/p/558286384

指定ssh key 克隆代码

git clone git@provider.com:userName/projectName.git --config core.sshCommand="ssh -i ~/location/to/private_ssh_key"

vscode 阅读内核源码配置

对比

  • source insight ,因为内核下有多个平台的头文件、源码,
    往往能找到很多个同名函数或变量的定义,还得一个一个去确认,非常麻烦。
  • vscode 加上 C++ Intellisense 插件或者 global 插件,类似source insight,
    需要手动排除未编译文件减小索引范围,代码定位不准。
  • 文本浏览工具和 grep 进行代码搜索浏览,这种方法最简单,效率也最低。
  • 使用 vim + ctags,比较高大上,但我觉得vim里打开很多文件不太方便,不太适合阅读大工程的代码。
  • vscode + remote ssh + clangd,clangd 插件用于代码语义分析、代码补全、跳转等。
    该方案克服了上面列举的几种方案的几乎各种缺点,能做到代码精准跳转、精准自动补全,

总体流程:

  • 安装 vscode
  • 安装 Remote SSH
  • 连接到远程 linux
  • 远程安装 clangd server
  • 本地安装 clange 插件
  • 配置 clangd 插件
  • linux 相关操作
  • 打开远程 linux 内核目录,等待 clangd 索引完毕
  • ctrl+t 查找符号,f12 查找定义,shift+alt+f12 查找引用,alt+箭头 编辑点跳转

clangd 插件配置

--compile-commands-dir=${workspaceFolder}
--background-index
--completion-style=detailed
--header-insertion=never
-log=info

linux 相关操作:

# 如果 vscode 远程无法安装 clang server,则手工安装
wget https://gitee.com/zhengqijun/clangd/releases/download/15.0.3/clangd-linux-15.0.3.zip

# 安装 bear,生成 compile_commands.json
sudo apt install bear
bear make bzImage ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-

# 如果上面生成的 json 文件无效,再尝试下面的脚本
./scripts/gen_compile_commands.py

了解linux内核必读的五本书
https://zhuanlan.zhihu.com/p/359049747

  • 《Linux内核设计与实现》 简称 LKD,内容比较浅显易懂,个人认为是内核新人首先必读的书籍。
  • 《深入理解Linux内核》简称 ULK,相比于LKD的内容不够深入、覆盖面不广,ULK要深入全面得多。
  • 《Linux设备驱动程序》简称 LDD,驱动开发者都要人手一本了。
  • 《深入理解Linux虚拟内存管理》简称 LVMM,介绍Linux虚拟内存管理机制。
  • 《深入理解LINUX网络内幕》,讲解网络子系统实现的书。

pip3 报错

AttributeError: module 'lib' has no attribute 'X509_V_FLAG_CB_ISSUER_CHECK'

解决

apt remove python3-openssl -y 
apt autoremove

linux 命令示例速查
https://github.com/cheat/cheat
https://mp.weixin.qq.com/s/CEOU9LDSKU05uJSvgLSMZg

查看两个时间点之间的日志

sed -n '/2022-11-01T16:52:40/,/2022-11-01T16:52:42/p' /var/log/nginx/access.log | more

Linux sed命令完全攻略(超级详细)
http://c.biancheng.net/view/4028.html

mmap的几种使用场景
https://www.cnblogs.com/Arnold-Zhang/p/15686868.html
https://izualzhy.cn/mmap

mysql

JSON_TABLE - The Best of Both Worlds
https://dev.mysql.com/blog-archive/json_table-the-best-of-both-worlds/

查看长语句进度
https://www.lanmper.cn/mysql/t8551

select SQL_TEXT,ROWS_EXAMINED,ROWS_AFFECTED,ROWS_SENT, TIMER_WAIT/(1000*1000*1000) wait_ms, LOCK_TIME/(1000*1000*1000)

lock_ms from performance_schema.events_statements_current where SQL_TEXT is not null and TIMER_WAIT/(100010001000) > 100 order by TIMER_WAIT desc\G

  • TIMER_WAIT 事件经过的时间(持续时间),单位是皮秒(万亿分之一秒)
  • LOCK_TIME 等待表锁所花费的时间,该值以微秒为单位计算,但归一化为皮秒,以便与其他性能模式计时器进行比较。
  • ROWS_AFFECTED 语句影响的行数。
  • ROWS_SENT 语句返回的行数。
  • ROWS_EXAMINED 服务器层检查的行数(不计算存储引擎内部的任何处理)。

How to create index on json column in MySQL?
https://stackoverflow.com/questions/38389075/how-to-create-index-on-json-column-in-mysql

CREATE TABLE inventory(
items JSON,
INDEX i1 ( (JSON_VALUE(items, '$.name' RETURNING CHAR(50))) ),
INDEX i2 ( (JSON_VALUE(items, '$.price' RETURNING DECIMAL(5,2))) ),
INDEX i3 ( (JSON_VALUE(items, '$.quantity' RETURNING UNSIGNED)) )
);

SELECT items->"$.price" FROM inventory
WHERE JSON_VALUE(items, '$.name' RETURNING VARCHAR(50)) = "hat";

SELECT * FROM inventory
WHERE JSON_VALUE(items, '$.price' RETURNING DECIMAL(5,2)) <= 100.01;

SELECT items->"$.name" AS item, items->"$.price" AS amount
FROM inventory
WHERE JSON_VALUE(items, '$.quantity' RETURNING UNSIGNED) > 500;

postgre

内核 IO 参数
sysctl -a |grep vm.dirty_background_ratio

推荐配置

40 core, 80 thread @ 2.2Ghz
256GB RAM
16TB NVMe storage (RAID10 usable ~8TB), 28GB/s sequential read, 26GB/s sequential write, 4.9M random read IO/s, 4.4M random write IO/s

可视化执行计划

https://tatiyants.com/pev/#/plans

kill sql

# only select
SELECT pg_cancel_backend(PID);

# can be update, delete
SELECT pg_terminate_backend(PID);

show processlist

SELECT pid, datname AS db, query_start AS start, now() - query_start AS lap, query 
FROM pg_stat_activity 
WHERE state <> 'idle' and query not like '%pg_stat_activity%'  
and (now() - query_start) > interval '1 seconds';

理财

日内做多策略

  • 看 5 分钟级别 K 线
  • 低开,不做
  • 开盘第一条 K 线长上影线,中性,等待,观察第二根 K 线
  • 开盘光头大阳线,做多信号 +1
  • 前一日下午盘在均线上方运行,尾盘稳定,做多信号 +1
  • 前一日高波动震荡,做多信号 -1
  • 开仓后做动态止损,随着价格上升,提高止损位
  • 开仓后第一次斜率变缓不止盈,等待第二次拉升或跌到止损位
  • 开仓后出现震荡,持续 10 根 K 线不创新高后止盈出场
  • 二次拉升后斜率变缓后止盈出场
  • 连续 3 根光脚阴线后止损出场

python 蜡烛图
https://www.statology.org/matplotlib-python-candlestick-chart/
https://www.geeksforgeeks.org/how-to-create-a-candlestick-chart-in-matplotlib/
https://www.highcharts.com.cn/docs/candlestick

大数据

Flink 从 0 到 1 学习
https://github.com/zhisheng17/flink-learning
http://www.54tianzhisheng.cn/2018/10/13/flink-introduction/#

数据分层详解ODS、DWD、DWM、DWS、ADS
https://blog.csdn.net/qq_38730338/article/details/122713887

数据仓库

  • Data warehouse(可简写为DW或者DWH)数据仓库,是在数据库已经大量存在的情况下的一整套包括了etl、调度、建模在内的完整的理论体系。
  • 数据仓库的方案建设的目的,是为前端查询和分析作为基础。
  • 数据仓库并不是数据的最终目的地,而是为数据最终的目的地做好准备,这些准备包含:清洗、转义、分类、重组、合并、拆分、统计等

分层:

  • ODS: Operation Data Store 数据准备区,也称为贴源层
    • 经过抽取、洗净、传输,也就是ETL过程之后进入本层。
    • 为了考虑后续可能需要追溯数据问题,因此对于这一层就不建议做过多的数据清洗工作,原封不动地接入原始数据即可。
    • 来源:
      • 业务库:
        • 离线:sqoop 定时抽取数据;
        • 实时: 使用 canal 监听 mysql 的 binlog 日志
      • 埋点日志:
        • 离线:日志一般是以文件的形式保存,可以选择使用 flume 来定时同步;
        • 实时:spark streaming,Flink、Kafka
      • 消息队列:ActiveMQ、Kafka
  • DWD:数据细节层 data warehouse details
    • 业务层和数据仓库的隔离层,保持和ODS层一样的数据颗粒度
    • 主要是对 ODS 数据层做一些数据的清洗和规范化的操作,比如去除空数据、脏数据、离群值等。
    • 为了提高 ODS 的易用性,该层通常会才采用一些维度退化方法,将维度退化至事实表中,减少事实表和维表的关联。
  • DWM:数据中间层 Data Warehouse Middle
    • 对通用的核心维度进行聚合操作,算出相应的统计指标,提升公共指标的复用性。
  • DWS:数据服务层 Data Warehouse Service
    • 整合汇总成分析某一个主题域,用于提供后续的业务查询,OLAP 分析,数据服务等。
    • 该层的数据表会相对较少,一张表会涵盖比较多的业务内容,由于其字段较多,因此一般也会称该层的表为宽表。
  • ADS:数据应用层 Application Data Service
    • 一般会存放在 ES、Redis、PostgreSQL 供数据产品和数据分析使用的数据。
    • 也可存放在 hive 或者 Druid 中,供数据分析和数据挖掘使用,常用的数据报表应该存在这里。
  • Fact Table: 事实表
    • 指存储有事实记录的表,比如系统日志、销售记录等。
    • 事实表的记录在不断地增长,比如电商的商品订单表
  • Dimension Table:维表层
    • 与事实表相对应的一种表,它保存了维度的属性值,可以跟事实表做关联。
    • 相当于将事实表上经常重复出现的属性抽取、规范出来用一张表进行管理。
    • 高基数维度数据:一般是用户资料表、商品资料表类似的资料表,数量较大。
    • 低基数维度数据:一般是配置表,比如枚举字段对应的中文含义,或者日期维表等,数量较小。

https://blog.csdn.net/weixin_37536020/article/details/106815387
Spark DAG(Directed Acyclic Graph) 有向无环图

概念理解:

  • 一个 Transform 操作(即懒加载方法)转换成一个 RDD。
  • RDD 之间存在依赖关系,最后通过一个 Action 操作函数对数据进行计算。
  • 我们把 RDD 间组成的计算链,称为 DAG。
  • 通过 RDD 间的依赖关系,可以跟踪依赖链找到该分区的父分区,重新计算该分区数据,
    • 采用这种逆推父分区,恢复数据的方式,实现了 RDD 的容错机制。
  • Action 操作对应一个 Job 任务,根据依赖关系,将 DAG 划分为不同的阶段。
  • Task 对应一个分区,一个 Task 就是一个分区,RDD1 有 2 个分区,即 2 个 Task。

RDD 之间的依赖关系:

  • 窄依赖:
    • 父分区和子分区存在一对一的关系,比如:map 、filter、union函数。
    • 不会引入Shuffle的概念,不会发生磁盘 IO 读写。
    • DAG 中连续连续多个窄依赖,会放到一起执行。
  • 宽依赖:
    • 父分区和子分区存在多对多的关系,比如groupBy、sortByKey 等带分组功能函数。
    • 引入了 Shuffle 的概念,会发生磁盘 IO 读写。
    • 宽依赖数据丢失时,可以从 Shuffle 临时文件恢复数据

执行 Job 阶段划分过程:

  • Spark 在执行 Transformation 类型操作时,都不会立即执行,而是懒计算。
  • 执行若干步 Transformation 类型操作后,一旦遇到 Action 操作,才会真正触发计算。
  • 从当前 Action 往前回溯,如果遇到的是窄依赖则应用流水线优化,继续往前找,直到遇到一个宽依赖。
  • 依赖要进行 Shuffle,不执行流水线优化,所以将这一阶段执行过程组装为一个 Stage。
  • 再从当前宽依赖开始向前找,重复刚才的步骤,从而将整个 DAG 划分为若干 Stage。

一文学完Spark常用算子(Spark算子大全)
https://blog.csdn.net/u011109589/article/details/125675177

Spark 算子分为以下三类:

  • Value
    • 输入分区与输出分区一对一型: map flatMap mapPartitions glom
    • 输入分区与输出分区多对一型: union cartesian
    • 输入分区与输出分区多对多型: grouBy
    • 输出分区为输入分区子集型: filter distinct subtract sample takeSample
    • Cache: cache persist
  • Key-Value
    • 输入分区与输出分区一对一: mapValues
    • 对单个 RDD 或两个 RDD 聚集: combineByKey reduceByKey partitionBy
    • 两个RDD聚集: Cogroup
    • 连接: join leftOutJoin rightOutJoin
  • Action
    • 无输出: foreach
    • HDFS: saveAsTextFile saveAsObjectFile
    • Scala: collect reduceByKeyLocally lookup count top reduce fold aggregate
  • 转换算子
    • Value类型: 1. map 2. mapPartitions 3. mapPartitionsWithIndex 4. flatMap 5. glom 6. groupBy 7. filter 8. sample 9. distinct 10. coalesce 11. sortBy
    • 双Value类型: 1. intersection 2. union 3. subtract 4. zip
    • K-V类型: 1. partitionBy 2. reduceByKey 3. groupByKey 4. aggregateByKey 5. foldByKey 6. combineByKey 7. join 8. sortByKey 9. mapValues 10. cogroup
  • 行动算子 1. reduce 2. collect 3. count 4. first 5. take 6. takeOrdered 7. aggregate 8. fold 9. countByValue 10. countByKey 11. foreach 12. save

spark 下载
https://spark.apache.org/downloads.html
https://mirrors.tuna.tsinghua.edu.cn/apache/spark/

wget https://mirrors.tuna.tsinghua.edu.cn/apache/spark/spark-3.3.1/spark-3.3.1-bin-hadoop3-scala2.13.tgz
tar xf spark-3.3.1-bin-hadoop3-scala2.13.tgz
cd spark-3.3.1-bin-hadoop3-scala2.13
./bin/spark-shell --version

Spark:从“大数据的Hello World”开始
https://zhuanlan.zhihu.com/p/407652473

scala> import org.apache.spark.rdd.RDD
import org.apache.spark.rdd.RDD

scala> val rootPath: String = "."
val rootPath: String = .

scala> val file: String = s"${rootPath}/README.md"
val file: String = ./README.md

scala> val lineRDD: RDD[String] = spark.sparkContext.textFile(file)
val lineRDD: org.apache.spark.rdd.RDD[String] = ./README.md MapPartitionsRDD[3] at textFile at <console>:1

scala> val wordRDD: RDD[String] = lineRDD.flatMap(line => line.split(" "))
val wordRDD: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[4] at flatMap at <console>:1

scala> val cleanWordRDD: RDD[String] = wordRDD.filter(word => !word.equals(""))
val cleanWordRDD: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[5] at filter at <console>:1

scala> val kvRDD: RDD[(String, Int)] = cleanWordRDD.map(word => (word, 1))
val kvRDD: org.apache.spark.rdd.RDD[(String, Int)] = MapPartitionsRDD[6] at map at <console>:1

scala> val wordCounts: RDD[(String, Int)] = kvRDD.reduceByKey((x, y) => x + y)
val wordCounts: org.apache.spark.rdd.RDD[(String, Int)] = ShuffledRDD[7] at reduceByKey at <console>:1

scala> wordCounts.map{case (k, v) => (v, k)}.sortByKey(false).take(5)
val res0: Array[(Int, String)] = Array((23,the), (16,to), (15,Spark), (13,for), (9,##))

简化

text_file = sc.textFile("hdfs://...")
counts = text_file.flatMap(lambda line: line.split(" ")) \
             .map(lambda word: (word, 1)) \
             .reduceByKey(lambda a, b: a + b)
counts.saveAsTextFile("hdfs://...")

Spark和Flink的对比,谁才是大数据计算引擎王者?
https://blog.csdn.net/educast/article/details/119929704

Spark详解(02) - Spark概述
https://www.cnblogs.com/meanshift/p/16063784.html

Spark 集群的独立部署环境

  • 不需要依赖其他的资源调度框架,自身就实现了资源调度的功能
  • 环境中还有其他两个核心组件:Master 和 Worker
  • Master 是一个进程,主要负责资源的调度和分配,并进行集群的监控等职责,类似于 Yarn 环境中的 RM
  • Worker 也是进程,一个 Worker 运行在集群中的一台服务器上,由 Master 分配资源对数据进行并行的处理和计算,类似于 Yarn 环境中 NM。

ApplicationMaster

  • Hadoop 用户向 YARN 集群提交应用程序时,提交程序中应该包含 ApplicationMaster,
    • 用于向资源调度器申请执行任务的资源容器 Container
    • 运行用户自己的程序任务 job
    • 监控整个任务的执行
    • 跟踪整个任务的状态
    • 处理任务失败等异常情况。
  • 说的简单点就是,ResourceManager(资源)和 Driver(计算)之间的解耦合靠的就是 ApplicationMaster。

Yarn 环境

  • Client 和 Cluster,主要区别在于:Driver 程序的运行节点位置。
  • Yarn Client 模式
    • Client 模式将用于监控和调度的 Driver 模块在客户端执行,而不是在 Yarn 中,所以一般用于测试。
    • Driver 在任务提交的本地机器上运行
    • Driver 启动后会和 ResourceManager 通讯申请启动 ApplicationMaster
    • ResourceManager 分配 container,在合适的 NodeManager 上启动 ApplicationMaster,负责向 ResourceManager 申请 Executor 内存
    • ResourceManager 接到 ApplicationMaster 的资源申请后会分配 container,然后 ApplicationMaster 在资源分配指定的 NodeManager 上启动 Executor 进程
    • Executor 进程启动后会向 Driver 反向注册,Executor 全部注册完成后 Driver 开始执行 main 函数
    • 之后执行到 Action 算子时,触发一个 Job,并根据宽依赖开始划分 stage,每个 stage 生成对应的 TaskSet,之后将 task 分发到各个 Executor 上执行。
  • Yarn Cluster 模式
    • Cluster 模式将用于监控和调度的 Driver 模块启动在 Yarn 集群资源中执行。一般应用于实际生产环境。
    • 在 YARN Cluster 模式下,任务提交后会和 ResourceManager 通讯申请启动 ApplicationMaster,
    • 随后 ResourceManager 分配 container,在合适的 NodeManager 上启动 ApplicationMaster,此时的 ApplicationMaster 就是 Driver。
    • 后续和 Yarn Client 一样

spark-关于spark分区的理解
https://blog.csdn.net/qq_34224565/article/details/108556055

  • 确切的说,spark 没有分区,是 RDD 有分区。分区是 spark 在内存中进行并行计算时的一块独立的空间,是 RDD 并行计算的最小单元。
  • RDD 的数据集在逻辑上被划分为多个分片,每一个分片称为分区,而每个分区的数值计算都是在一个任务中进行的。
  • 任务的个数,也是由 RDD (准确来说是 job 最后一个 RDD)的分区数决定。
  • 数据源为 hdfs 时,rdd 的分区数由 hdfs 的 block 数决定,类似于 mr 的分片数跟 block 数相同,是考量了磁盘 IO 的性能后作出的选择。
  • 正常情况下,数据源为 hdfs 时,读取时是不需要设置分区数的,设置了反而会影响效率。
  • 分区数越多越好吗?
    • 分区数太多意味着任务数太多,每次调度任务也是很耗时的,所以分区数太多会导致总体耗时增多。
    • 如果一个分区的数据量过小,则 task 的调度会影响效率,如果分区数相对于 cores 过小,则会造成资源浪费。
  • 分区数太少会有什么影响?
    • 分区数太少的话,会导致一些节点没有分配到任务;
    • 分区数太少的话,会导致一些节点没有分配到任务;
    • 分区数不合理,会导致数据倾斜问题;
  • 官方建议 partitionNum 为 executor-cores * num-executor 的 2~3 倍。

分区方式
https://blog.csdn.net/dmy1115143060/article/details/82620715

  • Spark包含两种数据分区方式:HashPartitioner(哈希分区)和RangePartitioner(范围分区)。
  • 一般而言,对于初始读入的数据是不具有任何的数据分区方式的。
  • 数据分区方式只作用于<Key,Value>形式的数据。
  • 当一个 Job 包含 Shuffle 操作类型的算子时,如groupByKey,reduceByKey etc,此时就会使用数据分区方式来对数据进行分区
  • 在 Spark Shuffle 阶段中,共分为 Shuffle Write 阶段和 Shuffle Read 阶段
    • Shuffle Write 阶段中,Shuffle Map Task 对数据进行处理产生中间数据,然后再根据数据分区方式对中间数据进行分区。
    • Shffle Read 阶段中的 Shuffle Read Task 会拉取 Shuffle Write 阶段中产生的并已经分好区的中间数据。

Scala基础教程
https://blog.csdn.net/zzy979481894/article/details/123890912

其它

  • 俗话说:兔子不吃窝边草 可俗话又说:近水楼台先得月
  • 俗话说:宰相肚里能撑船 可俗话又说:有仇不报非君子
  • 俗话说:人不犯我,我不犯人。 可俗话又说:先下手为强,后下手遭殃。
  • 俗话说:男子汉大丈夫,宁死不屈。可俗话又说:男子汉大丈夫,能屈能伸。
  • 俗话说:打狗还得看主人  可俗话又说:杀鸡给猴看。
  • 俗话说:车到山前必有路  可俗话又说:不撞南墙不回头
  • 俗话说:礼轻情谊重        可俗话又说:礼多人不怪
  • 俗话说:人多力量大        可俗话又说:人多嘴杂
  • 俗话说:一个好汉三个帮  可俗话又说:靠人不如靠己
  • 俗话说:人往高处走        可俗话又说:爬的高,摔得重。

电路

德州仪器电路仿真 TINA-TI(TM)模拟器简介
http://training.eeworld.com.cn/TI/video/18813

整流电路
https://blog.csdn.net/cherrychen666/article/details/112986395

Tina-TI——小巧好用又高效的原理图仿真软件
https://zhuanlan.zhihu.com/p/437404464

  • TI 提供了很多仿真样例,包括音频、比较器、控制环路、电流环路、振荡器、功率放大器、传感器等等。
  • 仿真分析包括直流分析、交流分析、傅里叶分析、噪声分析等。
  • 直流分析可以用来测量某一些节点电压和直流传输特性等,如下可以测量某些节点的电压值。
  • 交流分析包括节点电压、振幅、相位、时延、奈奎斯特等。
  • 交流中分析bode图的幅频和相位曲线。
  • 测量工具包括常见的信号分析仪、示波器、XY记录器、函数发生器、万用表。

aws

ddb test

import boto3
from boto3.dynamodb.conditions import Key
ddb = boto3.resource('dynamodb')

test = ddb.Table('test')

print('insert data')
test.put_item(Item={'domain': 'hello.com', 'email': 'hao@hello.com'})
test.put_item(Item={'domain': 'hello.com', 'email': 'jimmy@hello.com'})
test.put_item(Item={'domain': 'gmail.com', 'email': 'onlytiancai@gmail.com'})

print('scan data')
response = test.scan()
for i in response['Items']:
    print(i)

print('query data')
response = test.query(
    KeyConditionExpression=(Key('domain').eq('hello.com') & Key('email').eq('hao@hello.com'))
)
for i in response['Items']:
    print(i)

print('delete data')
test.delete_item(Key={'domain': 'hello.com', 'email': 'hao@hello.com'})
test.delete_item(Key={'domain': 'hello.com', 'email': 'jimmy@hello.com'})
test.delete_item(Key={'domain': 'gmail.com', 'email': 'onlytiancai@gmail.com'})

DynamoDB基本概念
https://zhuanlan.zhihu.com/p/72397412

DynamoDB-二级索引
https://zhuanlan.zhihu.com/p/72610885