【碎片化知识总结】三月第二周
创始人
2025-05-30 14:27:09
0

目录

1、如何给IDEA设置炫酷的背景图片?

2、使用Python执行sql脚本

3、PL/SQL对分库或分表的sql查询

4、如何在spring的controller正确使用非静态成员变量?

5、解决mybatis使用中的实体类名称与表的字段名称不一致问题

6、Java中优雅的停止一个正在运行的线程

7、0.0.0.0,127.0.0.1,localhost的区别?

8、通过xxl-job每天凌晨0点定时重启第一台机器

9、Windows系统中的 win+r 常用查询

10、使用Redis统计网站的用户访问

1、如何给IDEA设置炫酷的背景图片?

只需以下几步,就可以轻松完成设置:

  1. file---settings---keymap:搜索Set Background Image。
  2. 添加一个快捷键:比如ctrl+alt+3,保存并退出。
  3. 下次使用该快捷键,召唤出背景设置弹框,如图所示:
  4. 选择本机图片,调整透明度等。
  5. 效果:

2、使用Python执行sql脚本

背景:最近在工作中经常使用 xxl-job,这是一个分布式的任务调度框架,可以并行的执行复杂的定时调度场景。不过,在正式启动 xxl-job 之前,需要将一些 sql 脚本在 MySQL 数据库跑一下。这里,我并不是复制 sql 脚本语句到数据库执行就完事了,而是想到了用 Python 写个脚本去执行 sql 脚本。

试想一下,如果执行sql脚本数据量较小时,直接复制到数据库客户端执行肯定最方便,但当有成百上千万行语句要执行时,通过Python处理无疑是比较合适的选择。实现步骤,有以下三步:

  • 读取.sql文件;
  • 预处理.sql文件;
  • 执行脚本;

演示代码如下:

import pymysql'''database一定要存在,否则会报错 1049'''
def get_connection():print('开始连接数据库.....')connection = pymysql.connect(host="localhost", port=3306, user="root", --pwd自行填写,database="xxl_job")print('连接数据库ok')return connectiondef process_sql(filename, connection):with connection.cursor() as cursor:with open(filename, "r", encoding='utf-8') as f:sql_list = f.read().split(";")[0:-1]for sql in sql_list:if "\n" in sql:sql.replace("\n", " ")if "   " in sql:sql.replace("   ", " ")sql_item = sql + ";"# print(sql_item)cursor.execute(sql_item)connection.commit()if __name__ == '__main__':con = get_connection()process_sql(r"D:\items\xxl-job\doc\db\tables_xxl_job.sql", con)print("sql执行成功!")

执行效果:

23f5293d1b70e35896dc7fd167055cd3.png

3、PL/SQL对分库或分表的sql查询

PL/SQL 是 Oracle 对 SQL 语言的过程化扩展,指在原有的增删查改的基础上,对 SQL 命令语言中增加了过程处理语句(比如分支,循环等),使 SQL 语言具有过程处理能力。

在数据库表的设计中可能会存在分库或分表的情况。假如有一张表 T_CHG_RECORD,它有16个分库 chg01~chg16,如何统计出该表的总数据量?最简单的方式是写16条 SQL 查询语句了,但肯定还有更高大上的方式,此时 PL/SQL 就可以排上用场,写法如下:

------ 先查CHG01~CHG09
declare v_count number;v_total number := 0;
beginfor idx in 1 .. 9 loopexecute immediate 'select count(*) from CHG0'|| idx ||'.T_CHG_RECORD ' into v_count;v_total := v_total + v_count;--dbms_output.put_line(idx ||':' || v_count);end loop;dbms_output.put_line('total:' || v_total);
end;------再查CHG10~CHG16
declare v_count number;v_total number := 0;
beginfor idx in 10 .. 16 loopexecute immediate 'select count(*) from CHG'|| idx ||'.T_CHG_RECORD ' into v_count;v_total := v_total + v_count;--dbms_output.put_line(idx ||':' || v_count);end loop;dbms_output.put_line('total:' || v_total);
end;

假如有一张表 T_ORDER_RECORD 做分表设计,分为64张表,此时使用 PL/SQL 查询64张表的总数据量就更容易了,写法如下:

---统计2023年之前的订单总数量
declarev_count number;v_total number := 0;
beginfor idx in 1 .. 64 loopexecute immediate 'select count(*) from ORDDB.T_ORDER_RECORD'|| idx ||' t where t.updatetime< to_timestamp(''2023-01-01 00:00:00.0'',''yyyy-MM-dd hh24:mi:ss.ff'')' into v_count;v_total := v_total + v_count;--dbms_output.put_line(idx ||':' || v_count);end loop;dbms_output.put_line('total:' || v_total);
end;

