Leetcode review
399. Evaluate Division问题描述:
You are given an array of variable pairs equations and an array of real numbers values, where equations[i] = [Ai, Bi] and values[i] represent the equation Ai / Bi = values[i]. Each Ai or Bi is a string that represents a single variable.
You are also given some queries, where queries[j] = [Cj, Dj] represents the jth query where you must find the answer for Cj / Dj = ?.
Return the answers to all queries. If a single answer cannot be determined, return -1.0.
Note: The in ...
Spring Boot全局异常处理
前言当我们用Spring Boot构建工程的时候,在处理各种复杂的业务需求时往往会涉及到各种各样的异常,比如在进行文件的IO操作时会遇到IOException,FileNotFoundException,在编写SQL语句或使用JDBC时会遇到SQLException,在编写涉及反射相关的代码时会遇到ClassCastException。除此之外还有许多常见的异常如空指针异常NullPointerException,数组下标越界异常ArrayIndexOutOfBoundsException,在使用迭代器遍历集合时修改元素产生的异常ConcurrentModificationException,算数异常(如除0)ArithmeticException等等。
在处理这些异常时无非就是两种选择,最直接最省事的选择是直接使用throws关键字抛出异常,让上层的方法处理异常。另外一种方法就是用try-catch代码块捕捉异常。这两种方法的缺点都很明显,当工程量变大需要处理异常的地方逐渐变多时,如果一个一个的处理异常会显得非常低效,而且也不方便进行统一管理。
那么是否存在一种可以全局管理异常的方法 ...
Spring Boot整合Redis和Redis配置
前言说起Nosql数据库,或者数据库缓存,消息队列,token认证等等应用时,Redis总是大家绕不开的话题。作为一款由C语言开发的运行在内存中进行数据读写的应用,它以高性能和易用性著称。得益于单线程的设计,避免了多线程场景下的锁竞争,从而能做到每秒数十万次的读写操作。同时,Redis还实现了主从模式,哨兵模式和集群模式等分布式解决方案,在保证高性能的前提下提高了可用性和扩展性,成为了开发时不可或缺的组件。
Spring Boot 整合 Redis由于Spring Boot中各种starter的存在,配置redis其实是简单的事情。
首先在pom中导入依赖
1234567891011121314<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency> <groupI ...
Spring Boot 整合日志
前言Java发展至今已经形成了一套完整的日志体系,分为日志门面和日志具体实现。日志门面相当于一个接口,日志各种实现其实就是日志门面的不同实现。
Java的日志加载依赖于SPI,不同于API, SPI模式下接口处于调用者一侧,开发者一侧只拥有具体的实现。而API模式下接口和具体实现都处于开发者一侧,调用者无需关心具体实现,只管调用开发者提供的接口即可。
SPI机制给予了程序动态加载的能力,程序运行的过程中根据接口去动态扫描对应的接口实现类并加载。
举个例子,Java的日志门面Slf4j对应的具体实现有Spring Boot自带的也是默认的logback,还有log4j,log4j2等,在使用时会动态加载classpath中存在的slf4j对应的实现类并把它加载使用,这就是SPI机制。
Logbacklogback是Spring Boot默认使用的日志实现,即使不配置也可以直接使用。
12345678910@SpringBootApplicationpublic class RedisUsageApplication { public static void main( ...
SQL注入和MyBatis对应措施
SQL注入作为一个经典的网络安全问题,sql注入是每一个学习过网络安全课程的同学都多多少少接触过的一个问题。
它的原理其实非常简单,就是通过向sql语句中插入一些特殊的敏感字符,使得查询条件变成恒等从而绕过密码、用户名等的检查直接获取数据库的内容。更有甚者可以通过sql注入导致数据库内容损坏、丢失,产生一系列非常可怕的影响。
下面是一个sql注入的例子。
假如我有一个用于登录的表单,客户端可以输入用户名和密码来提交表单,后端通过对用户名和密码的验证返回数据。
1SELECT * FROM users WHERE username = ${} AND password = ${};
此时,如果一些恶意用户试图输入一些特殊的符号来进行sql注入,如输入用户名为
1' OR '1'='1
原先的sql就会变成一个恒等式
1SELECT * FROM users WHERE username = '' OR '1'='1' AND password = ...
hearthstone database项目总结
写在前面这是一个前后端分离的全栈开发项目。后端采用的技术栈是SpringBoot + MyBatis + MySQL。前端采用的是vue3框架。在项目完成后部署在了AWS云服务上,OS采用的是ubuntu并使用nginx进行了反向代理。
整个项目从收集数据集,清洗数据,整合数据库开始,一直到最终部署在服务器上历时大约10天。其实前后端开发占用时间并不是很长,也没有用到很复杂的技术,主要的时间消耗在于数据库的清洗和整合工作。元数据来自一个第三方的hearthstone网站提供的API(在此非常感谢),但在获取元数据之后发现并不能立刻投入使用,因为存在很多脏数据和一些冗余数据,并且一些数据还存在格式上的不匹配。把这些问题处理完毕耗费了大约3-4天的时间。
本文章用于总结和回顾整个项目开发过程中遇到的问题和主要的工作量。
先贴一张IDEA的项目结构图
整个后端项目采用的是经典的SpringMVC框架,即Controller-Service-Mapper三层。同时也设计了Pojo类以及自定义Typehandler,自定义TypeHandler用于处理数据库查询结果和Java实例之间的映射( ...
设计模式总结
设计模式装饰器模式装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许你动态地为对象添加新的行为,而不改变其结构或影响其他对象。这种模式通过将对象放入一个“包装器”(即装饰器对象)中,以便在保持原始对象类型不变的情况下,扩展或修改其行为。
对象组合:装饰器模式依赖于对象组合(composition),而不是继承(inheritance)。你可以将一个对象嵌套在另一个对象中,从而添加额外的功能。
遵循接口:装饰器和被装饰对象通常都实现相同的接口或继承相同的父类,因此可以互换使用。
动态扩展:装饰器模式可以在运行时为对象添加新的功能,而不像继承那样在编译时就固定了行为。
下面是一个装饰器模式的示例代码
12345// 咖啡的基础接口interface Coffee { String getDescription(); double getCost();}
123456789101112// 具体的基础咖啡实现(被修饰的对象)class SimpleCoffee implements Coffee { @Overr ...
Java集合原理和底层数据结构总结
先放一张集合的层级图
ListList的特点是顺序性,可重复性。
ArrayList允许任何元素包括null。和Vector相比不是线程安全的。在必要时可以用Collections.synchronizedList()来将ArrayList转换成线程安全的List
1List list = Collections.synchronizedList(new ArrayList());
底层维护了一个Object数组用来存储元素。
1transient Object[] elementData;
定义了一个grow()方法,当调用一系列重载的add方法时,会根据是否到达capacity来调用grow()以保证ArrayList的容量满足需求。
PriorityQueuePriorityQueue通过维护了一个小顶堆来保证首元素是所有元素中最小的元素,最小取决于元素实现的Comparator或者Comparable。它也提供了一个构造函数以便传入自定义的Comparator来决定排序的顺序。
1public PriorityQueue(Comparator<? super E&g ...