案例17-在线人员列表逻辑混乱-ThreadLocal、继承、索引失效
创始人
2025-05-28 11:52:19
0

目录

    • 背景介绍
      • 现状:
    • 思路&方案
      • 一、类中公共变量由于线程共享,导致的数据混乱(公共变量)
        • 解决方法:使用ThreadLocal变量
        • 结论: ThreadLocal 定义的变量是线程安全的
    • 二、后端本身逻辑漏洞
      • 四、索引失效
    • 总结

背景介绍

本篇博客是对在线人员列表逻辑混乱,前端数据显示出现问题,反例进行的总结和进行的改进。

现状:

在这里插入图片描述

1、类中写了公共变量最后导致数据混乱现象
2、保存数据没有考虑业务的隔夜覆盖导致的逻辑漏洞
3、涉及到继承,对于this,如果父类有同样的成员最终使用哪一个?
4、参数不一致导致后续维护混乱
5、mysql由于关联字段类型不一致导致产生索引失效问题,进而产生慢sql
6、sql不考虑业务导致有明显的逻辑漏洞

上述问题可以分为四类:
1、变量作用域太大
2、后端逻辑本身有问题
3、继承问题,this.属性,和方法具体使用的是哪个
4、mysql索引失效

思路&方案

一、类中公共变量由于线程共享,导致的数据混乱(公共变量)

在这里插入图片描述
所有线程都可以修改全局变量的数据
当咱们不使用多线程的时候不会出现数据错乱的问题,但是当使用多线程且同时修改这个全局变量的时候,就会出现问题了。

解决方法:使用ThreadLocal变量

创建了一个 ThreadLocal类型名为localVar的变量,并且赋初值为 默认localVar
一个打印 localVar值的print()方法
main方法 创建了两个线程:
1、第一个线程操作修改了localVar的值
2、第二个线程直接打印了localVar的值

package org.example;public class Main {static ThreadLocal localVar = ThreadLocal.withInitial(() -> "默认localVar");static void  print(String str){//打印当前线程内存储的本地变量的值System.out.println( str +"   de~~~   " + localVar.get());}public static void main(String[] args) {//创建线程一Thread thread1 = new Thread(new Runnable() {@Overridepublic void run() {//打印一下localvar的值System.out.println("thread1线程" + localVar.get());//修改一下localvar的值localVar.set("thread1的local");//打印print("thread1");}});thread1.start();//创建线程二Thread thread2 = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("线程二不共享localVar变量,值为默认值" + localVar.get());}});thread2.start();}
}

结论: ThreadLocal 定义的变量是线程安全的

结果:从结果上我们可以看出 第一个线程修改了我们定义的localVar的值之后,第二个线程打印的仍是我们一开始初始化设置的默认值

二、后端本身逻辑漏洞

2、保存数据没有考虑到跨天的问题
在查询的逻辑里添加了 createDate的字段,这里的createDate是按照天取得年月日。如果跨天就会出现问题。
在这里插入图片描述
4、参数不一致,导致无法维护
在这里插入图片描述
登录状态问题,这里的状态在之前的业务里,已经传入了,但是后续却用了一个魔法值表示,虽然功能上没有出现问题,但是却多了一个写死的值,不利于复用。

6、sql不考虑业务
在这里插入图片描述
此sql对应的是教师进行结课之后,将学生的最近登录时间修改。这里存在两个问题。

update_time字段的使用,这个是我们数据库建表规范必备三字段(id,create_time,update_time)之一,业务需要应该新建字段,而不是使用update_time字段
额外添加了createDate字段,用当天时间做为where条件,如果跨天的话,就会出现下线状态无法更新问题。

三、继承(this)
在这里插入图片描述
java中继承关系的父子类,相同的方法会被重写
当子类父类中的成员没有重名时,子类都可以通过this去调用。
当成员方法 重名,子类就会将父类中的方法进行重写。如果还想调用父类中的方法只能通过 super去进行调用。
当时成员变量不存在覆盖重写:在子类中只能通过super调用父类的

四、索引失效

在这里插入图片描述

索引会因为 隐示数据转换造成 索引失效的问题。在设置外键的时候,一定要保持与相对应的主键的数据类型一致,否则查询的时候,就会出现不走索引的慢sql,多表联查的时候注意条件的数据类型要保持一致。

总结

边界清晰,胆大心细,是写好代码的重中之重。

相关内容

热门资讯

linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
C++ 机房预约系统(六):学... 8、 学生模块 8.1 学生子菜单、登录和注销 实现步骤: 在Student.cpp的...
JAVA多线程知识整理 Java多线程基础 线程的创建和启动 继承Thread类来创建并启动 自定义Thread类的子类&#...
【洛谷 P1090】[NOIP... [NOIP2004 提高组] 合并果子 / [USACO06NOV] Fence Repair G ...
国民技术LPUART介绍 低功耗通用异步接收器(LPUART) 简介 低功耗通用异步收发器...
城乡供水一体化平台-助力乡村振... 城乡供水一体化管理系统建设方案 城乡供水一体化管理系统是运用云计算、大数据等信息化手段࿰...
程序的循环结构和random库...   第三个参数就是步长     引入文件时记得指明字符格式,否则读入不了 ...
中国版ChatGPT在哪些方面... 目录 一、中国巨大的市场需求 二、中国企业加速创新 三、中国的人工智能发展 四、企业愿景的推进 五、...
报名开启 | 共赴一场 Flu... 2023 年 1 月 25 日,Flutter Forward 大会在肯尼亚首都内罗毕...
汇编00-MASM 和 Vis... Qt源码解析 索引 汇编逆向--- MASM 和 Visual Studio入门 前提知识ÿ...
【简陋Web应用3】实现人脸比... 文章目录🍉 前情提要🌷 效果演示🥝 实现过程1. u...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
windows安装JDK步骤 一、 下载JDK安装包 下载地址:https://www.oracle.com/jav...
分治法实现合并排序(归并排序)... 🎊【数据结构与算法】专题正在持续更新中,各种数据结构的创建原理与运用✨...
在linux上安装配置node... 目录前言1,关于nodejs2,配置环境变量3,总结 前言...
Linux学习之端口、网络协议... 端口:设备与外界通讯交流的出口 网络协议:   网络协议是指计算机通信网...
Linux内核进程管理并发同步... 并发同步并发 是指在某一时间段内能够处理多个任务的能力,而 并行 是指同一时间能够处理...
opencv学习-HOG LO... 目录1. HOG(Histogram of Oriented Gradients,方向梯度直方图)1...
EEG微状态的功能意义 导读大脑的瞬时全局功能状态反映在其电场结构上。聚类分析方法一致地提取了四种头表面脑电场结构ÿ...
【Unity 手写PBR】Bu... 写在前面 前期积累: GAMES101作业7提高-实现微表面模型你需要了解的知识 【技...