由于 PL/SQL 语法支持循环等逻辑,让查询分库/分表的语句就变得优雅简洁,execute immediate ...... into ...... 是查询的核心语句,根据自己的需求改造即可。

4、如何在spring的controller正确使用非静态成员变量?

Spring的Controller默认是单例的,如果使用了静态非成员变量,且该变量不做同步处理的话,会引发线程安全问题。

举例说明:

@Controller
@Slf4j
public class ScopeTestController {private int num = 0;@RequestMapping("/testScope1")public void testScope1() {log.info("testScope1:{}", ++num);}@RequestMapping("/testScope2")public void testScope2() {log.info("testScope2:{}", ++num);}
}

首先访问 http://localhost:8080/testScope1,得到的答案是1;然后再访问 http://localhost:8080/testScope2,得到的答案是 2。

由此,就产生了线程安全问题了。为避免这种问题,最好不要在类里定义非静态成员变量。如果实在是需要定义该非静态成员变量,那如何正确使用呢?有两种方式:

第一种,使用多例模式,增加@Scope("prototype")注解

@Controller
@Scope("prototype")
@Slf4j
public class ScopeTestController {private int num = 0;@RequestMapping("/testScope1")public void testScope1() {log.info("testScope1:{}", ++num);}@RequestMapping("/testScope2")public void testScope2() {log.info("testScope2:{}", ++num);}
}

第二种,使用 ThreadLocal 保证变量不被修改

@Controller
@Slf4j
public class ThreadLocalController {//    private int num = 0;private static final ThreadLocal num = ThreadLocal.withInitial(() -> 0);@RequestMapping("/test1")public void test1() {int value1 = num.get();if (value1 == 0){log.info("test1:{}", ++value1);}num.remove();}@RequestMapping("/test2")public void test2() {int value2 = num.get();if (value2 == 0){log.info("test2:{}", ++value2);}num.remove();}
}

5、解决mybatis使用中的实体类名称与表的字段名称不一致问题

这是个基础而常见的问题,解决方式有以下两种:

第一种,修改实体类名称,或数据库表的字段使用别名,保持二者名称一致(不推荐这种方式)。

第二种,使用 resultMap 标签,举例如下:

cc733a8e680f41b5bba3411e7d8d7e85.png

6、Java中优雅的停止一个正在运行的线程

<1>. 既然优雅,肯定不能采用 kill 主进程而终止线程的超级暴力方式(不考虑)。

<2>. 调用 Thread 类中的 stop() 方法,这是一个被标记为废弃的线程终止方法,因为 stop 方法会释放锁并强制终止线程,可能造成执行一半的线程被终止,从而造成数据不一致问题(不推荐)。

<3>. 优雅停止线程的最佳实践是,调用 Thread 类的中断方法+中断判断方法(极力推荐)。

