暂时未有相关云产品技术能力~
暂无个人介绍
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects。
我们都知道想要实现拷贝需要实现Cloneable接口并在类中实现clone()方法,不过比较神奇的是,clone()方法并不是Cloneable接口中的方法。 Cloneable接口是一个空接口,里面没有任何内容
javac在这一阶段会把java代码编译为class文件,保存在硬盘中,这个文件中保存着这个类的类名、成员名、构造方法、其他方法等。
动态代理是指代理类不是写在代码中的,而是在代码运行过程中产生的,Java提供了两种方式来实现动态代理,分别是基于Jdk的动态代理和基于Cglib的动态代理。
在详细了解反射机制之前,我们先来了解一下java代码在计算机中的运行过程: 比如当我们编写好一个类:Student.java,里面包含学生的姓名和年龄,构造方法,其他方法。
对象头用于存储对象的元数据信息,包括运行时数据和类型指针、实例数据存储的是真正有效数据、对齐填充主要补充字节,使得内存所占字节能被8整除。
线程(thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位,我们的程序最终都是由线程进行运作。在Java中,创建和销毁线程的动作是很消耗资源的,因此就出现了所谓“池化资源”技术。线程池是池化资源技术的一个应用,所谓线程池,顾名思义就是预先按某个规定创建若干个可执行线程放入一个容器中(线程池),需要使用的时候从线程池中去取,用完之后不销毁而是放回去,从而减少了线程创建和销毁的次数,达到节约资源的目的。
执行cancel(true)方法将以中断执行此任务线程的方式来试图停止任务,如果停止成功,返回true;当任务已经启动,执行cancel(false)方法将不会对正在执行的任务线程产生影响(让线程正常执行到完成),此时返回false;当任务已经完成,执行cancel(...)方法将返回false
Java中创建线程的方式主要有四种: 1.继承Thread类实现run方法 2.实现Runable接口实现run方法 3.实现Callable接口实现call方法 4.使用线程池实现
乐观锁和悲观锁不是两种具体的锁,而是一种观念。 乐观锁:乐观锁认为对于同一个数据的并发操作,是不会发生修改的。在更新数据的时候,会采用尝试更新,不断重新的方式更新数据。乐观的认为,不加锁的并发操作是没有事情的 悲观锁:悲观锁认为对于同一个数据的并发操作,一定是会发生修改的,哪怕没有修改,也会认为修改。因此对于同一个数据的并发操作,悲观锁采取加锁的形式。
迭代器模式是二十三种设计模式之一,这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。 在Java中,通过iterator.hasNext()检测是否存在下一条记录,通过iterator.next遍历集合中的元素。
在高并发的情况下,如果所有的数据都从数据库中去读取,那再强大的数据库系统都承受不了这个压力,因此我们会将部分数据放入缓存中,比如放入redis中。这是典型的用空间换时间的方式。 但是这个redis相当于是真实数据的一个副本,这就意味着如果数据库中数据发生变化的时候,就会导致缓存数据不一致的问题。 归根结底,只要有两份数据存在,数据一致性问题就是不可避免的。
BIO即同步阻塞IO,实现模型为一个连接就需要一个线程去处理。这种方式简单来说就是当有客户端来请求服务器时,服务器就会开启一个线程去处理这个请求,即使这个请求不干任何事情,这个线程都一直处于阻塞状态。
异步任务的需求在实际开发场景中经常遇到,Java实现异步的方式有很多,比如多线程实现异步。在SpringBoot中,实现异步任务只需要增加两个注解就可以实现。当前类添加@Async注解,启动类添加@EnableAsync
抽象类必须要有抽象方法吗?抽象类能使用 final 修饰吗?
两个对象的 hashCode()相同,则 equals()也一定为 true吗?
HashMap底层是一个哈希表,以数组加链表的形式存储值。HashMap具有以下特点: 1.HashMap允许key和value为空 2.HashMap是线程不安全的 3.HashMap的初始容量为16,负载因子大小为0.75 4.在jdk7.0中,底层是数组加链表;在jdk8.0中,底层是数组加链表加红黑树
每天一个知识点(三)如何让多个线程按顺序执行?
不一样,使用String str="i",java虚拟机会把它分配到常量池中,而 String str=new String(“i”)创建了一个对象,会被分到堆内存中。
final作为Java中的关键字可以用于三个地方。用于修饰类、类属性和类方法。
Shiro是Apache的一个安全框架,Shiro可以非常容易的开发出安全性足够好的应用,Shiro可以完成认证、授权、加密、会话管理、缓存等功能。 从应用程序的角度来观察Shiro,我们可以发现Shiro的运行过程主要如下:
对于一个Web项目来说,最重要的不是功能酷不酷炫,而是这个项目安不安全。做过项目的人都知道,一个项目在上线前一定会经过安全漏扫,只有通过安全漏扫后这个项目才能正式上线。 Spring Security是一个功能强大且高度可定制的身份验证和访问控制框架,类似的安全框架还有Shiro。 Spring Security主要做两个事情,认证、授权。
SpringBoot底层统一采用SpringData处理数据库,这一章主要来讲一下SpringBoot整合jdbc、durid、mybatis的方式。
springboot的配置文件中存在大量的配置,这一点在官网上就能看到了: docs.spring.io/spring-boot… 如果要用的时候直接去官方文档或者百度取确实是个办法,但却并不是最好的办法,最好的办法是理解这些配置文件的原理,以后要用的时候直接通过原理去写配置文件。 在前面一章讲自动装配的时候我们已经知道了,Springboot项目在启动时会去META-INF/spring.factories取配置信息
Springboot相比于之前spring的一个很大进步在于我们不用再手动配置一系列配置文件,springboot会自动帮我们配置。关于springboot自动装配的原理我们依旧需要了解。
SpringBoot作为现在工作中最常用的一个框架,大部分人对他都只做到了会用这一步,但是SpringBoot的许多细节却被我们所忽略掉了,因此我打算写这样一个有关SpringBoot的系列文章,争取能让不管是新手还是老手都能从中再学到东西。
在对大量网站进行网页爬虫时,一般需要两步,先对url进行搜集,再对每一个url进行爬取。这里很有可能搜集到的url是重复的,因此需要在第一步对url进行去重。如何去重呢?你会想到将url放进HashSet中,但是如果url的数量过大,HashSet是撑不住的。 我们在看新闻或者看抖音时,它会不停推荐新内容给我们,推荐时需要去除已经看过的内容,那么如何实现去重呢?你会想到服务器记录了用户看过的所有记录,推荐时从历史记录中去筛选,但是当用户量很大,并且用户看过的新闻很多,性能能跟上吗? 另外在遇到缓存穿透问题时,请求绕过缓存直接读取持久层数据库,能否在请求来的时候先进行一次过滤,如果确定所请求的k
当用户想要查询一个数据的时候,发现redis内存数据库中没有,于是向持久化数据库查询发现也没有,相当于请求绕过缓存直接打到持久层。当用户很多的时候,如果大量缓存都没有命中,于是都去请求了持久化数据库,这会给持久化数据库带来很大的压力,这就是缓存穿透。
在前面的博客系列中,我们把redis的基础语法配置等比较详细的讲了一遍,但如果要用现在更多的是集成到spring系列的框架之中,今天我们就来讲解springboot集成redis的方法以及一些注意点。
前面我们讲了redis的主从复制,为了实现高可用,会选择一台服务器作为master,多台服务器作为slave。现在有这样一种情况,master宕机了,这时系统会选择一台slave作为master,然后把宕机的master下线,再通知所有slave新的master是谁。这里就产生了一个问题,master是否宕机、选择哪台slave作为master都是谁来决定的?
前面所讲的关于redis的操作都属于单机操作,单机操作虽然操作简单,但是处理能力有限,无法高可用。所谓高可用性,就是指当一台服务器宕机的时候,有备用的服务器能顶替上,在单机操作上这是无法实现的,因此就出现了主从复制。 我们把一台服务器看作是主服务器(master),把另外多台服务器看作是从服务器(slave),主从复制就是将master中的数据即时有效的复制到slave中。
高级数据类型和五种基本数据类型不同,并非新的数据结构。高级数据类型往往是用来解决一些业务场景。
谈到数据库的高级应用,不可避免会谈到事务。熟悉mysql的朋友们对事务肯定不陌生,简单来讲事务就是控制一个数据库操作序列要么全部执行要么全部不执行。今天我们就来了解redis中的事务是如何执行和使用的。
持久化顾名思义就是将存储在内存的数据转存到硬盘中。在生活中使用word等应用的时候,如果突然遇到断电的情况,理论上数据应该是都不见的,因为没有保存的word内容都存放在内存里,断电后就会清空,但是重新开启电脑后会发现有一个~$xx.docx的文件,虽然不一定保存所有数据,但是会将大部分数据保存下来,这种“自动备份”这就是持久化的一种实际案例。
如果不把数据库和后端语言联系起来,就起不到数据库应该要起到的作用。Java语言通过JDBC操作mysql,用Jedis操作redis。当然了,java操作redis的方式不止jedis一种,现在我们主要使用Jedis来操作redis。
五种数据类型都用到了key,key本身是一种字符串,通过key可以获取redis中保存的对象。这一篇博客就将介绍key的通用操作。
欢迎关注同名公众号《Java鱼仔》,更多知识点你值得拥有 在前面一篇博客中我们已经学完了redis的五种数据类型操作,回顾一下,五种操作类型分别为:字符串类型(string)、列表类型(list)、散列类型(hash)、集合类型(set)、有序集合类型(sorted_set)。学完基础语法操作后下一步就是通过几个案例来实践操作一下redis。在这里不会采用任何其他语言,单纯使用redis进行模拟操作。
如果你是计算机专业学生 ,那么一定使用过关系型数据库mysql。在请求量小的情况下,使用mysql不会有任何问题,但是一旦同时有成千上万个请求同时来访问系统时,就会出现卡顿甚至系统崩溃的情况。最典型的例子就是早期的12306购票网站,一旦到了购票高峰期,12306肯定崩溃。造成这个原因的罪魁祸首就是关系型数据库。
欢迎关注同名公众号《Java鱼仔》,更多知识点你值得拥有 开场 一位穿着蓝色衬衫,牛仔裤,拿着一个白色保温杯的中年男子急匆匆地坐在你对面,看样子是项目上的东西很急,估摸面试时间不会太长,这样一想心情放松了许多......(后来我就被打脸了)
在前面一篇博客中,通过mysql的优化解决了超卖的问题,但是没有解决同一用户有几率多次购买的问题,这个问题可以通过加锁来解决,解决思路在于一个请求想要购买时需要先获得分布式锁,如果得不到锁就等待。
在没有高并发的环境下,做到现在已经算是一个比较完善的后端逻辑了,但是如果同时有1000个请求或者更多请求的时候,就会产生很多问题,包括秒杀最怕的超卖。想一下,秒杀活动本来就是不赚钱甚至是亏钱的活动,如果超卖了,发货就代表亏本,不发货直接影响信用。因此绝不能出现超卖的情况。
消息中间件属于分布式系统中一个子系统,关注于数据的发送和接收,利用高效可靠的异步消息传递机制对分布式系统中的其余各个子系统进行集成。java中常用的消息中间件有ActiveMQ、RabbitMQ、Kafka等等。消息中间件的作用主要有系统解耦、异步调用、流量削峰等等。
抢购功能是整个系统的核心,接下来的很多优化都是在优化抢购功能,在写抢购功能模块之前,先封装几个公共的类。
在上一篇博客中,我们已经搭好了系统的主要架构,目前已经可以跑通这个项目,接下来我们就可以把注意力都集中在代码上。本次需要创建的代码目录。
我搭建了一个微信公众号《Java鱼仔》,如果你对本项目有任何疑问,欢迎在公众号中联系我,我会尽自己所能为大家解答。
如今的应用系统已经不再局限于简单的单机环境或者几百几千的点击量,像每年的618和双十一,各大电商平台都会同时接收到千万级的点击量,因此有了做这个秒杀项目的想法。 系统后端采用SpringBoot,前端用了BootStrap框架,因为这次的主要目的是后端逻辑的学习,因此本项目不再注重前端的处理。
线程(thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位,我们的程序最终都是由线程进行运作。在Java中,创建和销毁线程的动作是很消耗资源的,因此就出现了所谓“池化资源”技术。线程池是池化资源技术的一个应用,所谓线程池,顾名思义就是预先按某个规定创建若干个可执行线程放入一个容器中(线程池),需要使用的时候从线程池中去取,用完之后不销毁而是放回去,从而减少了线程创建和销毁的次数,达到节约资源的目的。
今天公司的一个需求需要统计一个数据库中表的行数有多少,二话不说当然就直接用count()这个聚合函数,以前经常听到一种说法说count(1)的效率比count(*)要高,于是测试了一下count(1)和count(*)的速度差距,发现两者的查询速度很接近,甚至count(*)要更快一些,于是就有了这篇文章。
Map中用到最多的是HashMap,有关HashMap的介绍和底层源码的分析可以看我之前的文章。 HashMap有个很致命的问题就是他并非线程安全,因此在多线程环境下使用HashMap会出现问题,HashTable线程安全,但是它的效率太低了,ConcurrentHashMap就出现了,ConcurrentHashMap兼顾了线程安全和速度,下面就从底层源码出发来了解一下ConcurrentHashMap。这里用到的JDK版本是1.8。
OSI网络体系结构分为七层: 从下到上分为:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层 TCP/IP协议结构分为四层: 从下到上分为:网络接口层、网际层、传输层、应用层 网络接口层对应于OSI的物理层和数据链路层,应用层对应于OSI的会话层、表示层、应用层。