JAVA开发中常见问题

这篇具有很好参考价值的文章主要介绍了JAVA开发中常见问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1.深浅克隆问题

2.Mysql中可以代替左模糊或全查询的函数方法

3.开发时需注意,使用String类的equals()方法时,原则上需要左边的变量不能为null值,避免程序执行时出现空指针报错

4.Mysql Update的高效应用

5.Mysql Insert 的高效应用

6.在try-catch-finally代码块中return或者throw Exception时需注意的问题

7.索引过多导致查询的时间不稳定

8.JSON转化为带泛型的集合

9.当时使用Map集合需要在输出时变得有序,可以使用new LinkedHashMap()代替new HashMap()

10.关于使用String.valueOf()时需要关注的问题

11.Mysql高效新增同时更新重复数据

12.CaseInsensitiveMap应用,v>

13.获取List<对象>集合中对象某个字段的集合体,同时去重

14.@Builder注解用法

15.自定义线程池

16.@FeignClient在Application启动时抛出对象重复异常

17.新项目启动时依赖缺失问题

18.idea启动服务时报错Command line is too long

19.List<引用类型>集合排序

20.泛型方法使用

21.静态方法调用Mapper接口

22.Mysql中group by 和 limit 同时使用时注意事项:

23.stream流去重

24.Spring容器跳过指定对象初始化扫描

25. Spring自带的入参判空应用

26.时间戳与日期戳的处理


1.深浅克隆问题

在深浅克隆时一定要注意拷贝的内容如果是基本类型和String类型,还有Integer的-127~128范围可以直接用浅克隆(这些类型在虚拟机都有常量池保存,不会额外新增地址保存值);如果是其他的引用类型则需要使用深克隆来操作(深克隆操作这里不做文章,具体可以参考其他大佬的文章)

2.Mysql中可以代替左模糊或全查询的函数方法

  • LOCATE('keyword',`field`,index)或者LOCATE('keyword',`field`)前者返回值=0时表示field中不存在keyword字符串,如果返回值>0表示存在,此外index表示key在field字段第index个字符开始起第一次出现的坐标值,后者使用的方法相似,只是返回值默认取第一次出现的坐标值;

       例如:select 字段 from 表 where locate(‘检索的串’,字段名,检索起始位置可省略)>0

  • POSITION('keyword' IN 'field')该函数的用法和LOCATE函数没有太大的差异,返回值也是一样的效果;

       例如:select 字段 from 表 where position(‘检索的串’IN 字段名)>0

  • INSTR(`field`, 'keyword') 该函数用法与①②是相近,返回值一样的效果;

       例如:select 字段 from 表 where instr(字段名,‘检索的串’)>0

注意:以上三种函数需要在检索串的所在字段有创建索引情况下才能达到优化效果

3.开发时需注意,使用String类的equals()方法时,原则上需要左边的变量不能为null值,避免程序执行时出现空指针报错

例如:

①Field.equals(“str”)—这是错误的写法

②“str”.equals(Field)—正确的写法

③若两个比较的都是变量,则需提前为左边的变量做好判空处理

