自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 Groovy基础

在使用动态语言编写程序时,变量的类型不需要在声明时明确指定,而是在运行时根据赋给变量的值来确定类型。Closure.DELEGATE_FIRST,优先级:delegate > owner,闭包首先在其delegate上查找属性和方法,如果找不到,则在owner上查找。Closure.OWNER_FIRST,优先级:owner > delegate,闭包首先在其owner上查找属性和方法,如果找不到,则在delegate上查找。总结:如果闭包定义在类中,则owner指向的是类的实例;,而不需要显式声明参数。

2025-02-08 19:21:27 1009 1

原创 手写一个路由框架实现页面跳转

相信大家现在已经知道框架是怎么做出来的吧,先完成需求,再慢慢优化我们这个框架用到了:APT、反射、PMS、类加载、javapoet等技术。

2024-11-25 19:01:48 913

原创 第一个设计模式——单例模式

1.反序列化破坏:将一个单例对象进行序列化后,再反序列化,而反序列化的对象和程序对象不是同一个对象。缺点:可能被反序列化和反射破坏、浪费资源,当你不需要单例实例,只想调用类中的静态方法时,它都会帮你执行静态代码块和静态变量,因为类加载。优点:是线程安全的,因为JVM在进行类加载的时候,会进行加锁,每个类只有一份class对象,然后类加载的时候就会执行静态代码块、静态变量。缺点:不能继承其它类,因为它内部已经继承了Enum类、它的线程安全是依靠类加载,但是类加载是耗性能的。指在类加载时就完成了初始化。

2024-07-28 19:14:13 1001

原创 三张表,搞懂HashMap的基础

怎么解决hash冲突?当由key计算出来的hash相同时,HashMap使用的是链表或红黑树来解决。3.当数组的元素数量已经到达当前容量的75%(默认阈值是0.75),则进行扩容。2.当存在链表节点长度>=8,但数组长度小于64时,则进行扩容。1.数组为空,首次扩容。每次扩容原来的2倍长的新数组。什么时候会进行扩容?

2024-07-28 11:02:11 313

原创 HashMap详细讲解

如果不为空则进行添加元素,先通过(n-1)&hash计算出在数组的索引值,然后判断该索引是否有数据,如果没有则直接创建一个Node存到该索引上,如果有则说明该索引上已有数据(称为hash冲突),那么就有两种情况:第一种情况是当该索引上的Node的key是否与我们传进来的key相同并且hash相同,如果相同,则覆盖value;如果不是,则走链表的添加流程,通过循环找到next为null的Node,当在循环的过程中,如果找到了和传入的key一样的key,hash值也一样,那么就覆盖value;

2024-07-28 10:52:52 1048

原创 java的八大包装类

复杂操作的场景,场景1:比如定义一个Integer类型的变量,用它作为一个方法的返回值,这个方法经过一系列的操作,最后得到一个Integer类型的数据,我们并不知道他最后返回一个什么东西,有可能是数字,也有可能是个null值,如果我们用int类型来接收null的话,就会出现空指针异常,这时候就得用包装类来接收。场景2:再比如我们想要得到int的最大值,这时基本数据类型是得不到的,但包装类可以,它内部有一个静态变量,该变量存的是int类型的最大值。1.由于包装类是个类,它有丰富的方法,可以做复杂的功能。

2024-07-27 16:48:52 1200

原创 还搞不清楚String、StringBuilder、StringBuffer?

代码解释:在堆中创建StringBuilder对象,然后builder指向该对象,"hello"存在StringBuilder 的成员变量value中,value是指向堆的一个byte[]对象,这个byte[]对象的值为"hello"。代码解释:在堆中创建StringBuffer对象,然后buffer指向该对象,"hello"存在StringBuffer的成员变量value中,value是指向堆的一个byte[]对象,这个byte[]对象的值为"hello"。如果大于0,则需要扩容,然后通过复制达到扩容。

2024-07-27 10:56:46 2288

原创 线程并发工具类——fork-join

分而治之是一个算法设计思想,它就是把大问题分割为多个相同的小问题,并且小问题之间无关联,如果小问题之间有关联就叫做动态规划。像我们的归并排序算法就利用这个思想二、Fork-Join就体现了分而治之原理:就是在必要情况下,将一个大任务,进行拆分(fork)成若干个小任务(拆到不可再拆时),再将一个个小任务运算的结果进行join汇总起来。

2024-07-23 14:53:25 611

原创 线程的协作——线程之间相互配合,完成某项工作

例如:一个线程修改了一个对象的值,而另一个线程感知到了变化,然后进行相应的操作,整个过程开始于一个线程,而最终执行又是另一个线程,前者是生产者,后者是消费者。要想做到上面的需求,我们常规思路是:让消费者线程不断地循环检查变量是否符合预期在while循环中设置不满足的条件,如果条件满足则退出while循环,从而完成消费者的工作。但是却存在如下问题:1)难以确保及时性2)难以降低开销,如果降低睡眠的时间,比如休眠1。