代码演示如下:

    @Testpublic void testInterrupted() throws InterruptedException {Thread thread = new Thread() {@SneakyThrowspublic void run() {log.info("线程启动了...");//一直循环while (true) {log.info(String.valueOf(isInterrupted()));Thread.sleep(1000);//如果线程被中断,就退出死循环if (isInterrupted()) {log.info("线程结束了...");return;}}}};thread.start();Thread.sleep(2000); //等待2秒thread.interrupt(); //中断线程}

7、0.0.0.0,127.0.0.1,localhost的区别?

主要区别如下:

0.0.0.0地址,IPV4中被用于表示一个无效的,未知的或者不可用的目标。

127.0.0.1地址,是回环地址的一种(回环地址,指的是所有发往该类地址的数据包都应该被loop back),因此,可以通过使用ping 127.0.0.1 测试某台机器上的网络设备,操作系统或者TCP/IP实现是否工作正常。

localhost,准确的说是一个域名,而非IP地址,用于指代 this computer 或者 this host,可以用它来获取运行在本机上的网络服务。实际上,大多数机器地址都会将localhost映射到 IPV4的127.0.0.1地址,或IPV6的::1地址。

额外补充:

0.0.0.0地址:当一台主机还没被DHCP分配一个IP地址时,表示主机本身。用在服务端时,表示本机上的任意IPV4地址。用作路由时,它表示的是默认路由,即当路由表中没有找到完全匹配的路由的时候所对应的路由。

127.0.0.1地址:需要注意,所有带127网络号的地址都是回环地址,127.0.0.1只是其中一种回环地址。实际应用有,在大多数web容器测试中作为域名localhost所绑定的IP地址。在DDos攻击防御中,将域名指向127.0.0.1,让攻击者自己攻击自己。

localhost:作为域名,需要区分使用的是ipv4还是ipv6。大多数系统,绑定的是IPV4的127.0.0.1地址,或IPV6的::0地址。本机web测试中,一般会使用的是localhost域名。

8、通过xxl-job每天凌晨0点定时重启第一台机器

背景:在做数据稽核项目时,有一台机器隔几天总是出现报错 "java.lang.IllegalStateException: Request cannot be executed; I/O reactor status: STOPPED"。

经过排查发现,基本原因:ES client 内部的调用链为 IOReactor->performRequestAsync的Listener -> onFailure,当短暂抖动触发 onFailure 中抛出异常时,最终导致整个 IO Reactor 不可用,后续请求都受影响,需要重启才能恢复。

因此,通过 xxl-job 配置两个定时任务,于每日凌晨0点定时重启报错机器(要保证凌晨0点左右该机器无定时任务在执行)。在 xxl-job 的 GLUE IDEA 编写脚本代码,做法如下:

每天定时重启第一台机器--kill

#!/bin/bash
echo "xxl-job: hello shell"ssh 用户名@机器IP < . /home/xxw/tmp/audit-kill.shecho "Good bye!"
exit 0

每天定时重启第一台机器--restart

#!/bin/bash
echo "xxl-job: hello shell"ssh 用户名@机器IP < . /home/xxw/tmp/audit-restart.shecho "Good bye!"
exit 0

涉及 shell 脚本:

audit-kill.sh

#!/bin/bashkill -9 `jps |grep 'xxxxx.jar' |awk '{print $1}'`

audit-restart.sh

#!/bin/bashecho "restart begin....."
sh xxxxx/cfg/start.sh start
echo "restart end....."

9、Windows系统中的 win+r 常用查询

使用快捷键win+r,召唤出运行弹框,可以通过 Windows 系统自带的命令打开对应的内容面板。

6c0cd5cc83f941729449bd00fe9fa1a8.png

按功能划分的话,可分为:

计算机管理

compmgmt.msc

-------------【计算机管理】下分项自带命令------------------

# 设备管理器: devmgmt.msc

# 磁盘管理: diskmgmt.msc

# 本地服务: services.msc

# 性能监视器: perfmon.msc

# 本地用户和组: lusrmgr.msc

# 事件查看器: eventvwr

计算机管理

# 任务管理器:   taskmgr   一般使用快捷键ctrl+shift+esc
# 文件资源管理器:   explorer   一般使用快捷键Win+E
# 注册表编辑器:    regedit    (删除某些程序的时候用的到)
# 证书管理器:   certmgr.msc    (查看电脑上的所有证书,不常用)
# 本地安全策略   secpol.msc     (电脑安全方面的设置,不常用,win10家庭版无)
# 组策略编辑器   gpedit.msc      (win10家庭版无)

控制面板

control
-------------【控制面板】下分项自带命令------------------
desk.cpl(桌面设置)
main.cpl(鼠标设置)
inetcpl.cpl(Internet属性)
ncpa.cpl(网络连接)
mmsys.cpl(声音和音频设备)
powercfg.cpl(电源选项)
sysdm.cpl(系统属性)
firewall.cpl(防火墙)

系统自带工具

calc(计算器)

osk(虚拟键盘)

write(写字板)

notepad(记事本)

mspaint(画图)

magnify(放大镜)

snippingtool(截图工具,支持无规则截图 )

mplayer2(简易widnows media player)

Sndvol(音量控制程序 )

关机命令

shutdown -s -t 0(在x秒后关机,x取值0-300,0表示立即关机)
shutdown -r -t 0(在x秒后重启,x取值0-300,0表示立即重启)
tsshutdn(60秒倒计时关机,win10家庭版无)
rononce -p(15秒倒计时关机,win10家庭版无)

以上绝大部分命令,都亲测实用~

10、使用Redis统计网站的用户访问数

有以下几种方案,各有优缺点,可根据实际场景需求选择。

第一种,使用hash数据类型(hset+hlen命令)

使用hset命令,key=网站首页地址+当天日期,field的话,如果用户已登录存放用户ID,如果未登录则随机生成一个唯一标识表示用户ID,value默认设置1。最后统计某天的网站用户访问量时,使用hlen命令即可。

# 模拟用户访问网站首页的过程,第4条命令属于重复用户,不会被重复计入访问人数中的> hset http://123/index.html20230307 user_id1 1
1
> hset http://123/index.html20230307 user_id2 1
1
> hset http://123/index.html20230307 radom_id1 1
1
> hset http://123/index.html20230307 user_id2 1
0
> hlen http://123/index.html20230307
3

这种方式的优点:简单易实现,查询也方便,而且统计准确度高。但是,缺点也很明显:随着key越来越多占用内存会越大,可能出现性能瓶颈。

请注意,对于访问量不高的网站可以使用这种方式,像电商网站就不适用了!

第二种,使用bitmap结构。

bitmap通过一个bit位来表示某个元素对应的值或者状态,其中的key就是对应元素本身。常用命令有:

  • SETBIT key offset value:对key所储存的字符串值,设置或清除指定偏移量上的位(bit)。
  • BITCOUNT key [start] [end]:计算给定字符串中,被设置为 1 的比特位的数量。

正是如此,bitmap常用来做:用户签到、活跃用户、在线用户等功能。这里,setbit命令,key=网站首页地址+当天日期,offset=位的标识(标记1表示一个用户),value默认为1。使用bitcount命令,可以统计该网页每天的访问数量了。

# 模拟使用bitset统计用户访问网站首页的过程
> setbit http://123/index.html20230307 1 1
0
> hset http://123/index.html20230307 11 1
0
> hset http://123/index.html20230307 100 1
0
> hset http://123/index.html20230307 100 1
1
> bitcount http://123/index.html20230307
3

使用bitmap优势在于占用内存少,查询也方便,统计准确率高。不过,对于非登陆用户可能会映射到同一个用户ID,需要区分的话则会增加额外开销。

另外,bitmap适用于非稀疏的用户分布,用户过于稀疏可能比第一种方式更占用内存!

第三种,使用HyperLogLog概率算法。

Redis HyperLogLog 是用来做基数统计的算法,优点是在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、且很小的。

在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 它不能像集合那样,返回输入的各个元素。

当用户访问网站的时候,我们可以使用PFADD命令(Pfadd 命令将所有元素参数添加到 HyperLogLog 数据结构中,格式:PFADD key element [element ...]),设置对应的命令,最后我们只要通过PFCOUNT就能顺利计算出最终的结果,因为这个只是一个概率算法,所以可能存在0.81%的误差。

> pfadd http://123/index.html20230310 a b c d e f g h i j k l m n o p q
(integer) 1
>pfcount http://123/index.html20230310
(integer) 17

优点:占用内存极小,对于一个key,只需要12kb,对于电商网站这种超多用户的特别适用。

缺点:查询指定用户的时候,可能会出错,毕竟存的不是具体数据。总数也存在一定误差。它只能统计在线人数,不能实现其余的任何功能。这种方案仅仅只能统计出某个时间段在线人数的总量, 对在线用户的名单却无能为力,但是却挺节省内存的,对统计数据要求不多情况下 ,我们便可以考虑这种方案。

三月第二周总结梳理,就到这~

相关内容

热门资讯

linux驱动学习加强版-3 ... 文章目录一、用户测试代码二、驱动功能完善。三、open函数的特异性四、代码中的注意事项 一、用户测试...
【Java语法基本问题】记录面... 文章目录包装类单继承Object超类String类接口异常泛型四种引用 包装类 1. 为什么要有包装...
为什么说新一代流处理器Flin...        Flink 被认为是第三代流处理器,这是因为 Flink 在设计时参考了...
第二届辽宁法律人才专场招聘会举... 原标题:第二届辽宁法律人才专场招聘会举办 法治日报讯(记者张国强 实习生窦靖涵)近日,由辽宁省委社会...
律师称两天收到同案相反“判决”... 近日,网上关于“律师称两天收到同案相反‘判决’”引起网民关注。经核,网传案件是平桥区人民法院审理的一...
背包总结(01,完全,多重,分... 本质 从一堆物品中选,选择一些物品,使得这个选择满足某种条件࿰...
shopee API接口:it... 为了进行电商平台 的API开发,首先我们需要做下面几件事情。 1)开发者...
GIS应用技巧之图斑四至坐标计... 一、前言某些时候需要计算图斑的四至坐标,其实坐标不仅在CAD中可以实现,...
使用Hexo+Github搭建... 准备工作:本地需要安装Git,Node.js环境,GitH...