if(StringUtils.isEmpty(变量1){

throw e;

}

bollean flag = 变量1.equals(变量2);

4.Mysql Update的高效应用

当我们需要update的表字段关联的条件在其他时,可以这么操作:

Update 表1 别名1,表2 别名2 set 字段1=更新值 where 别名1.条件字段=别名2.条件字段 and 别名1.条件字段=条件值
或者先联查两个表再条件查询更新值
Update 表1 别名1 INNER(LEFT/RIGHT) JOIN 表2 别名2 ON 别名1.联查字段=别名2.联查字段Set 别名1.字段=值 , 别名2.字段=值 where 别名1.条件字段=值

5.Mysql Insert 的高效应用

Insert操作时除了可以利用foreach标签批量插入外,可以利用查询结果作为插入的values

例如:

INSERT INTO 表 (字段1,字段2…)SELECT 字段1,字段2… FROM 表 WHERE 条件1…

以上需要注意的是插入表的字段顺序,数据类型,字段名(别名也有效)必须与查询语句中的一致

当insert表字段与select的表字段名,类型一致时也可以简化为:INSERT INTO 表1 select * from 表2 where 条件1…
注意:这里更推荐使用前者指定字段,因为当表有更新字段时后者可能存在不匹配的情况\

6.在try-catch-finally代码块中return或者throw Exception时需注意的问题

如果三者中均存在return,那么执行的顺序会优先try里的运算表达式但不会马上返回值,而是优先走finally里面的运算表达式,这样try里return的值并不是开始想要的,而finally中return值是不生效的,而是走try或catch中的return值;此外try中出现异常的位置不同也会导致最终的结果不一样

注意**在finally代码块中永远不会只是throw Exception,但是可以是用try-catch代码结果补货异常后打印到日志中**

下面是一个简单的代码测试:

public class test{
    public static void main(String[] args) {
        int result = testMethod();
        System.out.println(result);
        //当异常x生效时,结果为5;当异常y生效时,结果为5;当x/y异常均不生效时,结果是4
    }

    private static int testMethod() {
        int a = 0;
        try {
            int b = 1;
            //int x = 1 / 0;//这里模拟出了异常
            a = a + b;
            //int y = 1 / 0;//这里模拟出了异常
            return a;
        } catch (Exception e) {
            int c = 2;
            a = a + c;
            System.out.println("出问题了:" + e.getMessage());
            return a;
        } finally {
            int d = 3;
            a = a + d;
            return a;
        }
    }
}

7.索引过多导致查询的时间不稳定

当表中索引的数量很多,且explain查询语句时,发现某个表的可能索引有很多个,此时可以在表名后面增加一个force index(索引名)来强制走某一个索引,这样就可以节约的mysql在查询时增加检索索引的时间,提高性能,并且能稳定查询时间

例如:

select 字段 from 表名 force index(索引名) where 条件1 and 条件2 ...

8.JSON转化为带泛型的集合

引用类型<T>  obj = JSON.parseObject(JSON.toJSONString(Object),new TypeReference<引用类型<T>>(){});

常用与JsonRespone<T>,PageResult<T>,Map<K,V> 这种类型的jsonString -> 对象

9.当时使用Map集合需要在输出时变得有序,可以使用new LinkedHashMap()代替new HashMap()

public class test {
    public static void main(String[] args) {
        Map<Integer, Object> map1 = new HashMap();
        map1.put(7, "c");
        map1.put(5, "a");
        map1.put(6, "b");
        System.out.println(map1);//输出结果不会按照key的put顺序输出而是一个随机顺序

        Map<Integer, Object> map2 = new LinkedHashMap();
        map2.put(3, "c");
        map2.put(1, "a");
        map2.put(2, "b");
        System.out.println(map2);//输出结果会按照key的put顺序进行输出
    }
}

10.关于使用String.valueOf()时需要关注的问题

情况一:
String a = String.valueOf(null);
以上再运行时会抛出空指针异常


情况二:
Long b = null;   String a = String.valueOf(b);
综上所述:代码在执行时并不会抛出空指针异常,但是会把null值转化为”null”字符串,从某种意义上会改变原有的代码逻辑

11.Mysql高效新增同时更新重复数据

INSERT INTO 表名 (字段1...) VALUES (值1...) ON DUPLICATE KEY UPDATE 字段1=values(字段1), 字段2=values(字段2);
注意:以上sql需要配合唯一索引使用,并且唯一索引设定有可能会存在冲突问题

12.CaseInsensitiveMap<k,v>应用

CaseInsensitiveMap<k,v>与常规的HashMap<k,v>不同的是,CaseInsensitiveMap的key值是不区分大小写的

13.获取List<对象>集合中对象某个字段的集合体,同时去重

集合对象.stream().map(对象别名(自定义即可)->别名.get字段).distinct().collect(Collectors.toList);

14.@Builder注解用法

在实体类上添加@Builder(toBuilder = true)注解,可以在创建对象时赋值或者重新对一个对象重新赋值,用法上类似@Accessors(chain = true)与链式加载,例如:

①创建新对象
引用类型 对象 = 引用类型.builder().属性1(value1).属性2(value2).build();
②重新赋值对象
对象.toBuilder().属性1(value1).属性2(value2).build();

15.自定义线程池

ThreadPoolExecutor(corePooSize,maximumPoolSize,keepAliveTime,unit,workQueue,threadFactory,handler);

参数说明:

1.corePoolSize -- 核心线程数
2.maxmunPoolSize -- 最大核心线程数
3.keepAliveTime -- 闲时线程最大存货时间
4.unit -- 单位(用于定义最大存活时间)
5.workQueue -- 队列规则
6.threadFactory -- 线程池工厂
7.handler -- 线程异常类型

16.@FeignClient在Application启动时抛出对象重复异常

当同一个服务下有多个feign对象配置了相同的value值(调用同一个服务名),正常情况下会因为对象创建冲突导致异常,这种时候有两种方法解决:
①在yml中配置(允许覆盖重名的对象创建,但是这样就可能不能实现feign的相互独立):
spring:
  main:
    allow-bean-definition-overriding: true
②在每个@FeignClient中添加contextId属性值,作为对象创建时的区分

17.新项目启动时依赖缺失问题

新项目中明明Maven已经正常下载完所有的依赖了,但是在启动服务时还是会出现依赖缺失等异常的问题?

这是因为spring在启动时会忽略pom.xml文件中带<scope>provided</scope>标签的依赖,最终导致依赖出现缺失的问题,解决方法:
①找到这些依赖并注释该标签内容,但需要注意某些项目在上线构建时并不需要这些依赖,所以在上线记得要把注释恢复回来
②(推荐)在idea的启动configurations配置中增加provideds属性配置如图:

JAVA开发中常见问题

18.idea启动服务时报错Command line is too long

idea启动时报错:Error running xxxxx. Command line is too long. Shorten the command line via JAR manifest or via a classpath file and rerun.

这里解决方法有两个:
①(推荐)在idea的启动configurations配置如图:

JAVA开发中常见问题
②在项目的.idea/workspace.xml文件中,找到<component name="PropertiesComponent">,后面在添加一行<property name="dynamic.classpath" value="true" />

19.List<引用类型>集合排序

//按照List中对象的字段属性升序
list.sort(Comparator.comparing(引用类型::get字段))

//按照List中对象的id属性降序
list.sort(Comparator.comparing(引用类型::get字段).reversed());

//多条件升序
list.sort(Comparator.comparing(引用类型::get字段1).thenComparing(引用类型::get字段2));

//id降序
list.sort(Comparator.comparing(引用类型::get字段1).reversed().thenComparing(引用类型::get字段2))

20.泛型方法使用

泛型方法的声明:
修饰符 <T> 返回值 方法名(参数...){...}
*注意<T>是表示当前方法是一个泛型方法,一般在修饰符和返回值中间进行声,明

21.静态方法调用Mapper接口

我们都知道静态方法只能调用静态资源,当静态方法中想调用Mapper接口时,我们是不能在Mapper前面添加static修饰的,那么想要调用Mapper就得换一个思路,Spring在实例化一个bean时会对这个bean中的属性进行赋值,既然Mapper无法成为静态资源那么我们就可以将这个工具类本身作为一个静态资源(对象)去调用,例如:

@Component
public class DemoUtils{
     @Autowired
     private XxMapper xxMapper;

     private static DemoUtils demoUtils;

     //自定义实例化
    @PostConstruct
    public void init() {
        demoUtils = this;
        demoUtils.xxMapper = this.xxMapper;
    }

     public static void method1(参数1){
        //利用已实例化好的静态对象进行调用Mapper
        demoUtils.xxMapper.xx方法(参数1);
   }
}

22.Mysql中group by 和 limit 同时使用时注意事项:

在Mysql中我们经常会使用group by对数据进行分组查询,但是有一种现象需要注意的,即当我们在查询时如果表的可能索引不是唯一的,且查询时join 联查的条件 和 where查询的条件使用的索引不一致,此时如果group by 的字段涉及到这个表时 ,我们在进行limit 分页查询那么可能会出现那么一种现象: group by 后加了limit 查询会很慢,这是因为group 和 limit 同时使用时会重新扫描sql上所有的关联表,最终即使limit 10条数据也会比原来的sql慢上许多;

解决方法:

①使用强制索引(硬核安心),如:

select * from t1 force index(xxx索引) left join t2 on xxx条件 where xxx条件 group by xx字段 limit 0,10

②group by 和 limit 隔离使用,即将原有的sql作为一个子查询再去limt 分页,如:

select * from (...含了group by的sql) limit 0,10

23.stream流去重

一个已知集合List<引用类型>  A,根据A集合中的每个对象的特定字段作为唯一主键去重

①单字段去重

A.stream().collect(Collectors.toMap(引用类型::getXX字段,e->e)).values().stream().collect(Collectors.toList());

②多字段去重(通用型表达,只get一个字段相当于①的表达式效果)

A.stream().collect(Collectors.toMap(e->e.get字段1()+e.get字段2(),e->e)).values().stream().collect(Collectors.toList());

说明: toMap()里面有两段表达时,以","号分隔,第一段表示获取哪些字段作为主键去重,②中的e可以任意命名,表示A集合中的每个元素的变量名;第二段表示去重前的引用类型和去重后需要得到的内容,->e.get字段()可以指定某些字段

在使用流去重时还需要注意,当选取的唯一主键(单字段或多字段)不是一对一时,这个表达式编译时不会异常,但运行时会抛出Duplicate key...的异常,意思就是出现了一对多的关系不可以无法的到Map<k,v>的结构,解决方法:

方法一:

Collectors.toMap(...)改为Collectors.groupBy(e->e.get字段1()+get字段2()..),最终可获取到一个Map<k,List<T>>的结构,这样的话,去重数据时还要做一次遍历封装去重后的数据

方法二(推荐):

优化Collectors.toMap(e->e.get字段1()+get字段2()..,e->e,(key1,key2)->key1或key2),这里(key1,key2)是固定写法表示出现了重复数据,当表达式->key1时表示重复数据只保留前者,同理key2代表后者

24.Spring容器跳过指定对象初始化扫描

我们在分布式项目中经常都是建立子Maven工程集成于父级工程的pom.xml,但是在父级工程中会存在很多公共的依赖,而一些子级工程是不需要的,例如:MYBATIS的JDBC依赖,如果子级工程没有在在yml文件中声明数据库连接的配置,在启动spring容器时就会报错,此时我们又不想增加无用的配置在yml中,我们可以在这个子级的启动类的@SpringBootApplication注解上exclude={类名.class},即可跳过这些类的对象初始化

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, DruidDataSourceAutoConfigure.class})
@EnableEurekaClient
public class ClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(ClientApplication.class, args);
    }
}

