自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

子翊寒

放开,让我带你入门

  • 博客(66)
  • 收藏
  • 关注

原创 一次写文,多平台直接粘贴&打造最流畅的写作流程

文字爱好者的痛点**这一段可以跳过,解决办法在后面。**因为大家既然痛过,也就懂了。对于很多文字爱好者来说,都希望写一篇文章后,可以实现多平台发布。国内的很多平台都开始支持 Markdown,除了微信公众号平台。但是,Tyora 这个工具,能解决这个问题。通过 Typora 这个工具,你可以实现一次写作,复制后,然后在其他平台一键粘贴,包括微信。下图,是直接在 微信公众号平台 和 知乎 ...

2019-09-17 21:15:07 309

原创 PyTorch深度学习快速入门教程(绝对通俗易懂!)

Pytorch教程相信尝试找到此教程的你,已经知道PyTorch的用途。找到此教程的你,也许跟我一样,尝试过各种教程,官方的教程文档,各色的视频,但发现都不是很友好。深知此感受的我,尝试写下这份教程,希望能为你稍微照亮下周边的道路。需要具备的基础:编程语言基础,我觉得任何一门语言都是可以的知道面向对象的知识,类,继承,实例零:目录安装一些基础操作读取加载图像一些准备知...

2019-02-03 17:55:16 8347

原创 Spring 概述

在学习 Spring 的时候,我们必须得有个整体性的概念。这个概念就是:Spring 到底是什么?官网给了如下的介绍:The Spring Framework provides a comprehensive programming and configuration model for modern Java-based enterprise applications - on any kind of deployment platform.A key element of Spring is

2020-07-01 15:12:05 427

原创 Java 虚拟机栈

