项目实战典型案例7——在线人员列表逻辑混乱反例
创始人
2024-06-03 02:30:42
0

在线人员列表逻辑混乱反例

  • 一:背景介绍
    • 在线人员列表逻辑混乱反例中涉及到的问题
  • 二:思路&方案
    • 类中写了公共变量最后导致数据混乱现象的解决方案
      • 解决方案1 使用ThreadLocal
      • ThreadLocal的简单使用
      • 解决方案2 将全局变量修改为成员变量
    • 对于在线人员的业务存在逻辑问题(对应上面的 2 4 5 7 )的方案
    • 面向对象继承的问题
      • 面向对象子类与父类中this的使用
    • mysql由于关联字段类型不一致导致索引失效的问题的解决方案
  • 四:总结
  • 五:升华

一:背景介绍

本篇博客是对在线人员列表逻辑混乱反例进行的总结和进行的改进。
目的是将经历转变为自己的经验。通过博客的方式分享给大家,大家一起共同进步和提高。

在线人员列表逻辑混乱反例中涉及到的问题

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

上面的问题主要分为四类问题:

  1. 公共变量导致数据混乱
  2. 对于在线人员的业务存在逻辑问题(对应上面的 2 4 6 )
  3. 面向对象继承的问题,this.属性和方法的问题
  4. mysql由于关联字段类型不一致导致索引失效的问题。

二:思路&方案

类中写了公共变量最后导致数据混乱现象的解决方案

在这里插入图片描述

由于线程共享全局变量,并且在实际业务的过程中对全局变量进行了操作(修改),所以在高并发、多线程的条件下会产生公共变量导致数据混乱的现象。

解决方案1 使用ThreadLocal

ThreadLocal叫做线程变量,该变量对于其他线程而言是隔离的,该变量是当前该线程独有的变量。

它与普通变量的区别在于,每个使用该变量的线程都会初始化一个完全独立的实例副本。正是由于每个线程都有自己的实例副本,且与其他线程不可访问,那就不存在多线程共享该变量的问题。

ThreadLocal 常见使用场景
1、每个线程需要有自己单独的实例
2、实例需要在多个方法中共享,但不希望被多线程共享

ThreadLocal的简单使用

多线程环境下未使用ThreadLocal出现数据混乱的问题

public class Client {public static void main(String[] args) {// 定义线程实现接口Runnable runnable = new Runnable(){Counter counter = new Counter();@Overridepublic void run() {counter.count();}};// 启动10个线程for( int i= 0;i< 10;i++) {new Thread(runnable).start();}}}
public class Counter{private int number;public void count(){for (int i = 0; i <=10 ; i++) {number=number+i;}System.out.println(Thread.currentThread().getName()+ "--"+number;}
}

实现结果
出现数据混乱的问题,正确计算结果应该都为55
在这里插入图片描述
多线程环境下使用ThreadLocal解决数据混乱的问题

public class Client {public static void main(String[] args) {// 定义线程实现接口Runnable runnable = new Runnable(){Counter counter = new Counter();@Overridepublic void run() {counter.count();}};// 启动10个线程for( int i= 0;i< 10;i++) {new Thread(runnable).start();}}}
public class Counter {private static ThreadLocal number = new ThreadLocal() {// 重写这个方法,可以修改“线程变量”的初始值,默认是null@Overrideprotected Integer initialValue() {return 0;}};//计数方法public  void count() {for( int i= 0;i<= 10;i++) {number.set(number.get()+i);}System.out.println(Thread.currentThread().getName()+ "--"+number.get());}
}

实现结果
在这里插入图片描述

解决方案2 将全局变量修改为成员变量

public  void count(){int number = 0;for (int i = 0; i <=10 ; i++) {number=number+i;}System.out.println(Thread.currentThread().getName()+ "--"+number);}}

实现效果
在这里插入图片描述

对于在线人员的业务存在逻辑问题(对应上面的 2 4 5 7 )的方案

在这里插入图片描述
解决思路:由于这里查询的入参带了createDate,如果该学生从第一天到第二天一直没有下课,那么你这儿查询的话由于带了createDate就查询不到该学生的在线数据,在后续的流程中就会重复插入,该学生就会有两条数据,查询的时候就会有数据问题。

在这里插入图片描述
解决思路: 对于isOnline参数,上面paramUser中有该参数。不必再进行赋值。这样的好处是参数值保持了一致,降低了复杂度。
在这里插入图片描述
**解决思路:**这里主要是对在线人员进行下线处理,1.如果在这里更新了update_time那么就相当于这个课程班级中的所有学生的最近一次登陆时间都是一致的,并且最近一次登陆时间与实际不符。2.如果where条件上加上了create_date作为条件那么如果过了十二点结束课程,那么所有在线的人就无法进行下线处理了。

正确的SQL语句:
在这里插入图片描述

面向对象继承的问题

解决思路: 1.子类可以继承父类的所有非private修饰的属性和方法 2.this.方法的问题
在这里插入图片描述

面向对象子类与父类中this的使用

实例结构
在这里插入图片描述
动物类

public class Animal {protected String name="动物" ;protected String age="18";public void printName(){System.out.println(name);}public void printAge(){System.out.println(age);}
}

猫类

public class Cat extends Animal {private String name="猫";public void printName(){System.out.println(this.name);System.out.println(super.name);}public void println(){this.printName();super.printName();}}

调用类

public class Client {public static void main(String[] args) {Cat cat =new Cat();cat.printName();cat.printAge();cat.println();}
}

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

mysql由于关联字段类型不一致导致索引失效的问题的解决方案

在实际的项目开发过程中,需要特别注意关联字段的数据类型是否一致。吐过不一致将导致索引失效,出现mansql的情况。

索引失效的问题复现

EXPLAIN SELECTaui.ding_phone,aui.ding_name,aui.chaoxing_name,aui.chaoxing_phoneFROM(SELECT info_id FROM `arpro_user_course_info` WHERE course_id = '223667994' AND class_id = '55801765' AND is_delete = 0 GROUP BY id)as aucileft JOIN arpro_user_info as aui on auci.info_id=aui.id

arpro_user_course_info与arpro_user_info通过info_id与aui.id进行主外键的关联。

arpro_user_info的id类型为varchar类型
在这里插入图片描述
arpro_user_course_info的info_id类型为bigint类型
在这里插入图片描述
通过EXPLAIN进行sql语句的性能分析
发现arpro_user_info的为全部查询,索引失效了。
在这里插入图片描述

将关联字段的类型修改为一致再次进行测试

在这里插入图片描述
测试结果
索引生效
在这里插入图片描述

四:总结