这里的DataSourceAutoConfiguration.class 和 DruidDataSourceAutoConfigure.class都是用于数据库连接的配置对象,不一定两个都需要跳过,具体看父级的依赖引入,这里就不做过多的解释了

25. Spring自带的入参判空应用

在实现接口时,我们经常都需要对某些关键入参进行判空,防止空指针异常的出现,但有些公共的入参都是同一个实体类并且关键入参字段都是一样的,我们在每个接口实现都写一次就会出现许多重复的代码,Spring框架就自带了@Valid 和 @Valided注解对入参中的实体类进行判空,以下是代码实现:

//实体类的代码
@Data
public class DemoDto{

@NotEmpty
private String name;

@NotNull
private Long id;

}

 这里在使用时需要注意数据类型

@NotEmpty表示 不能为空串和null值 ,一般用在字符串类型上

@NotNull表示 不能为空,任意的引用类型都可以使用

//控制层代码
@RestController
public class DemoController{

@PostMapping("/test/demo")
public JsonResponse testDemo(@Valid @RequestBody DemoDto param){

    return JsonResponse.success("OK");

}
}

这里需要注意@Valid 和 @Valided注解需要配合实体类上的注解一起使用,否则容器不知道这个实体类需要校验哪些字段为非空入参

26.时间戳与日期戳的处理

