工作问题汇总

1.SQL相关


1.mysql中单双引号都表示子符串,as 起别名时,使用反引号(尤其是中文),也可以不添加反引号,当错误使用单双引号时会出现sql语句正常执行,结果不符合预期。

2.sql语句尽量不要写在for循环,考虑使用批量增删的方式

3.聚合查询 + order by rand()

(SELECT c.id FROM c_course_menu cm 
 JOIN c_course c ON cm.id = c.menu_id 
 AND cm.course_type = '2' 
 AND c.id IN
    (SELECT relation_id 
     FROM c_post_course pc 
     WHERE post_id = #{postId} 
    )  
                                   
ORDER BY rand() 
LIMIT 2
)

 UNION

(SELECT c.id,c.price
 FROM c_course_menu cm
 JOIN c_course c
 ON cm.id = c.menu_id
 AND cm.course_type = '3'
 AND c.id IN (
     SELECT relation_id
     FROM c_post_course pc
     WHERE post_id = #{postId}
             )
ORDER BY rand() LIMIT 2
)

UNION的作用

UNION运算符用于组合两个或更多SELECT语句的结果集。

UNION会对结果进行去重处理,如果不关心是否去重,可以使用union all 替代union以提升sql执行效率

UNION使用前提

    UNION中的每个SELECT语句必须具有相同的列数

  • 这些列的数据类型必须兼容:类型不必完全相同,但是必须可以隐式转换。
  • 每个SELECT语句中的列也必须以相同的顺序排列[即类型的顺序需要保持一致

一张表可以考虑来连结多次

连结表后可以考虑追加筛选提条件

一个经典问题:

SELECT A*

FROM A

LEFT JOIN B

ON A = B

INNER JOIN C

ON B = C 

B表中没有数据时,会导致查询查询出来的全部为空
表联结时,会先连结AB的结果,再追加C的结果,其中C的结果是根据B来的

 sql排查:

  • 一张表可以考虑连接多次,sql逐级排查

  • 子查询中查询失败(列不存在),程序也有可能正常执行

    排查sql时,要查验所有的sql条件

     数据库全局搜索时,ctrl + f 当前页没有时,切换分页

一种特殊写法 

JOIN( SELECT DISTINCT(business_id),id,check_desrc,create_time,check_status,create_by FROM d_workflow_check ORDER BY create_time DESC )

批量添加

Map

# forEach的属性括号,不会参与循环,只有作为标签体的内容时,才会参与循环
<insert id="batchAddCourse">
        INSERT INTO c_course_user (id, user_id, course_id, create_by,
        create_time, update_by, update_time)
        values
        <foreach collection="map" item="item" index="index"
                 separator=",">
            (#{index}, #{userId}, #{item}, #{createBy}, #{createTime},
            #{createBy}, #{createTime})
        </foreach>
    </insert>

4.动态增减可以考虑 

// 统计增加和减少了多少
public Map<String, String> compare(String a, String b) {
    String[] listA = a.split(",");
    String[] listB = b.split(",");
    Set<String> setA = new HashSet<>(Arrays.asList(listA));
    Set<String> setB = new HashSet<>(Arrays.asList(listB));
    Set<String> addedData = new HashSet<>(setB);
    addedData.removeAll(setA);
    Set<String> removedData = new HashSet<>(setA);
    removedData.removeAll(setB);
    String addedResult = String.join(",", addedData);
    String removedResult = String.join(",", removedData);
    Map<String, String> result = new HashMap<>();
    result.put("add", addedResult);
    result.put("reduce", removedResult);
    return result;
}

判断两个字符串是否相等方法

public boolean isDataEqual(String str1, String str2) {
    // 将字符串按照逗号分隔成字符串数组,并去除空格
    String[] arr1 = str1.split("\\s*,\\s*");
    String[] arr2 = str2.split("\\s*,\\s*");
    // 将字符串数组转换为Set集合
    Set<String> set1 = new HashSet<>(Arrays.asList(arr1));
    Set<String> set2 = new HashSet<>(Arrays.asList(arr2));
    // 判断两个Set集合是否相等
    return set1.equals(set2);
}

5.考虑使用事务
 

事务的应用场景:当你需要保证且通过数据事务可以保证多个操作的ACID的时候。

简单点说就是多个写操作要么一起成功,要么一起失败的时候就需要用事务。

@Transactional失效问题:
注意是通过Spring的AOP功能进行实现的,因此想要正常生效,必须动态代理生效,并且可以调用到代理对象的方法。

  • 类内部方法调用,这时方法的调用者是this而非代理对象。
  • 静态方法调用,静态方法是属于类的,而非对象。
  • final方法,无法对子类方法进行覆盖

6.使用流的方式优化集合的操作方式

遍历原有集合,将其添加进新的集合

Set<CourseUserVO> courseUserVOList = new HashSet<>();
String orderId = GlobalRecIdUtil.nextRecId();
courseUserVOList = courseIdList.stream()
        .map(o -> {
            CourseUserVO courseUserVO = new CourseUserVO();
            courseUserVO.setId(GlobalRecIdUtil.nextRecId());
            courseUserVO.setCreate_by(userId);
            courseUserVO.setUser_id(userId);
            courseUserVO.setCourse_id(o);
            courseUserVO.setOrder_id(orderId);
            return courseUserVO;
        })
        .collect(Collectors.toSet());
List<String> parkIdList = authorizeParkList.stream()
        .map(AuthorizeParkVO::getSmart_park_id)
        .collect(Collectors.toList());

批量向集合中添加多个对象

List<AlertVO> alertVOList = new ArrayList<>();
AlertVO todayAlertNumAndGrowth = alertMapper.getTodayAlertNumAndGrowth();
AlertVO currentMonthAlertNumAndGrowth = alertMapper.getCurrentMonthAlertNumAndGrowth();
AlertVO currentYearAlertNumAndGrowth = alertMapper.getCurrentYearAlertNumAndGrowth();

Stream.of(todayAlertNumAndGrowth, currentMonthAlertNumAndGrowth, currentYearAlertNumAndGrowth)
        .forEach(alertVOList::add);

7.Find IN Set

FIND_IN_SET函数 是一个比like关键字更加高级的精确查询匹配

用法:find_in_set('欲查找的值', '被查找值的集合,用英文逗号隔开')

user表与岗位表作关联关系
FROM sys_user u
LEFT JOIN c_post p ON FIND_IN_SET(p.id, u.post_id)

8.全局变量

使用全局变量要考虑清除的问题

9.Set和List

Set集合10万条数据同List相比,相差20ms

10.程序启动

项目启动失败:

日志提示的原因可能,有可能不是根本原因

需检查是否是以maven的格式进行打开的

11.Mybatis相关原因导致程序启动失败

1.mapper文件出现了根本的语法错误,<include>没有引用sql标签,引用了其它的<insert>
2.标签体不完整
3.文档逗号等与xml无关的符号
4.mappr注入失败:检查注入mapper的位置,是否在mapper文件夹下
5.全局的类型别名优于@Alias便签,在IDEAresultType中点击简写的实体对象可以跳转

12.缓存相关

 浏览器缓存是一种机制,它可以将一些静态资源(如HTML、CSS、JavaScript、图像等)保存在用户的本地计算机上,以便在后续的访问中能够更快地加载这些资源,提高网页的加载速度和性能。

通过浏览器缓存机制,可以减少对服务器的请求次数,节省带宽和提高网页加载性能。
怀疑某些原因是浏览器问题造成的,可以在浏览器的调试模式中停用页面缓存

命中率
缓存的一种有效性指标

缓存的成本:

考虑到缓存穿透、缓存击穿、缓存雪崩等因素

  • .数据一致性成本
  • 代码维护成本
  • 运维成本

13.跨域问题处理

跨域:域名不一致就是跨域
主要包括:

  • 域名不同:www.taobao.com 和www.taobao.org
  • 域名相同,端口不同:localhost:8080和localhost:8081

跨域问题解决:

  • 使用拦截器
  • @Crossorigin
  • 实现WebMvcConfigurer接口,进行跨域的@Bean的配置

14.List->String

org.apache.commons.lang3.StringUtils,同时建议所有对字符串处理都使用该工具类
ying
需求场景:新闻发布时,将dto中List<Image>,保存到新闻的实体类中。
 if(dto.getImages() != null && dto.getImages().size() > 0){
            String imageStr = StringUtils.join(dto.getImages(), ",");
            wmNews.setImages(imageStr);
        }

15. 浏览器输入url

一个标准的URL通常由以下几个部分组成:

协议(Protocol):URL的开头部分通常指定了用于访问资源的协议,如HTTP、HTTPS、FTP等。

主机名(Host):主机名指示了资源所在的服务器的域名或IP地址。例如,www.example.com或192.168.1.1。服务器的位置

端口号(Port):端口号是一个可选的部分,用于指定访问服务器上特定服务的端口。如果未指定,默认使用协议的默认端口,如80(HTTP)或443(HTTPS)。服务器上通常部署多台web应用,每个应用程序占用一个端口。

路径(Path):路径表示服务器上资源的具体位置。它以斜杠(/)开头,后面可能跟着文件路径或目录结构。

查询参数(Query):查询参数是一些附加信息,以问号(?)开头,用于传递给服务器的参数。参数以键值对的形式存在,例如?key=value。

片段标识(Fragment):片段标识用于指示资源中的特定部分。它以井号(#)开头,通常在网页中用于定位页面中的锚点

16. Stream API相关

Stream.map()是Stream最常用的一个转换方法,它把一个Stream转换为另一个Stream。
所谓map操作,就是把一种操作运算,映射到一个序列的每一个元素上。例如,对x计算它的平方,可以使用函数f(x) = x * x。我们把这个函数映射到一个序列1,2,3,4,5上,就得到了另一个序列1,4,9,16,25:

List<TrafficFlowVO> slowSpeedWayList = uniqueYearList.stream()
                .map(year -> limitTrafficFlowVOList.stream()
                        .filter(trafficFlowVO -> trafficFlowVO.getYear().equals(year)
                                && trafficFlowVO.getHighway_type() == 1
                               )
                        .findFirst()
                        .orElse(new TrafficFlowVO(0L, year))
                    )
                .collect(Collectors.toList());

简记: 都有一个的情况下可以省略

  • 如果小括号内有且仅有一个参数,则小括号可以省略

  • 如果大括号内有且仅有一个语句,可以同时省略大括号,return 关键字及语句分号

     

17.前端取值

 this.data可以获取数据,生命周期函数的this指向为vm

export default {
  name: "TrafficFlow",
  data() {
    return {
      // 图表ID
      myChart: Math.random(),
      // 图表数据
      data: {
        "id": "multipleBarsLines",
        "legendBar": ["高速公路", "城镇公路"],
        "symbol": " ",
        "legendLine": ["环比"],
        "xAxis": [],
        "yAxis": [[], []],
        "lines": [[],[] ],
        "barColor": ["#009883", "#e66922"],
        "lineColor": ["#fd6665", "#fba73b"],
      },
    };
  },

18.前端概念

组件  

组件:局部功能代码(html、css js)和资源(mp3 mp4 ttf .zip)的集合

当某个css发生修改时,需考虑其它页面的引入情况 


单文件组件:一个文件包含一个组件,.vue结尾

非单文件组件: 一个文件包含多个组件,.html结尾

生命周期

mounted() {} 完成模板的解析,并把初始的真实dom放在页面中 ,即挂载完毕之后,即{{}}在页面成功解析之后

AJAX

AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)
最大的优点是可以在不重新加载整个页面的情况下,完成局部的刷新

异步:发送请求后,无需等待响应,继续执行后续操作
同步:发送请求后,需要等待成功响应后才能继续执行后续操作 

实现:JQUERY的实现与Axios实现 

this关键字

vue2:

在Vue.js中,当你想要在data对象中访问或修改一个变量时,你应该使用this关键字。这是因为data对象是Vue组件的一个属性,而this指向的是当前组件实例。

当你在模板中引用一个data对象中的变量时,Vue会自动为你添加this。例如:

data() {
  return {
    message: 'Hello'
  }
}

在模板中使用message变量时,应该这样写:

<p>{{ message }}</p>

如果你要在Vue组件的方法中调用一个data对象中的变量或方法,同样需要使用this关键字。例如:

methods: {
  greet() {
    console.log(this.message);
  }
}

在方法中使用message变量时,应该写成 this.message

请注意,在Vue组件的生命周期钩子和计算属性中,也应该使用this来访问data对象中的变量。 

总结来说,当你需要在Vue组件中访问或修改一个data对象中的变量时,都应该使用this关键字
在vue的钩子函数调用其它函数时,前面必须加this

19.jar包与war包区别

jar文件(扩展名为. Jar,Java Application Archive
war文件(扩展名为.War,Web Application Archive)

JAR和WAR都是Java的归档文件(打包格式),用于打包和分发Java应用,但用途和内容有所不同。JAR用于通用目的,打包Java类文件和相关元数据和资源,可以直接运行。WAR专门用于JavaWeb应用,包含JSP、HTML、javascript和其他web资源,需要部署到支持Java的servlet容器中才能运行。

19.检查依赖冲突

使用Maven或Gradle等构建工具,运行依赖树命令(如mvn dependency:tree),查看是否存在重复或冲突的库。如果有冲突的库,请调整你的pom.xmlbuild.gradle文件以消除冲突。

20.日志性能优化

21.全局异常

单体项目中的全局异常处理由@ControllerAdvice +  @ExceptionHandler实现
可以任务它是一个异常拦截器。

微服务中的全局异常处理一般在Gateway网关中处理,如不进行全局异常处理,会导致直接返回的是错误页面

22.本地缓存和Redis缓存的使用场景

本地缓存适用于以下场景:

  • 对数据及时性要求不高,可以容忍一定的数据延迟

Redis缓存使用场景:

  • 对数据及时性要求较高,需要实时更新

本地缓存可以避免不必要的网络io操作,相较于Redis缓存而言性能更好,通常本地缓存作为一级缓存使用,Redis缓存作为二级缓存使用。

23.Maven常用命令

install命令会根据项目中的POM信息,将依赖引入本地Maven库中,注意:在某些情况下,引入的jar包可能损坏。

  • 23
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值