栈结构栈,这种数据结构,太重要了。如果学习过算法,就可以了解它的强大了。栈,就像我们叠起来的盘子,只能对最上面的部分进行操作。对于栈,只有两种操作:入栈,在上面再加一个盘子出栈,拿掉最上面的盘子别小看这两种操作,他可以完成很多复杂的事情,这就是数据结构和算法的魅力。JVM 的运行是基于栈的指令集,也就是说,JVM 对于数据的操作,都是基于栈这种数据结构的。栈指令集我们写一段代码:package runningDate;public class JavaStackTest {

2020-06-24 16:19:01 342

原创 程序计数器

程序计数器先来看这张图,对于数据区,存在着线程,进程的概念。程序计数器是每个线程私有的。如果没有多线程的概念,可以直接无视。程序计数器程序计数器,也有人叫它 程序寄存器。但是叫做 程序计数器更为精确。因为我们知道,在计算机也有一种结构叫做 寄存器,它储存容量小,但是速度快,一般用于 CPU 中。但是我们这里的 程序计数器 只是我们常说的内存中划分出的一块小内存区域,用来充当 程序计数器的功能。它记录了,我们下一条要运行指令的地址。我们来看这张图。右边是我们从 Java 文件编译出的 cl

2020-06-24 15:19:49 765

原创 运行时数据区

按理说,在介绍完前端编译器之后,我们应该介绍如何让 JVM 去解释运行 这个编译后的 .class 文件。但是感觉并不是很恰当。如果把 .class 文件比做新购买的家具,那么如果需要把家具摆放到家里,是不是得先了解房子的结构和布局,然后才能将家具进行正确的摆放。我们这里介绍的 运行时数据区 相当于前面提到的 房子结构。运行时数据区,这个名字实在取得太高大上了。其实就是,当我们程序运行的时候,这一块区域主要是负责数据的处理。程序的基本逻辑,无非就是不同的数据进行交互。在这块 数据区 中,有很多不

2020-06-24 14:57:43 189

原创 前端编译

前端编译的主要作用,是将 我们编写的 .java 文件 编译成 .class 文件,也就是我们常说的 字节码 文件。字节码 文件,里面包含了我们编写的 .java 代码中的运行逻辑,参数 以及 这些参数在内存中的分配。前端编译过程解析与填充符号表注解处理分析与字节码生成总而言之,就是对 .java 文件进行语法分析,根据 .java 文件构建抽象语法树。前端编译结果package methodArea;public class MethodTest { public stat

2020-06-24 14:04:57 1557

原创 方法区概述

方法区概述首先先来说说 方法区 的作用。方法区方法区,是用来存放有关 类、方法 信息的一块逻辑上的区域。也就说,人们想规划出一块区域,用来存储类 方法 相关信息。除此之外,还用来存储常量、静态变量,以及一些代码缓存等数据。想想,这些数据都有什么特点。几乎不变;不怎么依赖于对象,独立。方法区的故事关于方法区,有很多的故事 和 混乱。方法区、永久代、元空间都跟他有着故事。故事的缘由是由历史和部分概念不清晰导致的。我们之前说到,方法区 只是一个逻辑上的概念。具体的实现,叫做 永久代 和 元空

2020-06-24 10:31:27 2425

原创 常见测试堆空间的 JVM 参数

-XX:+PrintFlagsInital 查看所有参数的初始值-XX:+PrintFlagsFinal 查看所有参数的最终值-Xms 设置堆的初始值-Xmx 设置堆的最大值-Xmn 设置新生代的大小-XX:NewRatio 新生代与老年代的比例-XX:SurvivorRatio 设置 Eden 和 Survivor 比例-XX:MaxTenuringThreshold 设置进入老年代的年龄阈值-XX:+PrintGCDetails 打印 垃圾回收 的细节-XX:HandlerPromot

2020-06-23 00:08:24 165

原创 对象创建与堆

这一节主要介绍对象创建时,在堆中的一些过程。回忆下,我们之前说的,什么时候会发生垃圾回收?除了在一些安全点处也许会发生垃圾回收(只是也许),如果在所需内存不足的情况下,一定会发生垃圾回收。分配堆空间首先通过设置参数,把堆空间设置为 20M,其中 新生代 10M,老年代 10M。参数设置:-Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails结果为:Heap PSYoungGen total 9216K, used 1685K [0x00000007

2020-06-22 23:40:35 217

原创 对象的内存布局

对象的内存布局创建一个对象,不仅仅是找一块内存区域,然后把对象的值赋值进去那么简单。你想想,当我们 new 一个对象出来的时候,我们可以利用反射获取对象的一些信息。可以通过对象调用其中的一些方法。所以,在内存中,对象不仅仅包含了对象值那么简单,它还包含了更多的信息。这些信息保存在一个名为 对象头 的结构中。对象头一个对象实例,包含了 对象头、实例数据 和 对齐填充。对象头主要保存了这个实例的一些信息,实例数据保存了其中的实例数据。最后的 对齐填充,只是为了单纯填充空间。可以从图上看到,对象头主

2020-06-22 14:54:26 171

原创 基于分代的堆结构

堆的结构是基于分代理论(垃圾回收)的,这种结构划分,是为了更好地进行垃圾回收。我们将堆分为老年代、新生代。永久代、元空间、堆这几个概念一直比较混乱。但是看到上图,堆的定义只包含 新生代 和 老年代。这一点我们在实际设置 JVM 的参数的时候,你会发现,设置的空间的确只包含 新生代 和 老年代。新生代 和 老年代 是根据对象的生命周期特点来区别的。堆参数的设置接下来,我们来看下 Java 8 中,关于 堆 参数的设置:-Xms:表示堆的起始内存-Xmx:表示堆的最大内存一旦堆需要的空间大于

2020-06-22 12:47:14 187

原创 强软弱虚引用

强软弱虚,是 Java 中比较主流的四种引用。(多念念,就顺口了)从这四种引用的作用来看(接下来你会看到),引用,与对象的存活密不可分。也许正是因为有了 JVM 的垃圾收集器,才有了这四种引用。我觉得直接看四种引用的概念比较好:强引用;无论何时,只要有强引用关系的对象,都不会被垃圾回收器回收掉,如果内存不足的时候,直接报错软引用:有软引用关系的对象,当内存即将不足的时候,会被垃圾回收器清理掉;弱引用:有弱引用关系的对象,只能活到下一次垃圾回收的时候,也就是,只要发生了一次垃圾回收,那么弱引用关系

2020-06-21 19:05:15 229

原创 安全点和安全区域

前面介绍了垃圾回收器几个方面的内容:如何标记垃圾如何处理垃圾那么还有什么问题要解决呢?既然是自动垃圾回收,那么自动是什么情况呢?在我看来,自动主要来自两个方面:当我们年轻代、老年代内存不足时,触发某种条件,进行垃圾收集还有一个就是我们接下来说的安全点、安全区域安全点为什么要有安全点呢?在一个程序执行过程中,我们不一定要等到内存不足的时候,再进行垃圾回收整理。如果只是等待到内存不足的时候再进行整理,那么这个时候,就会有大量的垃圾,那么处理起来,要耗费的时间就会增长。所以,为了减

2020-06-21 15:36:09 545

原创 垃圾回收算法

前面介绍了如何去识别和标记垃圾,现在主要介绍,如何去回收(处理、删除)这些垃圾?你也许会想,找到了直接删掉不就行了吗?恭喜你,已经学会了一个很重要的算法。标记-清除(Mark-Sweep)标记-清除算法,主要分为两个步骤,标记 和 清除。标记,就使用之前说过的 可达性分析算法,即可进行标记。就是我们根据 GC Roots 标记出存活对象,然后将垃圾对象进行清除即可。就是这么简单。但是这种算法主要有如下缺点:会产生大量的内存碎片。内存空间不再连续,对于一些大对象连续的对象结构来说,无非是浪费

2020-06-21 14:02:08 207

原创 垃圾回收相关算法

这里介绍的垃圾回收相关算法,主要解决的问题:判断哪些内存是垃圾(需要回收的)?常用的两种算法:引用计数可达性分析(GC Root)首先介绍算法前,得定义:如何判断一个对象的死亡?我们一般这样定义:当一个对象不再被任何存活的对象继续引用的时候,这个对象就死亡了。引用计数引用计数算法,是给每一个对象添加一个计数器,当有对象引用它的时候,计数器+1,当有对象取消对它的引用时,计数就会-1。当计数器的值为 0 时,即说明没有对象引用它,也就是这个对象死亡了。这种算法很简单,但是有个

2020-06-21 11:14:07 191

原创 内存访问全过程

这一篇,是重点!我们将去讲解操作系统根据代码(逻辑)地址去访问真实物理地址的全过程。将把全面几节的东西全部用上,并完全梳理,完善细节。前面讲了分段、分页机制,他们都可以实现,从虚拟地址(地址空间)向物理地址的转换。但是,实际使用过程中,使用的是分段+分页机制,段页结合。段页结合全过程分析(高能)我们现在采用边实验边讲解翻译全过程。写了一段 c 代码,编译,然后在 Linux 0.11 中,进行调试#include <stdio.h>int i = 0x12345678;in

2020-05-10 16:54:40 2836

原创 多级页表与快表

之前页表结构的不足之前的页表结构看起来挺好的呀,有什么问题呢?如果每个页的大小是4k,也就是2的12次方。如果是32位的地址话,也就是说,有2的20次方个页。那么对应到页表,也就说页表应该有2的20次方个项。因为每个项表示的是一个内存地址,也就说一个项的大小是32位,也就是4个字节。这样算下来,对应于一个32位的内存地址,一个页表应该4M大小。看起来还可以接受啊。但注意,每个进程都有一个页表。看下,我的电脑现在有280个进程,也就说如果采用之前的结构,光页表结构就得占用280*4M=1120M,

2020-05-09 16:27:54 2108

原创 分页

前面说到了采用分段技术来进行虚拟地址(地址空间)到物理内存的转换。分段有什么问题?肯定得有不足,才需要提出新的技术来改进。那么我们刚才的分段机制,不是挺好的嘛?有什么问题呢?比如说,我们现在存放一些内容,需要占用 160K 的空间,但是我们来看空间的地址空间,分别是150K和50K,每个段都不足以满足 160 K 的要求,但是两个加起来,的的确确可以满足要求。只使用 分段机制,会造成内存碎片,浪费空间。如何解决呢?针对上面的问题,我们可以想到有下面的一些方法:移动已经使用的内存,把空闲的内

2020-05-09 16:11:48 380

原创 虚拟内存

背景我们一般把内存看成一块连续的字节数组。我们通过指定地址来访问其中的内容。我们看到图上,0KB-64KB 地址范围内,存放着操作系统。如果现在 A 同学想要写一个程序,它指定代码放在64KB-128KB的位置。现在B同学也写了一个程序,为了避免覆盖A同学程序,需要指定将代码放在128KB以后的位置。这样,就很麻烦了,你需要提前知道其他程序所在的位置,这样写代码就特别痛苦。为此,引入了虚拟内存的概念。地址空间的引入为此,引入了地址空间的概念,或者叫做虚拟地址。现在,对每一个程序,进程,都

2020-05-09 15:22:57 231

原创 内存分段机制

我们可以写一段简单的c代码(code/memory/segment_1.c):#include <stdio.h>int main(){ int a = 1; printf("Hello, World!"); return 0;}然后将其转为汇编,运行:gcc -S segment_1.c之后会生成一个.s 文件(code/memory/segmen...

2020-05-07 17:37:49 435

原创 Java vs c++ 字符串 vector ArrayList 迭代器数组比较

字符串Java 和 c++ 都支持字符串,但在使用方面有所区别。初始化,Java 的初始化方式比较简朴,= 后加上字符串即可。c++ 可以在变量后,使用括号进行多次重复或者进行赋值。除此之外,Java 可以两个字面量进行直接连接,而c++ 需要字面量另一边需要有一个字符串变量才可以。取值方式不同,如果想获取字符串中的每一个字符。那么Java 只能用charAt 函数,或者转为char[] ...

2020-03-27 13:33:19 269

原创 Java vs C++ 基础异同比较

数据类型Java 中只有8种数据基本类型,C++的基本数据类型较多Java 中的8种基本数据类型为:boolean, byte, short, int, long, float, double, charc++ 中的数据类型较多,且部分写法有所区别:bool, short, int, long, float, double, char基本数据类型占用的字节数有所区别,因为 Java ...

2020-03-26 22:45:44 313

原创 2. 数组

2.1 数组的结构数组,是一块连续的内存区域,且具有相同类型的数据结构。说回上一次的图。(图片修改自极客专栏:《数据结构与算法之美》)这就是数组的一块内存区域。我们提下上面说的两个特点:连续内存区域相同的数据类型这两个特点有什么好处呢?我们上次说到,如果我们想要查找一个房间1036(一块数据),我们站在上图中1000的位置,然后有下面两种方式:从1000走4步,到1004...

2020-03-26 00:33:19 126

原创 1. 数据结构概述

1.1 什么是数据结构说到数据结构,我觉得可以拆分成两个词,数据和结构。先来打个比方。同样是水,有的被放进了游泳池,成为了游泳嬉戏的场所;有的被放进了杯子,供我们喝水;我们不可能喝水,不用杯子,用游泳池。说到底,就四个字:因地制宜???(好像比较恰当,欢迎大家集思广益)数据就好比这里的水,是我们想要使用的东西,对我们有价值的东西;结构就好比游泳池、杯子,是帮助我们更好的使用数据,...

2020-03-25 17:14:16 201

原创 动态规划专题:LeetCode 完全平方数

原题链接279. 完全平方数思路这道题跟之前的动态规划有些区别。刷了不少动态规划的题目。大部分的结构,都是类似于这种形式dp[i] = Math.max(min)(dp[i-n]+k, dp[i-m]+k1) + M这种形式,涉及到最大小值,肯定涉及到题目求解的最值问题而且一般绝大多数情况下是,时间复杂度都是O(n)。这次的题目,主要涉及到一些关键点的处理。如果不考虑这些关键点,...

2020-03-24 23:14:34 155

原创 动态规划专题:LeetCode 乘积最大子数组

原题链接乘积最大子数组思路刷题得按专题刷,发现这道题很有意思。因为负数的引入,导致推导状态就比较麻烦。看了题解,分别记录最大值和最小值。当遇到负数的时候,最大值将会变为最小,最小将会变为最大。真的很巧妙。算是开拓了一个新的思路。class Solution { public int maxProduct(int[] nums) { int max = Intege...

2020-03-24 19:54:15 165

原创 动态规划专题:LeetCode连续数列

LeetCode题目链接面试题 16.17. 连续数列这个题目和最大子数列是一个题目思路用 dp[i] 表示,连续数列的和。当 dp[i-1] 小于0的时候,它如果加上nums[i]的话,肯定比单独的nums[i]小。此时,设置 dp[i] 为 nums[i]。如果它大于0,可以让其尝试继续相加。这里的dp[i]并不是说 i 位置前面连续数列的最大值。实现class Soluti...

2020-03-24 15:09:00 203

原创 动态规划专题:LeetCode 按摩师

LeetCode题目面试题 17.16. 按摩师思路为什么要用动态规划在知道如何使用动态规划前,知道何时使用动态规划最重要吧。如果你要知道最后一天的值,取决于第三天做不做,这就是二叉树的结构,一般涉及到两个选择的,画下的话,可以看到有重叠部分,可以考虑动态规划。遇到最值问题的时候,后面的选择取决于前面选择的时候,考虑动态规划。遇到子序列的(可不连续)的时候,考虑动态规划。最重要...

2020-03-24 13:39:25 189

原创 3. 无重复字符的最长子串

原题链接3. 无重复字符的最长子串解题思路在谈及重复问题,大概率会使用 hashmap 或者 hashset最长子串,因为是连续的,所以有点想使用滑动窗口的方法滑动窗口在 HashMap 中维护一个表,这个表的作用:记录每个字符最后一次出现的位置索引HashMap 天然是无重复的以abcba举例,在检索到abc的时候,在hashmap中存入,a-0,b-1,c-2。当检...

2020-03-23 11:21:04 93

原创 字典树(前缀树/后缀树)

用途有人说是为了统计字频,可我觉得 HashMap 就可以完成。有人说比 HashMap 占用内存要小,但我感觉小也小不到哪里去。有人说为了查询字符,还是那句话,HashSet 表示我也可以。也许在 Hash 没有出来前,它也许在这些领域占有一席之地。目前,从数据结构来看,我认为它的作用也许在以下方面比较突出:也被称为 前缀树,就是剔除相同的前缀操作,这里看不懂很正常,后面慢慢说搜索提...

2020-03-22 17:23:11 917

原创 10. 排序算法思想概述及总结(精华)

排序算法的常用种类初级排序选择排序插入排序希尔排序进阶排序快速排序归并排序(二叉堆排序)堆排序非比较排序计数排序基数排序桶排序逆序对逆序对,是分析排序算法的一个重要知识点。既然评估排序算法,就要知道如何去描述数组的排序程序。逆序对,数组中两个逆序元素的对数。比如【1, 5, 3】,其中(5, 3)就是逆序的,所以这个数组的逆序对为1。那么...

2020-03-20 15:53:23 403

原创 9. 桶排序

思想桶排序,也是为了解决计数排序计数数组大小设置的问题。桶排序,就是把待排序数据分为不同的区间,然后区间内进行排序,最后即可完成排序。就有点像,成绩会有一个区间,比如100-90, 90-80这样,每个区间就是一个桶,然后对桶内元素进行排序。最后取出来,即完成排序。从上面分析可以看出,我们对区间排序的时候,最好每个区间(桶)中数据是均匀的。至于如何对桶内元素进行排序?这个是一个困惑,网上很...

2020-03-20 15:38:27 138

原创 8. 基数排序

思想基数排序,是按照元素的更小元素组成来进行排序。拿常用的数字排序举例,会先对个位进行排序,然后对十位进行排序。其中,关键是如何对个位进行排序,如何对十位进行排序。我们知道对于数字的每一位,只有10个数字(0-9),这就是基数。所以故名,基数排序。基数排序所以可以理解为适用于基数是有限的情况下。所以基数排序中的基数,相当于把计数排序中的计数数组的大小确定下来了。那么如何对个位、十位进行排...

2020-03-20 15:12:26 145

原创 7. 计数排序

思想计数排序,不再依赖元素的比较,而是通过计数的方式,来进行排序。比如,你知道成绩比你高的有5个人,那么你是多少名呢?计数排序就是采用这种思想。计数排序,为每一个元素设置一个计数,然后进行计数排序。从这个思想上来看,计数排序会使用到复制的空间,而且辅助空间的数量为 待排序数组的最大值-最小值+1。从这个分析上,可以知道计数排序适用于 小范围的排序,就是说待排序的数组,最大小值的差值不能太...

2020-03-20 14:52:02 79

原创 6. 快速排序

思想快速排序,是选取一个元素,然后经过交换元素,保证选定元素的左边都小于它,右边元素都大于它。每次操作后,选定元素的位置就是排序后的位置。就像多个人进行高矮个排列一样,你看了下,前面的人都比你矮,后面的人都比你高,那么你就可以不动了,随他们怎么折腾,反正你站的位置对了,他们排序好了,你也还是站在这个位置。实现import java.util.Arrays;public class Qu...

2020-03-20 00:03:07 118

原创 5. 堆排序

思想维护一种数据结构,它可以完成下面两个功能:插入数据;取出最小数据。因为数组和链表均不能均衡这两个功能的时间复杂度。于是采用完全二叉树来实现这两种功能。小堆,每个节点值都小于其子节点的值。其实,就有点像排行榜的感觉,当有新的元素登上排行榜的时候,将会去除最后一名的元素,新加入的元素存储在相应的位置。只不过这个排行榜是用二叉树堆实现的,这个二叉树堆也不想二叉搜索树那样完全有序。其只要求父...

2020-03-19 22:54:35 111

原创 4. 归并排序

思想归并排序,是很有趣的算法,也是我了解的分治算法的启蒙算法。它就是将一个数组,分为两个数组,然后两个数组,继续往下分,指导每个数组子数组有两个元素,这个时候就很容易比较。然后再将其解进行合并。可以这样想,你手上有一堆牌,然后你的手太小了,没法排序,于是你把它按照两个一组放在桌子上。然后你对一组中的两张牌进行排序,然后都排序完后,再对组进行合并。实现import java.util.Arr...

2020-03-19 22:34:26 61

原创 3. 希尔算法

思想希尔算法,是间隔对数组抽样,从而形成多个子数组。在这多个子数组中,保证其排序正确性。然后对抽样间隔逐渐变小,再次保证其排序。对于这些抽样出来的子数组,应该如何排序呢?这里用到插入排序。(选择排序因为需要每次遍历,所以对于部分排序的数组,比较浪费时间)希尔排序的间隔选取也是有讲究的。实现import java.util.Arrays;public class ShellSort ...

2020-03-19 22:04:48 123

原创 2. 插入排序

思想将数组分为排序和未排序两部分,每次从未排序部分选取一个元素,按顺序插入到已排序部分。想象你打牌的时候,手上拿的是已排序的拍,每次抓牌的时候,都是把抓到的牌(未排序)按顺序插入到手上已排序的牌中。插入的策略,交换相邻元素或者移动插入。每进行一个相邻交换,逆序对减一。实现import java.util.Arrays;public class InsertSort { pub...

2020-03-19 21:07:04 111

空空如也

空空如也

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

TA关注的人

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