自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(88)
  • 收藏
  • 关注

原创 代码之丑第一期-缩进

是的,我刚开始都不信,不过这是Jeff Bay在对象健身操中指出的:拒绝使用else关键字,同样震撼的还有其他观点,如:每个方法只使用一级缩进,方法的长度不要超过5行。好吧,这是高情商的说法,大家应该也知道了,它的问题是嵌套的太深,缩进太多。上面的例子也是我最近开发遇见的一个case,我需要判断当前时间是否为静默时间,如果是,则继续判断阈值是否有效,如果无效直接返回,如果有效则执行对应逻辑;有一个标准来专门衡量我们今天的内容:圈复杂度,它的值越高,代码的复杂性就越高,理解和维护代码的难度也就越大。

2024-12-01 23:09:12 847 1

原创 分析为什么ArrayList、HashSet以及HashMap是线程不安全的

学习的时候都知道这三个是线程不安全的,但为什么是线程不安全的、具体在哪里不安全了却不太了解,这篇文章尝试分析一下。ArrayList它不安全的情况主要有这么几种(前提是多线程环境下):add元素之后,会出现有些位置的值为null的情况数组下标越界size大小不是预期的值下面分别对上述现象做出解释。出现null的情况先来看一下add方法的源码:private void add(E e, Object[] elementData, int s) { if (s == element

2021-09-15 13:17:04 719

原创 设计模式之装饰器模式

假设你有若干辆车,还有若干型号的配件,每个车都可以和某种配件组装,因此每种组合的价钱也不同。例如,有车A、B和C,配件有W1、W2和W3,那么,A和W1是一种组合,B和W1、W2也是一种组合,即车可以和一种或多种且数量不限的配件组合。应该如何设计呢?方案1 容易想到的方法先弄一个抽象类Car,所有的类都继承Car。如果只买车不买配件,那就是上图中的方框A,如果要计算价钱的话,直接让A实现Car中的computeCost方法就好了;如果想买车A和配件W1的话,就新建一个类,然后实现computeCo

2021-08-20 19:24:21 207

原创 设计模式之观察者模式(Java)

打个比方,有一家做天气预报服务的公司A,对外提供天气信息查询得服务。哪个公司想使用这个服务就向A去注册,A会在天气信息变化时将更新后的消息及时的推送给注册了的公司。在这里MyObservable类就是公司A:public class MyObservable { private int data; // 这个就是天气得数据 private List<ObserverInterface> list; // 这个是注册进来的观察者 public MyObservab

2021-08-20 16:38:03 185

原创 源码分析为什么多线程操作ArrayList时会出现ConcurrentModificationException异常

我们知道,ArrayList是线程不安全的,在多线程操作的时候会出现ConcurrentModificationException异常,其实在遍历时删除元素也会出现这个异常,但这种情况在单线程中也会出现(使用iterator即可解决),因为本文的重点是分析多线程情况下的异常,所以单线程先不说。先来看一段会出现异常的代码(这里以add为例):public static void main(String[] args) { ArrayList<String> list1 = new Ar

2021-07-14 22:45:47 1099

原创 几种最长XX类型的动态规划题目

无重复最长子数组遍历数组,每到一个新的位置i就看这个数字在之前是否出现过,如果没出现过直接dp[i] = dp[i-1] + 1,如果出现过,就看看i和之前出现过的位置的距离d是否比dp[i-1]大,要是大依然dp[i] = dp[i-1] + 1,(如 ayxyza,第二个a出现的位置下标是5,第一个a下标是0,相减等于5,而dp[4]=3,所以可以把这个a算进来);但如果d比dp[i-1]小,那么dp[i]就只能是d了(如abcb,b第一次是1,第二次是3,d=3-1=2,而dp[2]=3,所以dp[

2021-07-08 15:46:42 228 1

原创 leetcode147-链表排序(使用插入排序)

插入排序就是,初始时第一个数肯定是有序的,然后看第二个数,如果比第一个数小,那么就将第一个元素后移到第二个位置,然后将原第二个位置的元素插入到第一个位置;接着看第三个数…以1 3 2为例,初始时1自己肯定有序,然后看第二个元素3,比1大,所以继续看第三个元素2,它比3小,但比1大,因此将3右移到3位置,然后2插入到第二个位置:1 2 3.public ListNode sortInList(ListNode head) { // write code here if (head == n

2021-07-06 14:47:42 116

原创 leetcode刷题记录

二分如果一个排序数组中的元素互不相同,那么按照二分查找会返回目标元素的下标。如果有重复的元素,并且我们想得到第一个重复元素的下标,那么可以用如下代码: private int binarySearch(int[] nums, int target) { int l = 0, r = nums.length-1; while (l <= r) { int m = l + ((r-l)>>1);

2021-05-26 11:30:38 488 1

原创 JUC之Callable

Callable在java5之后实现多线程的方式由两种变为四种,这里先看实现Callable接口的方式。但之前两种创建线程的方式用的好好的,为什么又增加了两种呢?新技术的出现一定是为了解决老技术出现的问题,那么就要问,老技术有什么问题?我们不妨先对比一下,实现Runnable接口和实现Callable接口的代码有什么不同。Runnableclass MyThread1 implements Runnable { @Override public void run() {

2021-04-25 18:14:46 165

原创 Java 字符运算,与数字的运算

字符与字符进行加减运算此时会先将字符转换为ASCII码,将二者ASCII码值相加。char i = '3' + '0';int j = '3' + '0';i的值为c,j的值为99,因为字符c的ASCII码为99字符与数字进行加减运算会将字符转换为ASCII码,然后和数字相加。char i = 3 + '0';int j = 3 + '0';i的值为3,因为字符0的ASCII码为48,加3后为51,而51正好是字符3的ascii码;那么很显然j的值就为51字符与数字之间的转换如果有

2021-04-16 21:43:51 6193

原创 JVM 类的加载子系统

Java代码的执行流程操作系统并不识别字节码指令,它只识别机器指令,而执行引擎的作用就是将高级语言翻译成机器指令。JIT编译器将字节码指令编译成机器指令(第二次编译,第一次是将java源码编译为字节码),同时将需要反复执行的热点代码缓存起来。JVM架构模型JVM生命周期我们写的类是通过系统类加载器加载的,而Object是通过引导类加载器加载的。一些JVM虚拟机类加载器类的加载过程这个过程分为三个环节:加载链接初始化先来看加载(类的加载是一个广义上的概念,这里的加载

2021-03-06 16:49:38 118 1

原创 最小生成树之克鲁斯卡尔(Kruskal)算法及其实现

这里就简单说一下步骤:先在所有边中选一条权值最小的检查这条边和结果集中的边是否构成了环,如果构成环,则回到第一步重新选择除这条边外权值最小的边;如果不构成环,那么将这条边加到结果集中重复上述过程直到所有的点都出现在结果集中用一个例子来理解:上图计算最小生成图的步骤如下:先选AC,AC并没有与结果集中的其他边(此时为空)构成环,因此将AC放到结果集中选CD,与结果集中的边(AC)不构成环,因此将CD放到结果集中选AB,同样不构成环,将AB放到结果集中选AD,此时与结果集中的边构成环(

2021-02-23 10:52:38 917

原创 剑指offer43(leetcode 233),1-n整数中1出现的次数

这里主要记录一下时间复杂度为 O(数的位数) 的方法,原作者大神的解答在:https://leetcode-cn.com/problems/1nzheng-shu-zhong-1chu-xian-de-ci-shu-lcof/solution/mian-shi-ti-43-1n-zheng-shu-zhong-1-chu-xian-de-2/对于一个整数,它的位数是多少位呢?不妨举几个例子:如果是99,很显然,它是两位100,是三位可以用log10(m),即以10为底,m为给出的数来表示一个数能

2021-02-19 17:21:44 129

原创 各种排序算法及复杂度、稳定性(左神算法班)

对数器时间复杂度是指常数操作的数量级,以冒泡排序为例:第一次在0 - n-1 范围内找一个最小的数和0位置的数交换,这个过程需要找n次,每次都需要执行取数、比较和交换三个常数操作,因此常数操作需要进行n次第二次在1 - n-1 范围内找一个最小的数和1位置的数交换,这个过程需要找n-1次,每次都需要执行取数、比较和交换三个常数操作,因此常数操作需要进行n-1次重复上述过程那么最后常数操作的次数是(n + n-1 + n-2 + … + 1),这是等差数列,结果为:(n^2/2 + n/2),

2021-02-18 22:40:14 606

原创 文件上传与下载

前提:要有form标签,method得是post要有enctype属性,值为multipart/form-data在form标签中使用input type=file 添加上传的文件在相应的servlet程序中处理准备一个上传界面upload.jsp:相应的servlet程序UploadServlet,这里先简单写一下,主要用来测试上传请求能不能到后台:接下来上浏览器测试一下:点击上传时,按F12查看网络信息:上面测试使用的是谷歌浏览器,但没有找到请求体,换了ie浏览器之后找到

2021-02-11 09:28:25 228 2

原创 Servlet 重定向,请求转发,多个Servlet间的数据共享(ServletContext、Cookie、HttpSession和HttpServletRequest)

多个servlet之间的调用规则

2021-02-01 16:42:57 850

原创 Servlet+mysql数据库 添加、查询和删除练习,欢迎文件以及状态码

来看看HttpServletRequest和HttpServletResponse这两个接口实现类对象的生命周期,是谁创建的,什么时候以及如何到达doGet和doPost方法的。请求对象和响应对象的生命周期:添加逻辑:先完成html表单:<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title>&lt

2021-01-29 21:15:22 456 1

原创 Servlet HttpServletQequest接口

@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { StringBuffer requestURL = req.getRequestURL(); String method = req.getMethod(); System.out.println("url: " .

2021-01-28 16:19:57 156

原创 Servlet HttpServletResponse接口的使用

上篇说了需要重写doPost和doGet方法以处理相应的请求,那么这两个方法具体是如何处理请求并将结果返回给浏览器呢?public class OneServlet extends HttpServlet { public OneServlet() { System.out.println("OneServlet 实例对象被创建!"); } @Override protected void doGet(HttpServletRequest req, Htt

2021-01-28 12:16:18 474

原创 Servlet接口实现类开发步骤及对象生命周期

servlet接口实现类的开发步骤:创建一个类,让其继承HttpServlet类,使之成为servlet接口实现类重写HttpServlet中的doPost和doGet方法,以编写处理这两种请求的逻辑将servlet接口实现类的信息注册到Tomcat服务器我们先来看第一步,创建一个类,让其继承HttpServlet类,使之成为servlet接口实现类:一个类需要实现servlet的接口才能被服务器操作,如创建这个servlet实现类的对象,之后根据此实例对象调用service方法处理当前请求(

2021-01-28 10:52:36 391

原创 Spring JdbcTemplate操作数据库

Spring封装了jdbc的操作。导入jar包在spring配置文件中配置数据库的连接池<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://ww.

2021-01-23 14:40:33 157

原创 Spring (AOP)

面向切面编程有接口的情况,创建接口实现类的代理对象:参数:类加载器增强方法所在的类,此类实现的接口实现此接口,创建代理对象,写增强的方法没有接口的情况,创建子类代理对象:CGLIB...

2021-01-21 21:33:23 133

原创 Spring 基础(IOC部分)

Bean管理Spring创建对象:就是之前是用new创建对象,现在是用spring来创建对象Spring注入属性:之前是用set方法来设置属性,现在由spring来设置Bean管理的两种方式指实现创建对象和注入属性的两种方式基于xml配置文件基于注解基于xml配置文件的方式创建对象:<bean id="user" class="atjx.spring5.User"></bean>默认执行的是无参构造方法。注入属性:之前注入属性通常有两种方式,s...

2021-01-18 18:53:18 133

原创 搜索二叉树及相关习题

单纯的搜索二叉树并不能保证平衡,它的平衡性受制于输入数据,输入的顺序不好(1 2 3 4 5)会导致搜索二叉树变成一条线,这样的时间复杂度是O(n)下面是不同的平衡搜索二叉树AVL树最严格的平衡性,任何一个节点左子树和右子树高度差不超过1,意味着每插入一个数可能都要调整。以下两种树平衡性没有AVL树那么严格,只是在调整的时候策略不同。都能做到增删改查时间复杂度O(logn),差的只是常数项红黑树SB树练习题 大楼轮廓给你一组数:(1,6,4) (2,4,3) (5,8,5) (7,10,2

2021-01-13 08:59:40 581

原创 LRU和LFU

LRU双向链表+哈希表class Node { String key; int value; Node pre; Node next; public Node(String key, int value) { this.key = key; this.value = value; }}class biLinkedList{ Node head; Node tail; public biLi

2021-01-13 08:59:20 138

原创 左神算法班 单调栈、Morris遍历(前、中、后序)及时间/空间复杂度分析

单调栈解决的问题:对于数组中的每一个数,可以找到这个数左面的最近的比他大的数和右面的最近的比他大的数。例子:3 1 4 2 5,对于1来说,左面距离他最近的且比他大的数是3,右面距离他最近的且比他大的数是4;对于4来说,左面距离他最近的且比他大的数没有,右面距离他最近的且比他大的数是5.如果用暴力法求,那么时间复杂度是O(n^2),因为你要遍历数组中的每一个数,对于每次遍历,都对这个数的左侧与右侧再做一次遍历找到距离他最近的且比他大的值。而单调栈可以在O(n)内求解。理解:现有一数组:[3, 5,

2021-01-05 16:54:50 1128

原创 窗口结构及练习题

窗口的加数与减数开始之前窗口的左右边界L和R都设为-1当R向右移动时,窗口中的元素也相应地增加;当L向右移动时,窗口中的元素也相应地减少。此外,在任何情况下,R和L都不能回退,L也不能大于R。窗口内的最大值由于窗口的L和R是可能随时变动的,因此窗口内的元素是不固定的,即最大值也是不固定的。你当然可以在每次窗口变动后遍历一下[L, R]来求最大值,但这样时间复杂度就是O(窗口的长度)。所以要使用一种新的方式来解决上述问题双端队列结构对于一组数,每次只在队列尾添加数据,同时要将队尾元素和

2020-12-30 15:12:34 149

原创 Manacher(马拉车)算法详解、证明和练习题

给你一个字符串,让你在末尾添加最少数量的字符,使得添加后的字符串为回文串关于这道题,可以用Manacher算法的思想来做。首先找到以给出的字符串最后一个字符结尾的最长回文串,然后从头开始,遇见最长回文串的开头就停止,将这段字串逆序贴在整个字符串的末尾就是答案,举个例子:假设给出的字符串是:abcxyzfzyx,可以看出以最后一个字符结尾的最长回文串是xyzfzyx,然后从字符串的头开始遍历,直到x的前一个位置,最后遍历得到的子串为abc,将abc逆序为cba贴在给出的字符串后面即为答案:abcxyz

2020-12-27 15:10:12 801

原创 关于KMP算法的一些理解(next数组)

这里就不从头说了,只说一下自己的一些理解关于next数组next数组是KMP算法的核心,下面记录一下自己的理解。假设已经求出了第i-1个位置的前缀和后缀,如上图的两个红色的圈,现在要求第i个位置的最长相同前缀和后缀,该如何求呢?可以这么想,既然i-1位置的最长相同前缀和后缀是两个红色的圈,那么如果第k个位置的值等于第i-1个位置的值,就说明第i个位置的最长前缀和后缀是i-1位置的最长前缀和后缀数+1,所以要分两种情况考虑:k位置的值和i-1位置的值相同,那么i位置的最长前后缀为i-1位置最长前

2020-12-24 20:27:28 263 1

原创 前缀树

对于给出的字符串,从根节点出发,如果能复用边就复用,不能就弄一条新边。但这种结构查询bef的时候会判定be也是给出的字符串,但其实be只是由构建bef附带着得到的,因此用如下结构更好:在每个节点上附加一个值,表示有多少字符串是以到目前为止的字符串结尾的,对于上例来说,e和f之间的节点为0就代表没有字符串以be结尾。上述结构能够找到都有哪些字符串被添加进来了,但无法知道以某段字符串为前缀的字符串有哪些,例如我们不知道有多少字符串以be为前缀。因此在每个节点上再添加一个值,代表此节点被经过了多少次,见.

2020-12-20 10:08:57 91 1

原创 并查集解岛问题

并查集的功能:查询:两个元素是否在同一个集合中合并:两个元素各自所在的集合合并概念先不介绍了,网上资料很多时间复杂度:设数据量为N,那么只要查询与合并的次数整体逼近了O(N)及以上,平均每次的的时间复杂度为O(1)练习题这题正常做的话其实不难,递归就可以,主要思路是每次找到值为1的位置就开始递归,并将遍历到的值为1的位置置为2,这样做是防止下次又递归到上次的位置,代码如下:public class Island { private int count; public

2020-12-18 21:40:30 171 1

原创 哈希、布隆过滤器与一致性哈希

相同的输入得到相同的结果,不同的输入得到的结果在大样本的情况下在[0, HashSize]内是均匀分布的。推论: 对于若干输入,哈希函数将他们变换后,在结果集上是均匀分布的,那么对每一个变换的值都mod M,则这些结果在[0, M-1]内也是均匀分布的。一个快速获得多个不相关哈希函数的方法:先调用一个哈希函数,将它返回的结果,比如说16位。拆成两半,即前八位和后八位,然后按照下面的方式:h1 + 1 * h2h1 + 2 * h2h1 + 3 * h2…即可得到若干个互不相关的哈希函数。

2020-12-18 18:52:42 266

原创 二叉树及相关题目(非递归遍历, 完全二叉树节点数量, 判断是否为搜索二叉树/完全二叉树)

关于二叉树的递归遍历就不写了,这里介绍一下非递归方式二叉树的非递归遍历二叉树结构如下: public static class Node { public intvalue; public Node left; public Node right; public Node(int value) { this.value = value; }先序需要按照根-左-右的方式遍历。所以将根节点压入栈后,先输出它的值。接着看看根节点有无右子树,如果有则把右节

2020-12-16 17:06:31 246

原创 栈实现队列/队列实现栈,矩阵和链表的练习题

用数组实现栈index表示向栈中压入一个数时的数组下标,即新来的数的位置下标就是index,之后index+1;同理当出栈时,先将index–然后再输出栈顶元素。public class ArrayStack { private Integer[] arr; private Integer index; public ArrayStack(int initSize) { if (initSize < 0) { throw new I

2020-12-16 09:01:26 265

原创 leetcode - 05 最长回文子串

传送门:https://leetcode-cn.com/problems/longest-palindromic-substring/solution/zui-chang-hui-wen-zi-chuan-by-leetcode-solution/这道题的题目是在一个字符串s中寻找最长的回文子串,所谓回文子串就是正着读和反着读都一样的字符串,如 “aba”、“abxba"等等。一个字符串中可能有多个最长的回文子串,如题目给的"babad”,那么"bab"和 "aba"都是正确答案。解法有很多种解法,

2020-12-09 20:54:00 150

原创 EL表达式

EL,Expression Language,是表达式语言。使用jsp页面虽然能进行数据输出,但过于麻烦,而使用EL表达式在输出数据时会更简洁。

2020-12-08 22:30:28 503

原创 JSP 常用标签(静态/动态包含、请求转发)简单了解

常用标签静态包含在浏览网页的时候,同一个网站的footer可能是不变的,如果要给同一个网站的多个网页都加上footer那就太麻烦了,这时可以用静态包含。index:footer:运行结果:使用这种方式就可以通过改一个jsp文件而更新所有的网页了,翻译后的java代码如下:可以看到,静态包含其实是把被包含的jsp页面中的代码复制到包含的位置。动态包含和静态包含不同的是:动态包含会把包含的jsp页面也翻译成java代码动态包含底层代码是:org.apache.jasper.ru

2020-12-05 16:54:18 458

原创 Java8 新特性 (Lambda表达式、Stream)

Lambda表达式注意和Python中Lambda的区别,在Python中是方法,在Java中是对象。无参,无返回值 @Test public void test() { Runnable r1 = new Runnable() { @Override public void run() { System.out.println("1"); } };

2020-10-11 10:18:37 247

原创 JDBC (事务、隔离性、数据库连接池(C3P0,DBCP,Druid)、DBUtils)

事务引入事务的必要性未考虑事务的情况现在想对如下表进行转账操作,AA给BB转100,代码如下:public class TransactionTest { // 未考虑事务的情况 @Test public void test() throws Exception { String sql1 = "update user_table set balance = balance - 100 where user = ?"; update(sql1

2020-10-09 20:21:02 475

原创 JDBC (连接、基础的增删改查、PrepareStatement和Statement)

面向接口编程程序编写步骤获取连接在这之前,要获取mysql的驱动,你要把相应的jar包放在项目下:方式一import org.junit.Test;import java.sql.Connection;import java.sql.Driver;import java.sql.SQLException;import java.util.Properties;public class ConnectionTest { @Test public void test

2020-10-08 11:13:45 686

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除