- 博客(98)
- 资源 (1)
- 收藏
- 关注
原创 Python学习笔记-多线程编程
Python 实现多线程编程需要借助于 threading 模块,而threading模块中最核心的内容是Thread这个类。我们要创建Thread对象,然后让它们运行,每个Thread对象代表一个线程,在每个线程中,我们可以让程序处理不同的任务,这就是多线程编程。创建Thread对象有两种手段:1.直接创建Thread对象class threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=N
2021-07-15 14:07:50
194
原创 Python学习笔记-面向对象编程、with语句与自定义上下文管理器
1.定义一个类class Player(): # 类的名称规范上以大写字母开头 def __init__(self,name,hp,occu): self.name=name # self表示该类实例化后实例本身。 self.hp=hp self.occu=occu def print_role(self): print('%s:%s')
2021-07-14 18:38:24
227
1
原创 Python学习笔记-函数闭包
1.什么是闭包1.内部函数对外部函数作用域变量的引用(非全局变量),则称内部函数为闭包。即闭包就是能够读取其他函数内部变量的函数。2.一个闭包就是你调用了外部函数,外部函数返回内部函数,此时的内部函数就叫做闭包函数。2.闭包的简单例子# 普通函数写法def func(): a=1 b=2 return a+b# 闭包写法def sum(a): def add(b): # 内部函数称之为闭包函数 return a+b # 内部函数引用外部函数作用域变量a return ad
2021-07-13 20:35:29
254
3
原创 Python学习笔记-装饰器
1.不带参数的装饰器import time# 函数闭包操作def timmer(func): def wrapper(): start_time=time.time() func() stop_time=time.time() print("运行时间是 %s秒"%(stop_time-start_time)) return wrapper@timmerdef i_can_sleep() time.sleep(3)i_can_sleep()输出为:阐述一下过程:
2021-07-13 19:40:07
101
原创 动态规划问题
淘宝的“双十一”购物节有各种促销活动,比如“满 200 元减 50 元”。假设你女朋友的购物车中有 n 个(n>100)想买的商品,她希望从里面选几个,在凑够满减条件的前提下,让选出来的商品价格总和最大程度地接近满减条件(200 元),这样就可以极大限度地“薅羊毛”。作为程序员的你,能不能编个代码来帮她搞定呢?要想高效地解决这个问题,就要用到我们今天讲的动态规划(Dynamic Programming)。动态规划比较适合用来求解最优问题,比如求最大值、最小值等等。它可以非常显著地降低时间复杂度,提
2020-06-27 11:18:27
1495
原创 字典树——实现搜索引擎的搜索关键词提示功能
搜索引擎的搜索关键词提示功能,我想你应该不陌生吧?为了方便快速输入,当你在搜索引擎的搜索框中,输入要搜索的文字的某一部分的时候,搜索引擎就会自动弹出下拉框,里面是各种关键词提示。你可以直接从下拉框中选择你要搜索的东西,而不用把所有内容都输入进去,一定程度上节省了我们的搜索时间。尽管这个功能我们几乎天天在用,作为一名工程师,你是否思考过,它是怎么实现的呢?它底层使用的是哪种数据结构和算法呢?像 Google、百度这样的搜索引擎,它们的关键词提示功能非常全面和精准,肯定做了很多优化,但万变不离其宗,底层最基
2020-06-23 09:55:48
1412
原创 字符串匹配算法
字符串匹配这样一个功能,我想对于任何一个开发工程师来说,应该都不会陌生。我们用的最多的就是编程语言提供的字符串查找函数,比如 Java 中的 indexOf(),Python 中的 find() 函数等,它们底层就是依赖接下来要讲的字符串匹配算法。1.BF算法BF 算法中的 BF 是 Brute Force 的缩写,中文叫作暴力匹配算法,也叫朴素匹配算法。从名字可以看出,这种算法的字符串匹配方式很“暴力”,当然也就会比较简单、好懂,但相应的性能也不高。在开始讲解这个算法之前,我先定义两个概念,方便我后
2020-06-22 09:36:25
1532
1
原创 图的广度优先搜索和深度优先搜索
我们知道,算法是作用于具体数据结构之上的,深度优先搜索算法和广度优先搜索算法都是基于“图”这种数据结构的。这是因为,图这种数据结构的表达能力很强,大部分涉及搜索的场景都可以抽象成“图”。图上的搜索算法,最直接的理解就是,在图中找出从一个顶点出发,到另一个顶点的路径。具体方法有很多,比如今天要讲的两种最简单、最“暴力”的深度优先、广度优先搜索,还有 A*、IDA* 等启发式搜索算法。图有两种主要存储方法,邻接表和邻接矩阵。本文使用邻接表来存储图。我这里先给出图的代码实现。需要说明一下,深度优先搜索算法和广
2020-06-19 12:09:49
3471
原创 堆及其应用
1.如何理解堆?首先我们必须明确一点:堆是一种特殊的树。严格意义上来说:堆是一种特殊的完全二叉树。堆是一个完全二叉树。堆中每一个节点的值都必须大于等于(或小于等于)其子树中每个节点的值。对于每个节点的值都大于等于子树中每个节点值的堆,我们称之为“大顶堆”。反之称之为“小顶堆”。2.如何实现一个堆?要实现一个堆,我们先要知道,堆都支持哪些操作以及如何存储一个堆。首先,完全二叉树比较适合用数组来存储。用数组来存储完全二叉树是非常节省存储空间的。因为我们不需要存储左右子节点的指针,单纯地通过数组
2020-06-18 11:38:08
242
原创 红黑树
在前面,我们依次讲了树、二叉树、二叉查找树。二叉查找树是最常用的一种二叉树,它支持快速插入、删除、查找操作,各个操作的时间复杂度跟树的高度成正比,理想情况下,时间复杂度是 O(logn)。不过,二叉查找树在频繁的动态更新过程中,可能会出现树的高度远大于logn的情况,从而使得各个操作的效率下降。极端情况下,二叉树会退化成链表,时间复杂度会退化到O(n)。我上一节已经说过,要解决这个复杂退化的问题,我们需要一种平衡二叉查找树,也就是今天要说得这种数据结构。很多书籍里,但凡讲到平衡二叉查找树,就会拿红黑树作
2020-06-16 10:25:02
354
原创 哈希算法的应用
1.什么是哈希算法我们前面几节讲到“散列表”“散列函数”,这里又讲到“哈希算法”,你是不是有点一头雾水?实际上,不管是“散列”还是“哈希”,这都是中文翻译的差别,英文其实就是“Hash”。所以,我们常听到有人把“散列表”叫作“哈希表”“Hash 表”,把“哈希算法”叫作“Hash 算法”或者“散列算法”。那到底什么是哈希算法呢?哈希算法的定义和原理非常简单,基本上一句话就可以概括了。将任意长度的二进制值串映射为固定长度的二进制值串,这个映射的规则就是哈希算法,而通过原始数据映射之后得到的二进制值串就是哈
2020-06-08 11:33:23
579
1
原创 散列表
1.散列思想散列表的英文叫“Hash Table”,我们平时也叫它“哈希表”或者“Hash 表”,你一定也经常听过它,我在前面的文章里,也不止一次提到过,但是你是不是真的理解这种数据结构呢?散列表用的是数组支持按照下标随机访问数据的特性,所以散列表其实就是数组的一种扩展,由数组演化而来。可以说,如果没有数组,就没有散列表。我用一个例子来解释一下。假如我们有 89 名选手参加学校运动会。为了方便记录成绩,每个选手胸前都会贴上自己的参赛号码。这 89 名选手的编号依次是 1 到 89。现在我们希望编程实现
2020-06-04 09:47:40
694
原创 简单二分查找、复杂二分查找与跳表
1.查找的分类1.1 查找表用于查找的数据集合称之为查找表,它由同一类型的数据元素(或记录)组成,可以是一个数组或者链表等数据结构。对查找表经常进行的操作一般有四种:1.查询某个特定的数据是否在查找表中。2.检索满足条件的某个特定的数据元素的各种属性。3.在查找表中插入一个数据元素。4.从查找表中删除某个数据元素。1.2 静态查找表与动态查找表如果一个查找表的操作只涉及到1和2的操作,则无需动态地修改查找表,此类查找表称之为静态查找表,反之称之为动态查找表。适合静态查找表的查找方法有:顺序
2020-06-01 16:05:31
777
原创 十大经典排序算法
1.排序算法概述十种常见的排序算法可以分为两大类:**比较类排序:**通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也被称为非线性时间比较类排序。**非比较类排序:**不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此也称之为线性非比较类排序。2.交换排序2.1 冒泡排序(Bubble Sort)冒泡排序是一种简单...
2020-05-30 10:56:58
251
原创 Java核心面试精讲-27 Java的垃圾收集机制
在JVM的内存结构中,对于程序计数器、虚拟机栈、本地方法栈这三个部分而言,其生命周期与相关线程有关,随线程而生,随线程而灭。并且这三个区域的内存分配与回收具有确定性,因为当方法结束或者线程结束时,内存就自然跟着线程回收了。因此本篇文章所讲的有关内存分配和回收关注的是Java堆与方法区这两个区域。1.回收堆——如何判断对象已“死”Java堆中存放着几乎所有的对象实例,垃圾回收器在堆进行垃圾回收前...
2020-03-09 17:04:22
219
原创 Java核心技术面试精讲-25/26 JVM内存区域的划分
1.JVM内存区域划分用两张图即可完美表达:2.几个问题问题一:Java对象是不是都创建在堆上面呢?我注意到有一些观点,认为通过逃逸分析,JVM 会在栈上分配那些不会逃逸的对象,这在理论上是可行的,但是取决于 JVM 设计者的选择。据我所知,Oracle Hotspot JVM 中并未这么做,这一点在逃逸分析相关的文档里已经说明,所以可以明确所有的对象实例都是创建在堆上。问题二:OO...
2020-03-09 15:26:33
229
原创 Java核心技术面试精讲-23/24 Java的类加载过程
我们知道,我们写的java文件是不能直接运行的,我们可以在IDEA中右键文件名点击运行,这中间其实掺杂了一系列的复杂处理过程。这篇文章,我们只讨论我们的代码在运行之前的一个环节,叫做类的加载。首先我们给出这篇文章的大致结构:首先,认识类加载机制;然后,详细介绍类加载的过程。最后,说一说类加载器,以及双亲委派原则。1.什么是类的加载在介绍类的加载机制之前,先来看看,类的加载机制在整个ja...
2020-03-03 16:56:24
296
原创 队列-在线程池等有限资源池中的应用
前面我们说过,栈适合的应用条件是先进后出、后进先出。那么这节说的队列就是先进先出、后进后出。我们知道,CPU 资源是有限的,任务的处理速度与线程个数并不是线性正相关。相反,过多的线程反而会导致 CPU 频繁切换,处理性能下降。所以,线程池的大小一般都是综合考虑要处理任务的特点和硬件环境,来事先设置的。当我们向固定大小的线程池中请求一个线程时,如果线程池中没有空闲资源了,这个时候线程池如何处理这个...
2020-02-28 10:16:51
151
原创 线性表的构成形式-数组(顺序结构)与链表(链式结构)
什么是数组?数组(Array)是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。好的,这里存在着三个关键词,线性表、连续内存空间、以及相同类型数据。我们一个个看。1.线性表线性表以实现方式分为顺序结构(数组)和链式结构(链表)。数组这里的线性是指的逻辑上的线性,即只要数据的保存满足了一对一关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接没有例外;...
2020-02-23 18:14:02
823
原创 Java核心技术面试精讲-14 谈谈你知道的设计模式?
大致按照模式的应用目标分类,设计模式可以分为创建型模式、结构型模式以及行为型模式。详细博客见Java设计模式总结之23种设计模式1.创建型模式是对对象创建过程的各种问题和解决方案的总结,包括各种工厂模式、单例模式、构造器模式以及原型模式单例模式某个类只能有一个实例,提供一个全局的访问点。简单工厂一个工厂类根据传入的参量决定创建出哪一种产品类的实例。抽象工厂创建相关或依赖对...
2020-02-19 19:06:18
509
原创 Java核心技术面试精讲-13 谈谈接口和抽象类有什么区别?
接口和抽象类的概念不一样。接口是对动作的抽象,抽象类是对根源的抽象。抽象类表示的是,这个对象是什么。接口表示的是,这个对象能做什么。比如,男人,女人,这两个类(如果是类的话……),他们的抽象类是人。说明,他们都是人。人可以吃东西,狗也可以吃东西,你可以把“吃东西”定义成一个接口,然后让这些类去实现它。所以,在高级语言上,一个类只能继承一个抽象类(正如人不可能同时是生物和非生物),但是可以实...
2020-02-19 18:34:57
330
原创 Java核心技术面试精讲-11 Java有几种文件拷贝方式?哪一种最高效?
Java有多种比较典型的文件拷贝实现方法。1.利用java.io类库。直接为源文件创建一个FileInputStream负责读取,然后再为目标文件创建一个FileOutputStream负责写入public static void copyFileByStream(File source,File target)throws IOException{ try(InputStream is=n...
2020-02-19 13:26:34
314
原创 Java核心技术面试精讲-10 Java内存模型、volatile变量、AQS队列同步器以及并发包java.util.concurrent
1.典型回答Java提供了不同层面的线程安全支持。在传统集合框架内部,除了Hashtable等同步容器,还提供了所谓的同步包装器。我们可以调用 Collections 工具类提供的包装方法,来获取一个同步的包装容器(如 Collections.synchronizedMap),但是它们都是利用非常粗粒度的同步方式,在高并发情况下,性能比较低下。我们更加普遍的选择是利用并发包java.util....
2020-02-18 20:21:53
330
原创 Java核心技术面试精讲-09 Hashtable、HashMap、TreeMap有什么不同?
1.简单说一下红黑树由于TreeMap是由红黑树实现的,所以我们先说一下什么是红黑树。首先,红黑树是一种自平衡的二叉查找树,是一种高效的二叉查找树,其具有良好的效率,它可在O(logN)的时间内完成查找、增加删除等操作。学过二叉查找树的同学都知道,普通的二叉查找树在极端情况下可退化成链表,此时的增删查效率都会比较低下。为了避免这种情况,就出现了一些自平衡的查找树,比如 AVL,红黑树等。这...
2020-02-18 19:55:04
186
原创 Java核心技术面试精讲-08 对比Vector、ArrayList、LinkedList有何区别?
1.VectorVector 是 Java 早期提供的线程安全的动态数组,如果不需要线程安全,并不建议选择,毕竟同步是有额外开销的。Vector 内部是使用对象数组来保存数据,可以根据需要自动的增加容量,当数组已满时,会创建新的数组,并拷贝原有数组数据。其作为动态数组,内部元素是以数组形式顺序存储的,所以非常适合随机访问的场合。2.ArrayListArrayList 是应用更加广泛的动态...
2020-02-18 09:14:15
245
原创 Java核心技术面试精讲-07 基本类型和包装类
Integer 是 int 对应的包装类,它有一个 int 类型的字段存储数据,并且提供了基本操作,比如数学运算、int 和字符串之间转换等。在 Java 5 中,引入了自动装箱和自动拆箱功能(boxing/unboxing),Java 可以根据上下文,自动进行转换,极大地简化了相关编程。关于 Integer 的值缓存,这涉及 Java 5 中另一个改进。构建 Integer 对象的传统方式是直...
2020-02-17 22:43:03
262
原创 Java核心技术面试精讲-06 动态代理是基于什么原理?
1.动态类型和静态类型程序都需要进行错误的检查。比如 3 / 0,这个程序会有错误,我们应该在什么时候进行检查呢?在写程序时,只要编辑器里出现除以0,报错。在编译时,如果检查到了除以0,报错。在程序运行时,运行到了除以0,报错。不报错,返回无穷大 (+inf.0)。不同的语言设计上会选择在这4个过程中不同时候去报错。静态类型和动态类型的区别在于什么时候报类型的错误?,比如说 3 / "...
2020-02-17 22:18:55
141
原创 Java核心技术面试精讲-05 从String、StringBuffer、StringBuilder的区别学习可变类与不可变类
1.String、StringBuffer以及StringBuilder的区别与联系String是Java语言非常基础和重要的类,提供了构造和管理字符串的各种基本逻辑。它是典型的 Immutable 类,被声明成为 final class,所有属性也都是 final 的。也由于它的不可变性,类似拼接、裁剪字符串等动作,都会产生新的 String 对象。由于字符串操作的普遍性,所以相关操作的效率往...
2020-02-17 20:03:37
184
原创 Java核心技术面试精讲-04 可达性算法与强引用、软引用、弱引用,虚引用
在Java语言中,除了原始数据类型的变量,其他所有都是所谓的引用类型,指向不同的对象,理解引用对于掌握Java对象生命周期和JVM内部相关机制非常有帮助。引用出现的根源是由于GC内存回收的基本原理—GC回收内存本质上是回收对象,而目前比较流行的回收算法是可达性分析算法,从GC Roots开始按照一定的逻辑判断一个对象是否可达,不可达的话就说明这个对象已死。那么,强引用,软引用,弱引用以及幻象引...
2020-02-17 19:01:03
597
原创 Java核心技术面试精讲-03 谈谈final、finally、finalize有什么不同?
final用来修饰类、方法以及变量,分别有不同的意义。final修饰的class代表不可以被继承以及扩展。final修饰的变量是不可以被修改的。final修饰的方法是不可以被重写的。finally 则是 Java 保证重点代码一定要被执行的一种机制。我们可以使用 try-finally 或者 try-catch-finally 来进行类似关闭 JDBC 连接、保证 unlock 锁等动作。fi...
2020-02-17 18:07:27
208
原创 Java核心技术面试精讲-01 谈谈你对Java平台的理解?
问题一:Java程序运行步骤问题二:JRE与JDK的区别JRE(Java Runtime Enviroment)是Java的运行环境。面向Java程序的使用者,而不是开发者。如果你仅下载并安装了JRE,那么你的系统只能运行Java程序。JRE是运行Java程序所必须环境的集合,包含JVM标准实现及 Java核心类库。它包括Java虚拟机、Java平台核心类和支持文件。它不包含开发工具(编译器...
2020-02-17 16:20:22
1302
原创 Spring框架学习笔记-ThreadLocal基础知识
在前面我们已经说过,Spring通过各种模板降低了开发者使用各种数据持久化技术的难度。这些模板类都是线程安全的,也就是说,多个DAO可以复用同一个模板实例而不会发生冲突。我们使用模板类访问底层数据,根据持久化技术的不同,模板类需要绑定数据连接或会话的资源。但这些资源本身是非线性安全的,也就是说它们不能在同一时刻被多个线程共享,虽然模板类通过资源池获取数据连接或对话,但资源池本身解决的是数据连接或...
2020-01-15 21:15:16
376
原创 Spring框架学习笔记-Spring对DAO的支持
1.Spring的DAO理念DAO(Data Access Object)是用于访问数据的对象。在大多数情况下,我们会将数据保存在数据库中,但这并不是唯一的选择,用户也可以将数据存储到文件中或这LDAP中。DAO不但屏蔽了数据存储的最终介质的不同,也屏蔽了具体的实现技术的不同。只要为数据访问定义好DAO接口,并使用具体的技术实现DAO接口的功能,用户就可以在不同的实现技术之间平滑的切换。2.统...
2020-01-13 18:46:18
396
原创 Spring框架学习笔记-创建切面
1.增强与切面在介绍增强时,我们注意到一个问题:增强被织入到目标类的所有方法中。假设我们希望有选择地织入到目标类某些特定的方法中,就需要使用切点进行目标连接点的定位了。描述连接点是进行AOP编程最主要的一项工作。Spring通过org.springframework.aop.Pointcut接口描述切点,Pointcut有两个方法:getClassFilter() 以及 matches()...
2020-01-10 11:38:07
180
原创 高性能MySQL-Schema与数据类型优化
本章覆盖了MySQL特有的schema设计方面的主题1.选择优化的数据类型MySQL支持的数据类型非常多,选择正确的数据类型对于获得高性能至关重要。不管存储哪种类型的数据,下面几个简单的原则都有助于做出更好的选择。更小的通常更好要确保没有低估需要存储的值的范围,因为在schema中的多个地方增加数据类型的范围是非常耗时的过程。如果无法确定哪个数据类型是最好的,就选择你认为不会超过范围的最小...
2020-01-04 13:33:16
177
原创 Spring框架学习笔记-创建增强类
Spring使用增强类定义横切逻辑,同时由于Spring只支持方法连接点,增强还包括了在方法的哪一点加入横切代码的方位信息,所以增强既包括横切逻辑,还包括部分连接点的信息。1.增强类型AOP联盟为增强定义了org.aopalliance.aop.Advice接口前置增强: org.springframework.aop.BeforeAdvice,代表前增强,表示在目标方法执行前实施增强。后...
2020-01-01 17:03:39
135
原创 MySQL基础
1.MySQL的逻辑架构2.并发控制并发控制存在于MySQL的两个层面中:服务器层以及存储引擎层。2.1 读写锁共享锁(读锁)是共享的,或者说是相互不堵塞的。多个客户在同一时刻可以同时读取同一个资源而互不干扰。排他锁(写锁)是互斥的,也就是说一个写锁会阻塞其他的写锁和读锁。2.2 锁粒度一种提高共享资源并发性的方式是让锁定对象更有选择性。尽量只锁定需要修改的部分数据,而不是所有的资源...
2019-12-30 18:00:59
162
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人