SELECT * FROM db_user WHERE username=‘validuser’ OR ‘1’=‘1’ AND password=’’

同样,攻击者可以为password提供如下字符串。

’ OR ‘1’='1

当其注入到命令时,命令就会变成:

SELECT * FROM db_user WHERE username=’’ AND password=’’ OR ‘1’=‘1’

解决思路:

使用java.sql.PreparedStatement代替java.sql.Statement,做一个预编译,例如,select * from db_user where username=? and password=?,然后向PreparedStatement对象中添加对应的属性

public void doPrivilegedAction(String username, char[] password) throws SQLException {

Connection connection = getConnection();

if (connection == null) {

// Handle error

}

try {

String pwd = hashPassword(password);

// Ensure that the length of user name is legitimate

if ((username.length() > 8) {

// Handle error

}

String sqlString = “select * from db_user where username=? and password=?”;

PreparedStatement stmt = connection.prepareStatement(sqlString);

stmt.setString(1, username);

stmt.setString(2, pwd);

ResultSet rs = stmt.executeQuery();

if (!rs.next()) {

throw new SecurityException(“User name or password incorrect”);

}

try {

connection.close();

} catch (SQLException x) {

// forward to handler

} finally {

// forward to handler

}

}

3、不安全的随机数

Java API中提供了java.util.Random类实现PRNG(),该PRNG是可移植和可重复的,如果两个java.util.Random类的实例使用相同的种子,会在所有Java实现中生成相同的数值序列。

例如:下面代码片段中,使用了java.util.Random类,该类对每一个指定的种子值生成同一个序列。

import java.util.Random;

public static void main (String args[]) {

for (int i = 0; i < 10; i++) {

Random random = new Random(123456);

int number = random.nextInt(21);

}

}

解决思路:

在安全性要求较高的应用中,应使用更安全的随机数生成器,如java.security.SecureRandom类。

例如:下面代码片段中,使用java.security.SecureRandom来生成更安全的随机数。

import java.security.SecureRandom;

import java.security.NoSuchAlgorithmException;

public static void main (String args[]) {

try {

SecureRandom random = SecureRandom.getInstance(“SHA1PRNG”);

for (int i = 0; i < 10; i++) {

int number = random.nextInt(21);

} catch (NoSuchAlgorithmException nsae) {

}

}

使用java.security.SecureRandom可以确保是真*伪随机数,详见真伪随机数SecureRandom

4、硬编码的密码

程序中采用硬编码方式处理密码,一方面会降低系统安全性,另一方面不易于程序维护。

例如:下列代码中采用硬编码方式处理密码。

public class ConnectionConfig{

String url = “localhost”;

String name = “admin”;

String password = “123456”;

}

解决思路:

程序中不应对密码进行硬编码,可以使用配置文件或数据库存储的

《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》

【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享

方式来存储系统所需的数据;并且录入数据时,还可以在对敏感数据做加密处理之后再进行数据的录入,对于双向的加密算法可以解密后判断;对于单向的加密算法,可以通过对输入值的再次加密来判断。

可以构造一个属性文件工具类PropertiesUtil和加解密工具类EncryptUtil,把敏感数据加密后存在属性文件中,需要的时候再解码出来调用。比如可以用jasypt加密密码。

例如:下列代码中从配置文件中获取经过加密的密码值并解密使用。

public class ConnectionConfig{

String url = EncryptUtil.decrypt(PropertiesUtil.get(“connection.url”));

String name = EncryptUtil.decrypt(PropertiesUtil.get(“connection.username”));

String password = EncryptUtil.decrypt(PropertiesUtil.get(“connection.password”));

}

jasypt详细使用可查:springboot使用jasypt加密敏感数据

5、SimpleDateFormat的线程不安全

public class DateUtil{

//全局属性 new SimpleDateFormat

private static SimpleDateFormat dateFormatter = new SimpleDateFormat();

/**

  • 格式化时间到毫秒级

*/

public static String longDateFormat(Long time, String dateFormat) {

if (time == null) {

return null;

}

dateFormatter.applyPattern(dateFormat);

return dateFormatter.format(new Date(time));

}

}

这样一个时间工具类,在并发场景下,可能会产生线程不安全的情况,即某些调用者线程会读取到意料之外的日期(非自己输入),出现了幻读。

下图来自网络:

写个单元测试看一下效果:

public class test{

@Test

public void test1() {

//创建自定义线程对象

MyThread mt = new MyThread(“新的线程!”);

//开启新线程

mt.start();

//在主方法中执行for循环

for (int i = 0; i < 100; i++) {

logger.info(“main线程!” + i + DateUtil.longDateFormat(1692517360211l,“yyyy-MM-dd HH-mm-ss”));

}

}

class MyThread extends Thread {

//定义指定线程名称的构造方法

public MyThread(String name) {

//调用父类的String参数的构造方法,指定线程的名称

super(name);

}

/**

  • 重写run方法,完成该线程执行的逻辑

*/

@Override

public void run() {

for (int i = 0; i < 100; i++) {

logger.info(getName()+":正在执行!" + i + DateUtil.longDateFormat(1622517360211l,“yyyy-MM-dd HH-mm-ss”));

}

}

}

}

解决思路:

  1. 可以把SimpleDateFormat对象的创建放到方法内部,当成局部变量来使用,这样的好处是逻辑很简单直接,坏处是每次调用方法都要创建一个SimpleDateFormat对象,浪费堆内存。

SimpleDateFormat dateFormatter = new SimpleDateFormat();

  1. 使用ThreadLocal本地线程类,创建一个只属于每个副本的本地变量,不同线程互不可见从而保证线程安全。(推荐)

//使用ThreadLocal代替原来的new SimpleDateFormat

private static final ThreadLocal dateFormatter = new ThreadLocal(){

@Override

protected SimpleDateFormat initialValue() {

return new SimpleDateFormat(“yyyy-MM-dd”);

}

};

以上代码可以用Lambda表达式简化为:private static final ThreadLocal<SimpleDateFormat> dateFormatter = ThreadLocal.withInitial(SimpleDateFormat::new);

对应的方法修改为:

public static String longDateFormat(Long time, String dateFormat) {

if (time == null) {

return null;

}

dateFormatter.get().applyPattern(dateFormat);

return dateFormatter.get().format(new Date(time));

}

  1. 对代码块加同步锁synchronized,这个在并发大的情况下会显著影响性能

  2. 用Java8提供的DateTimeFormatter替代SimpleDateFormat。这两者最大的区别就是前者是线程安全的,后者线程不安全。(推荐)

  • 使用DateTimeFormatter解析日期

String dateStr= “2021年6月2日”;

DateTimeFormatter formatter = DateTimeFormatter.ofPattern(“yyyy年MM月dd日”);

LocalDate date= LocalDate.parse(dateStr, formatter);

  • 日期转换为字符串

LocalDateTime now = LocalDateTime.now();

DateTimeFormatter format = DateTimeFormatter.ofPattern(“yyyy年MM月dd日 hh:mm a”);

String nowStr = now .format(format);

由DateTimeFormatter的静态方法ofPattern()构建日期格式,LocalDateTime和LocalDate等一些表示日期或时间的类使用parse和format方法把日期和字符串做转换。

使用新的API,整个转换过程都不需要考虑线程安全的问题。

6、null引用

程序间接引用了可能为null的变量,从而引发空指针异常。这种情况需要即使的加非空判断,如何做好非空判断可查链接:Java中对各种类型判空的最优解

也要注意减少无意义的判空语句,比如在对某一对象判空之前已经调用了这个对象的某个属性或方法,如果为null,会提前产生空指针异常,那么就应该提前判空或者try - catch捕捉异常。

7、可以通过try - with - resources优化资源释放

在此不赘述,有兴趣的可看这篇博客【如何高效的使用IO流?】字节流、字符流、缓冲流、序列化对象流、打印流全整理

8、合理使用线程安全类

典型的就是在没有线程安全需求的代码中用了StringBuffer(),这个你可以通过下载一些代码质量检测的插件,会智能提醒你修改成StringBuilder(),当然自己也要有这个意识,根据业务场景和需求来区分。在使用StringBuilder(int capacity) 时候,根据业务情况手动指定初始容量(默认长度为16)。这是因为当StringBuilder内部是一个数组,每次容量不足时,他会产生一个新的大小的数组并将原数组的数据复制,旧数组依然留在堆内存中等待GC回收,在一定时间内会造成内存的浪费。

9、不安全的哈希算法

某些哈希算法是"不太安全的",即有被暴力破解的风险,比如MD5。在安全性要求较高的系统中,应采用比如:散列值>=224比特的SHA系列算法(如SHA-224、SHA-256、SHA-384和SHA-512)来保证敏感数据的完整性。(也可以是其他)

10、对常量CONST的声明

对CONST,如果仅在本类中使用就声明private,如果需要在其他类中调用,就声明public static final (切忌public static)会导致其他类有权限更改常量

11、使用了Number构造函数

Java默认会对整数-128到127之间进行缓存,程序中采用new Integer(int expression)等基本数据类型包装类构造函数来创建对象,而参数的值在-128到127之间,该方法产生的额外对象将占用更多空间、降低性能。

例如:下面代码示例中:使用了new Integer(int expression)来创建对象。

【代码调优】Java开发中总结的代码质量优化技巧,springboot企业级开发教程相关推荐

  1. 前端开发中,对图片的优化技巧有哪些?

    按照先后顺序有以下: 1.去掉无意义的修饰.嗯,我会瞎说吗?除了内容图片,其他的图片的作用是修饰,也就是对于传达信息来说并非本质性的.最大的优化就是压根不要图片!所以在优化之前要做的,首先是确认设计, ...

  2. Go代码调优利器-火焰图

    转自: https://lihaoquan.me/2017/1/1/Profiling-and-Optimizing-Go-using-go-torch.html Go代码调优利器-火焰图 go 调优 ...

  3. 【Spark篇】---Spark调优之代码调优,数据本地化调优,内存调优,SparkShuffle调优,Executor的堆外内存调优...

    一.前述 Spark中调优大致分为以下几种 ,代码调优,数据本地化,内存调优,SparkShuffle调优,调节Executor的堆外内存. 二.具体    1.代码调优 1.避免创建重复的RDD,尽 ...

  4. 机器学习系列(12)_XGBoost参数调优完全指南(附Python代码)

    机器学习系列(12)_XGBoost参数调优完全指南(附Python代码) 原文链接:http://blog.csdn.net/han_xiaoyang/article/details/5266539 ...

  5. weblogic java虚拟机_weblogic server 性能及调优-调优 java 虚拟机.doc

    weblogic server 性能及调优-调优 java 虚拟机.doc 还剩 8页未读, 继续阅读 下载文档到电脑,马上远离加班熬夜! 亲,喜欢就下载吧,价低环保! 内容要点: Sun 已针对 W ...

  6. Linux Page Cache参数调优在kafka中的应用

    文章目录 完整优化方案地址: 一.优化背景 二.基本概念 1.什么是Page Cache? 2.读Cache 3.写Cache 4.Page Cache缓存查看工具 三.参数调优 1.如何查看Page ...

  7. 【编程珠玑】第九章 代码调优

    一,概述 1)代码调优的目的是什么? 减少CPU运行时间:减少分页或增加高速缓存命中率:减少程序所需空间 2)代码调优为什么不能"滥用"? 1>效率的角色:不成熟的优化是大量 ...

  8. XGBoost参数调优完全指南(附Python代码)

    XGBoost参数调优完全指南(附Python代码) 译注:文内提供的代码和运行结果有一定差异,可以从这里下载完整代码对照参考.另外,我自己跟着教程做的时候,发现我的库无法解析字符串类型的特征,所以只 ...

  9. oracle正确使用索引,通过案例学调优之--Oracle中null使用索引

    通过案例学调优之--Oracle中null使用索引 默认情况下,Oracle数据库,null在Index上是不被存储的,当在索引列以"is null"的方式访问时,无法使用索引:本 ...

  10. NC65在日常开发中常用的代码写法

    标题 NC65开发相关代码 版本 1.0.1 作者 walton 说明 收集NC在日常开发中常用的代码写法,示例展示 1.查询 1.1 通过BaseDAO查询结果集并转换 //通过BaseDAO进行查 ...

最新文章

  1. Java设计模式-建造者模式 理论代码相结合
  2. net空间一次购买终身使用_官方解答关于 Internet Download Manager IDM 终身许可证和1年许可证的相关说明!...
  3. ubuntu 搜狗安装搜狗输入法(fcitx)亲测有用
  4. Django08-1:模型层(ORM)--聚合查询/分组查询/F与Q查询/开启事务/常用字段及参数/自定义字段/数据库查询优化
  5. 一文带你了解MySQL中的各种锁机制!
  6. php 中的作用是什么,php中static关键字的作用是什么
  7. Django template 过滤器
  8. iOS 抽奖程序 可指定版
  9. 安装 win7虚拟机
  10. 金立创始人刘立荣:从南下淘金到身价15亿
  11. (立下flag)每日10道前端面试题-15 关于【高级技巧】十问
  12. sin与cos的求法
  13. 恒定电流产生什么电场和磁场_概述理解_电磁学
  14. mybatis日志打印大杀器
  15. 获取Zabbix服务器的密码
  16. arduino的WiFi模块连接使用
  17. MySQL数据库(良心资料)
  18. “Windows 正在配置 Auto CAD 2007,请稍后...”的解决办法
  19. 个人资讯——如何分析业务需求和用户痛点
  20. java用drawline画血条,Java小项目之坦克大战单机1.0版

热门文章

  1. 洛谷P2341 受欢迎的牛
  2. 用云机器/虚拟机架设方舟游戏?
  3. STM32F103 NVIC嵌入式中断控制器
  4. 计算机机房的维护管理论文,计算机机房维护与管理论文.doc
  5. ENA36HD-S10SA9-0413I42-RBD倍加福小型编码器
  6. 获取a标签的src属性
  7. DOS游戏编程二十一条
  8. 社区团购系统开发哪家好 新零售系统厂商如何选择
  9. 自然人投资控股与非自然人投资控股
  10. 小说cmsPTCMS安装