2024-07-22 21:48:40 427

原创 四大引用——强软弱虚

强引用是在程序代码之中普遍存在的,类似于“Object obj = new Object()”,obj变量引用Object这个对象,就叫做强引用。“虚引用”顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。弱引用(WeakReference)也是用来描述非必需对象的,但是它的强度比软引用更弱一些,每次执行GC的时候,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。

2024-07-22 20:37:49 580

原创 使用ThreadLocal——解决线程共享安全问题

ThreadLocal是一个类,为每个线程都提供了变量的 副本,使得每个线程在某一时间访问到的并非同一个对象,这样就隔离了多个线程对数据的数据共享。

2024-07-22 19:54:51 1127

原创 volatile,最轻量的同步机制

volatile关键字只保证了线程的可见性volatile关键字不能代替synchronized关键字volatile关键字不能保证线程安全volatile关键字适用于一个线程写,多个线程读的场景。

2024-07-22 15:10:16 512

原创 使用synchronized关键字(基础篇)——解决线程共享安全问题

我们先来看一段代码:代码解释:我们开启两个线程去完成count++任务,一个线程加一万次,那么count值为10000,两个线程的话结果应该是20000,但是结果事与愿违,可以得出在多线程下,共同访问一个资源会引发安全问题。什么是线程间的共享?在一个进程中会有多个线程,而这些线程共享进程的资源,就称作线程间的共享。

2024-07-22 10:44:37 460

原创 java线程之守护线程

守护线程也称“服务线程”,它是后台线程,在没有用户线程可服务时会自动离开。主线程、我们自己开启的线程(没有设置为守护线程)就是用户线程。

2024-07-21 20:37:36 468

原创 线程的状态

该状态的线程位于可运行线程池中,等待被线程调度选中,获取。超时等待(TIMED_WAITING)运行状态(RUNNABLE)终止(TERMINATED)阻塞状态(BLOCKED)等待状态(WAITING)

2024-07-21 19:50:50 170

原创 面试官:如何实现线程按顺序执行?

我们先看一段代码:根据我们常规的思路来想(没学线程),我们先启动t1线程,再启动t2线程,肯定是t1先执行,然后执行t2,对不对?但是我们运行多次,会出现t2先执行,t1再执行!这是为什么?是因为当线程调用start方法时,该线程就会等待被分配CPU,一旦获取到了CPU,就可以开始工作。CPU是操作系统进行分配的,分配给谁是不确定的,有可能t1先得到CPU,先执行;有可能t2先得到CPU,先执行;有可能t1和t2同时拿到。这都是说不准的。那用什么方法可以确定线程的执行顺序呢?

2024-07-21 17:14:02 325

原创 深入理解run和start方法

我们都知道Thread类是java里对线程概念的抽象,当我们通过new Thread(),其实只是new了一个Thread的实例,还没有和操作系统中的真正的线程挂起钩来。

2024-07-21 16:32:21 309

原创 如何停止线程工作呢?

定义一个变量,由目标线程去不断的检查变量的状态,当变量达到某个状态时停止线程。我们可以看出t1线程中使用变量来判断是否停止执行业务逻辑,使用Thread.sleep方法让t1线程睡一会,睡醒了,看看flag标志位是否被更改,如果被更改,说明需要停止工作。但是定义变量是有问题的,分为两种情况:1.当标志位已经被我们更改,线程还在睡,睡醒了才能判断标志位是否被更改,这会导致不能及时停止线程工作问题。2.

2024-07-21 14:46:31 2100

原创 Java创建线程的四种实现方式

我们首先看看Thread的构造方法有哪几种,从代码中可以看出我们只传了一个参数进去,说明task要么是Runnable类型,要么是String类型,肯定不是String类型。所以我们可以大胆猜测一下,FutureTask是不是实现了Runabble接口。在上面我们可以看出Runnable的run方法不能定义返回值,Callbale接口的call方法可以定义返回值,只是使用有点复杂。可以看出,FutureTask在run方法中调用了Callable接口的call方法!后续会更新,请耐心等待。

2024-07-19 21:16:09 265

原创 java程序天生就是多线程

可以看到有8个线程,所以java程序天生就是多线程。这里面我们只是调用api查看当前java程序有哪些线程,

2024-07-19 20:34:21 161

原创 高并发编程的意义和注意事项

例如我们在实现电商系统的时候,用户一旦下单,我们就会去发短信通知用户,那用户关心你这个是怎么发送短信的吗?肯定不关心啊,所以我们就可以将向用户发送短信独立为单独的模块,并交给其它线程去执行,这样既增加了异步操作,提升了系统性能,又使程序模块化、简单化。是在面对大量并发请求时,为了保证系统的性能和处理能力,采用相应的编程技术和策略来处理并发任务。例如我们现在下载电视剧的时候,是不是不会一集一集的下,而是同时下载3,4集等等,为什么?多线程是实现高并发编程的一种常见技术和手段。可以使你的代码模块化。