在Excel导入时,有时因为某些格式配置导致了日期类型的时间 会 序列成了 数字格式的 字符串,这种字符也是就是我们常见的时间戳,但是时间 也是有几种的,目前了解的场景有3中:

①5位数 这种是因为日期格式中只有年月日转化导致得到了一个天数,可以理解为日期戳,而日期戳的换算如下:

Date date = new Date();
Calendar calendar = Calendar.getInstance();
//获取日期偏移值
long localOffset = (calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET)) / (60 * 1000); //系统时区偏移 1900/1/1 到 1970/1/1 的 25569 天
date.setTime(((Long.parseLong(val) - 25569) * 24 * 3600 * 1000 + localOffset));
//换算得成13位数的时间戳            
long timestamp = date.getTime();

②10位数 这种格式一般是年月日时分秒,去到秒级的的时间戳,转化如下

//10位时间戳
String  timestamp = "1702632914";
Date date = new Date(Long.parseLong(timestamp)*1000);

//获取13位时间戳
long  newTimestamp = date.getTime();

③13位数 这种就是毫秒级别的时间戳,转换如下:文章来源地址https://www.toymoban.com/news/detail-452170.html

// 13位时间戳
long timestamp = 1634567890123L;
 
//时间格式化对象,可以自定义 时间表达式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 
// 将13位时间戳转化为Date对象
Date date = new Date(timestamp);
 
//格式化的时间字符串
String  dateTimeStr = sdf.format(date);

//注意:以上可以通过统一转为13位的时间戳得到正确的 格式化Date对象 或者 时间字符串