  1. 在项目开发过程中,对于公共变量的使用一方面需要慎重,需要考虑是否有并发,多线程的情况,然后根据实际情况选择对应的处理措施。
  2. 关于项目开发过程中出现的逻辑问题,一方面进行开发一定需要绘制流程图,根据流程图进行代码编写,另一方面及时总结将经历转变为经验。
  3. 对于面向对象中子类父类的的特点,一方面进行理论学习,一方面特别需要进行实践验证。
  4. 关于sql语句由于级联关联字段类型不一致,出现索引失效的问题需要特别重视,极易出现性能问题。也需要了解其他情况下索引失效。

五:升华

  1. 闭环反馈,是成长型思维的核心
  2. 不怕不知道就怕不知道,扩大认知圈

相关内容

热门资讯

安卓系统重启的图标,解锁设备新... 手机突然重启,是不是心里有点慌?别急,今天就来和你聊聊安卓系统重启的图标,让你一眼就能认出它,再也不...
车载智慧屏安卓系统,智能出行新... 你有没有发现,现在的车载智慧屏越来越智能了?尤其是那些搭载了安卓系统的,简直就像是个移动的小电脑,不...
安卓系统连上网权限,解锁设备无... 你有没有发现,你的安卓手机里有些应用总是偷偷连上网?别小看这个小小的网络权限,它可是能影响你隐私、消...
安卓谷歌操作系统,探索安卓谷歌... 你知道吗?在智能手机的世界里,有一个操作系统可是无人不知、无人不晓,那就是安卓谷歌操作系统。它就像一...
安卓系统手写%怎样调出,具体实... 你有没有遇到过这种情况:在使用安卓手机的时候,突然想用手写输入法来记录一些灵感或者重要信息,可是怎么...
安卓手机重置 系统设置,轻松恢... 手机用久了是不是感觉卡顿得厉害?别急,今天就来教你怎么给安卓手机来个大变身——重置系统设置!想象你的...
win如何安装安卓系统,Win... 哇,你有没有想过,让你的Win系统也能玩转安卓应用?没错,就是那种在手机上轻松自如的安卓系统,现在也...
苹果qq和安卓系统,跨平台体验... 你有没有发现,现在手机市场上,苹果和安卓的较量可是越来越激烈了呢!咱们就来聊聊这个话题,看看苹果QQ...
显示最好的安卓系统,探索最新旗... 你有没有想过,为什么安卓系统那么受欢迎呢?它就像一个魔法盒子,里面装满了各种神奇的魔法。今天,就让我...
安卓app怎么降级系统,系统版... 你有没有发现,有时候安卓手机的系统更新后,新功能虽然炫酷,但老系统用起来更顺手呢?别急,今天就来教你...
雷军脱离安卓系统,引领科技变革... 你知道吗?最近科技圈可是炸开了锅,因为我们的雷军大大竟然宣布要脱离安卓系统,这可真是让人大跌眼镜啊!...
安卓系统自动开网络,安卓系统自... 你有没有发现,手机里的安卓系统有时候会自动开启网络连接,这可真是让人又爱又恨啊!有时候,你正专心致志...
安卓系统怎样控制后台,因为服务... 手机里的安卓系统是不是感觉越来越卡了?后台程序太多,不仅耗电还影响性能。别急,今天就来教你怎么巧妙地...
安卓系统打游戏推荐,一触即达! 你有没有发现,现在手机游戏越来越好玩了?不管是休闲小游戏还是大型MMORPG,都能在手机上畅玩。但是...
开店宝系统和安卓,助力商家轻松... 你有没有想过,开店也能变得如此轻松?没错,就是那个神奇的“开店宝系统”,它可是安卓平台上的一大神器呢...
安卓平板装早教机系统,安卓平板... 你有没有想过,家里的安卓平板除了刷剧、玩游戏,还能变成一个超级早教机呢?没错,就是那种能让孩子从小接...
电脑装安卓系统好处,电脑装安卓... 你有没有想过,你的电脑装上安卓系统会有什么神奇的变化呢?想象一台原本只能处理文档和PPT的电脑,突然...
HTC莫扎特刷安卓系统,畅享全... 你有没有听说过HTC莫扎特这款手机?最近,它可是刷爆了安卓系统爱好者们的眼球呢!今天,就让我带你一起...
安卓系统的致命漏洞,揭秘潜在安... 你知道吗?最近安卓系统可是闹出了一个大新闻,一个致命的漏洞让无数用户都紧张兮兮的。咱们就来聊聊这个事...
安卓的系统文件在哪,安卓系统文... 你有没有想过,你的安卓手机里那些神秘的系统文件都藏在哪个角落呢?别急,今天就来带你一探究竟,让你对这...