2024-07-19 20:16:20 383

原创 并发和并行

比如单 CPU 核心下执行多线程并非是同时执行多个任务,如果你开两个线程执行,就是在你几乎不可能察觉到的速度不断去切换这两个任务,已达到"同时执行效果",其实并不是的,只是计算机的速度太快,我们无法察觉到而已。例如:吃饭的时候可以边吃饭边打电话,这两件事情可以同时执行。并发是指应用在同一时间间隔能够交替执行不同的任务。并行是指应用在同一时刻能够同时执行不同的任务。

2024-07-19 15:44:25 258

原创 CPU 时间片轮转机制(RR调度)

系统将所有的就绪进程按先来先服务的原则,排成一个队列,每次调度时,把CPU分配给队首进程,并令其执行一个时间片。当执行的时间片用完时,由一个计时器发出时钟中断请求,调度程序便据此信号来停止该进程的执行,并将它送往就绪队列的末尾;但如果顾客太多,或者每个人的饭量不一样(进程的任务大小不同),就需要合理安排每个人的服务时间(时间片的长度),以确保大家都满意。操作系统给每个进程分配一段可运行的时间,该时间就叫做时间片,如果在时间片结束时进程还在运行,则CPU将被剥夺并分配给另一个进程。

2024-07-18 20:54:11 666

原创 java线程必学的进程和线程的概念

比如:在java中,如果你想运行一个java程序,就必须有一个main函数(main函数中啥也不写或者写一点代码),main函数一旦执行,就必定会有一个主线程。CPU 调度的最小单位,是真正执行任务的,必须依赖于进程而存在,一个进程会有多个线程,线程无处不在。线程(Thread)

2024-07-18 19:10:39 222

原创 检查死锁的三种方法

堆栈信息和jstack显示的差不多,堆栈信息中间部分比jstack多出一些信息。该工具是jdk提供的工具,在bin包下。该工具也是jdk提供的,也在bin包下。打开工具,然后选择程序,会自动检测死锁。检测死锁后,可以看到存在死锁的线程。首先使用jps查看Java进程编号。然后使用jstack查看进程信息(),出现以下信息,表示出现了死锁。打开工具,选择要检测的程序。jstack 进程编号。

2024-07-18 18:15:01 1015

原创 Android-----获取系统状态栏和导航栏的高度

3、当我们将一个view的x、y坐标赋了event.x和event.y,希望让view跟着我们触摸点移动时,但会发现我们虽然将触摸点赋给了view,view和我们的触摸点会有一段距离,这段距离就是(状态栏/导航栏/状态栏+导航栏)原因:在onCreate()、onStart()、onResume()中,Activity的视图层级还没有完全建立,DecorView还没有渲染出来,所以会导致无法获取高度。------------------前提是有状态栏或者导航栏------------------

2023-10-18 20:23:53 2093

原创 Activity和Fragment的生命周期

首先点击button进入下一个activity,然后点击back回到上一个activity,最后再点击button进入下一个activity。到第二个Fragment的时候,再触发触摸事件,再进行到第二个Fragment。触摸屏幕,运行触摸事件,进入下一个Fragemt。点到第二个Fragment,将应用保留到后台。点击button跳转到下一个界面。进入应用,然后将app保留到后台。在点击back,回到主屏幕。点击back,回到上一步。点击back,回到主屏幕。点击back,回到上一步。

2023-07-17 08:31:47 156 1

原创 结构体的存储

注:对齐数 = 编译器默认的一个对齐数与该成员大小的较小值。

2022-12-20 09:00:27 118

原创 进阶指针知识点

sgsggsg

2022-12-02 09:14:30 153

原创 指针的相关知识2

1、没有对指针进行初始化----->会初始为随机值2、指针越界访问3、指针指向的空间被释放了。

2022-12-01 22:22:40 146

原创 指针的相关知识

a.malloc()——首次分配eg:mallo(需要多大*sizeof(类型))a.当定义时,只为指针变量分配了8个自己的内存空间(用于存储地址)当对指针加或者减时,操作的是指针指向的元素占据的内存空间*数量。b.如果需要存数据,就必须为这个指针变量指向的区域分配内存空间。a.定义数组时,必须指定元素个数,数组的内容空间由系统分配。b.指针占8个字节的内存空间,和指向的类型没有关系。b.使用地址访问 *(a+0) *(a+1)c.free()——释放自己申请的内存空间。a.指针变量需要内存空间。

2022-11-26 22:44:08 85

空空如也

空空如也

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

TA关注的人

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