到了这里,关于JAVA开发中常见问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Visual Studio 2022创建ASP.NET Web应用程序(.NET Framework)发布并部署到局域网 及“常见权限问题和不列出目录问题解决”】

    然后给项目命名并选择文件保存位置 用一个空项目进行举例 创建完成如下 点击更多模板选择Web窗体 创建成功如下 .aspx页面编写前端代码,.aspx.cs页面编写后端代码 通过插入表格和拉取控件快速完成 然后给Button按钮设置一个点击事件,双击按钮后会跳到.aspx.cs页面,完善下面

    2024年02月07日
    浏览(65)
  • 面试-java常见问题

    程序计数器:当前线程所执行的字节码的行号指示器 java虚拟机栈:临时变量 元空间:类常量池,运行时常量池 方法区:类信息,静态变量 堆:对象实例,Sting常量池等 加载-链接(验证+准备+解析)-初始化-使用-卸载 加载 :将硬盘中的二进制文件转为内存中的class对象 链接

    2024年02月08日
    浏览(40)
  • Java毕业答辩常见问题

    你已经完成了数年的学习和努力,终于迎来了毕业答辩的大日子。而对于Java专业的同学们来说,以下是一些可能会被问到的常见问题,当然,我的回答可能有些幽默,希望能为你带来些许轻松。 这是一个经典的问题,也是一个常被问到的问题。尽管Java和JavaScript这两个编程语

    2024年02月08日
    浏览(38)
  • Java环境配置与常见问题

      在日程办公中Java环境搭建已经是非常基础且重要的一环,许多应用如tomcat、weblogic、zookeeper、kafka、Elasticsearch、hadoop、CDH等等都需要依赖它。 Java环境的搭建也比较简单,在Linux系统上有两种方法:一种是直接安装编译打包好的软件包;另一种是下载归档压缩包解压手动安装

    2024年02月10日
    浏览(40)
  • 音视频开发常见问题(五):视频黑屏

    本文介绍了视频黑屏的可能原因和解决方案。主要原因包括用户主动关闭视频、网络问题和渲染问题。解决方案包括优化网络稳定性、确保视频渲染视图设置正确、提供清晰的提示、实时监测网络质量、使用详细的日志系统、开启视频预览功能、使用视频流回调、处理编解码

    2024年02月08日
    浏览(52)
  • .NET 高级开发人员面试常见问题及解答

    当面试.NET高级开发人员时,面试官通常会围绕技术深度、问题解决能力、项目经验以及编程理念等方面提出问题。以下是20个常见的面试问题及其详细解答: 问题:请简述ASP.NET MVC的工作原理? 解答:ASP.NET MVC是一个基于MVC(模型-视图-控制器)设计模式的Web应用程序框架。

    2024年04月26日
    浏览(34)
  • flink开发常见问题 —— flink-kafka 依赖版本冲突问题

    由于 flink / kafka 的版本不断更新,创建项目的时候就应当考虑清楚这几个依赖库的版本问题,尽可能地与实际场景保持一致,比如服务器上部署的 kafka 是哪个版本,flink 是哪个版本,从而确定我们需要开发的是哪个版本,并且在真正的开发工作开始之前,应当先测试一下保证

    2024年02月07日
    浏览(41)
  • 【Java】缓存常见问题及解决方式

    由于引入缓存首先需要考虑的就是缓存更新的方式,之前在缓存更新的几种模式中我们介绍过。除了这个问题还有一些常见的问题,整理出一个表格,如下图所示: 缓存问题 产生原因 解决方案 缓存不一致 同步更新失败、异步更新 最终一致 缓存穿透 恶意攻击 空对象缓存、

    2024年02月10日
    浏览(37)
  • Java管理系统答辩常见问题

    大家好,今天我来跟大家分享一下Java管理系统答辩常见问题。我会尽可能用幽默的方式介绍这些问题,让大家在轻松愉快的氛围中学习。 这是一个很常见的问题,老师或者评委会问你的系统是否考虑到某个方面。不要慌张,这其实是他们想要了解你们的设计思路和考虑的全

    2024年02月09日
    浏览(43)
  • 实际开发中,React应用常见问题【持续更新中】

    实际开发中,React应用常见问题【持续更新中】 “react-router-dom”: “^6.14.2”, “react”: “^18.2.0”, 1、监听路由 2、路由编程式导航 useNavigate() 3、路由链接导航

    2024年02月15日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包