JAVA学习之Memcached

JAVA学习之Memcached 1、安装及命令 下载完成后,使用管理员运行cmd,进入memcached的目录下,即memcached.exe所在的目录 安装命令:memcached -d install 启动命令:memcached -d start 修改端口命令: memcached.exe -p 11211 -m 64 ( 指定它的监听端口是11211(这是它的默认端口,可以指定为其它大于1024的端口,因为小于1024的端口已经有了默认指定),最大使用内存为64m) 远程连接命令:telnet 127.0.0.1 11211 (注意:memcached默认的端口就是11211) 链接成功之后,可输入命令: stats --> 查看状态 quit --> 退出链接 flush_all --> 刷新 存储命令的格式: <command name> <key> <flags> <exptime> <bytes> <data block> 参数说明如下: <command name> set/add/replace <key> 查找关键字 <flags> 客户机使用它存储关于键值对的额外信息 <exptime> 该数据的存活时间,0表示永远 <bytes> 存储字节数 <data block> 存储的数据块(可直接理解为key-value结构中的value) 常用的几个命令:add/set/get/delete/gets/cas/replace 2、spring集成memcached过程 首先增加memcached的连接属性文件xmemcached.properties,代码如下: #连接池大小即客户端个数 memcached.connectionPoolSize=1 memcached.failureMode=true #server1 memcached.server1.host=127.0.0.1 memcached.server1.port=11211 memcached.server1.weight=1 然后增加spring对xmemcached的整合文件xmemcached.xml,代码如下: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="

JAVA学习之终端适配(spring根据设备自动切换页面)

1、页面适配(自动识别终端设备) 引入依赖 <springframework.mobile.version>1.1.5.RELEASE</springframework.mobile.version> <dependency> <groupId>org.springframework.mobile</groupId> <artifactId>spring-mobile-device</artifactId> <version>${springframework.mobile.version}</version> </dependency> 增加web-mobile.xml配置文件 <?xml version="1.0" encoding="GB2312"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> <!-- spring mobile --> <mvc:interceptors> <bean class="org.springframework.mobile.device.DeviceResolverHandlerInterceptor" /> <bean class="org.springframework.mobile.device.site.SitePreferenceHandlerInterceptor" /> </mvc:interceptors> <!--spring 3.0不支持此种方式--> <!--<mvc:annotation-driven> <mvc:argument-resolvers> <bean class="org.springframework.mobile.device.DeviceWebArgumentResolver" /> </mvc:argument-resolvers> </mvc:annotation-driven>--> <bean class="org.springframework.mobile.device.view.LiteDeviceDelegatingViewResolver"> <constructor-arg> <ref bean="viewResolver"/> </constructor-arg> <property name="order" value="1"/> <property name="enableFallback" value="true" /> <property name="mobilePrefix" value="${mobile.view.prefix}" /> <!-- <property name="tabletPrefix" value="tablet/" /> --> </bean> </beans> 增加全局变量

JAVA学习之SpringBoot增删改查demo

1、安装JDK、安装MAVEN、安装MTSQL、安装tomcat、建表、创建项目,导入依赖 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 配置devtools开启热部署 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> <!-- 配置tomcat启动器(tomcat我们自己提供) --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <!-- 在就容器上借助工具运行spring boot --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-legacy</artifactId> <version>1.1.0.RELEASE</version> </dependency> <!-- 配置MyBatis启动器 --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.0</version> </dependency> <!-- 配置mysql驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- 配置c3p0连接池 --> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.18</version> <scope>provided</scope> </dependency> <!-- 单元测试 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <!

java String方法入参赋值问题分析

最近看到了一个很有意思的面试题,该题看似简单但是实际考查的知识点颇为广泛。 我们先来看题: // 请写出执行结果 public class StringExer { String str = new String("good"); char[] ch = {'t','e','s','t'}; public void change(String str,char ch[]) { str = "test ok"; ch[0] = 'b'; } public static void main(String[] args) { StringExer stringExer = new StringExer(); stringExer.change(stringExer.str,stringExer.ch); System.out.println(stringExer.str); System.out.println(stringExer.ch); } } 可能部分同学粗略一看,这个题挺简单的,会认为就是修改了str的值,又修改了数组的第一个下标的值,会输出: test ok best 可能看到这里,你可能已经复制了上面你的代码,默默的缩小浏览器,打开IntelliJ idea工具,粘贴上代码去执行以便确认自己认为的结果。 其实不用这么麻烦,上面给出的答案其实是错误,正确的输出结果为: good best 我们来分析一下: 首先,change方法的入参类型为String类型和char数组类型,都属于引用类型,故change(String str,char ch[])这里的str和ch的引用都和成员变量中str和ch的指向是一致的。 然后change方法里面又执行了str = "test ok";,这个地方很关键,我们需要先了解一下String类型在内存中的不可变性。 举个例子: String str = "abc"; str = "

angular和vue对比

框架对比 1.体积和性能 相较于vue,angular显得比较臃肿,比如一个包含了 Vuex + Vue Router 的 Vue 项目 (gzip 之后 30kB) ,而 angular-cli 生成的默认项目尺寸 (~65KB) 还是要小得多。 在渲染性能上,这两个框架都很快,性能上几乎没有差别。 2.开发效率 都提供了各自的脚手架工具,帮助提高从开发到构建打包的整套过程,另外均可以基于组件化开发,编写可复用的组件,大大较少重复性的工作。但angular凭借 Typescript 本身比 JavaScript 更加工程化的优势,在都是团队开发的情况下,angular会更具优势。 3.灵活性 Vue 相比于 Angular 更加灵活,可以按照不同的需要去组织项目的应用代码。比如,甚至可以直接像引用jquery那样在HTML中引用vue,然后仅仅当成一个前端的模板引擎来用。 4.可维护性 我理解的可维护性包括两个层次,一是代码的可读性,二是可重构性。同样是因为对TS(能提供静态类型检查)的支持不够全面,使得vue在这两个层次都有些不足。vue作者本人也承认vue在TS 的支持上还有所不足,在3.0版本中将会有所改进。 5.es6支持 es6是新一代的javascript标准,对JavaScript进行了大量的改进,使用es6开发已是基本需求。虽然有部分十分老旧的浏览器不支持es6,但是可以利用现代开发工具将es6编译成es5。在对es6的支持上两者都做得很好,(TS本身就是es6的超集) 6.学习曲线 针对前端而言,angular的学习曲线相对较大,vue学习起来更容易一些。不过对java和c的使用者而言,angular的静态检查、依赖注入的特性,以及面向对象的编程风格,使得angular都要更亲切一些。 7.使用热度 在使用热度上,vue具有更大优势,主要原因是更受数量庞大的中国开发者欢迎。较低的上手难度,易懂的开发文档,以及国人主导开发的光环,都使得vue更为流行。但最近6个月似乎情况有所变化:

使用ggeasy R软件包更轻松地进行ggplot

ggplot2数据可视化R软件包非常强大且灵活。 但是,记住如何完成每个任务并不总是那么容易-尤其是如果您不是经常使用的用户。 如何更改图形标题的大小? 如何删除图例标题? 我通常的解决方案是保存RStudio代码段以备不时之需 。 但是还有一个可以帮助您的软件包: ggeasy 。 正如其名说,ggeasy的目标是,好了,让GGPLOT2容易-或至少EASI 呃 。 有些人可能会发现它对于典型的任务(大多数是围绕文本和轴格式设置)具有更直观的功能。 (此程序包不会影响线,点和条的外观和行为方式)。 所有ggeasy函数都以easy_ ,是的,很容易使用RStudio自动完成功能找到它们。 您可以在上面的视频中看到它的工作原理。 [ 在InfoWorld的“用R做更多”的视频系列中获取Sharon Machlis的R技巧 | 按任务,主题或程序包搜索“用R做更多”操作视频 ] 如果您想按照下面的示例进行操作,则ggeasy在CRAN上,因此可以使用install.packages("ggeasy") 。 我还将自然使用ggplot2,dplyr,rio和lubridate软件包。 稍后,我将添加补丁程序包,以使多个图形的放置变得非常简单。 这也在CRAN上。 对于此示例,我将使用有关当今大多数人心目中的数据:冠状病毒。 您可以从Coronavirus Tracking Project通过以下方式下载包含美国各州数据的CSV文件: download.file("http://covidtracking.com/api/states/daily.csv", destfile = "covid19.csv") (您可以将destfile目标文件命名为任意名称。)我使用rio::import()导入数据,但也可以使用readr::read_csv() , read.csv() , data.table::fread()或任何其他导入CSV的函数。 使用rio,日期以整数形式输入,因此我将使用lubridate的ymd()函数将该列转换为Date对象: data$date <- lubridate::ymd(data$date) 要创建一个不太难理解的图形,我将针对几种状态过滤此数据,因此不会有50条单独的时间序列线。 我选择路易斯安那州来看看那里的案件数量上升–路易斯安那州州长说,该州是全世界案件数量增长最快的国家之一。 (有猜测称,二月份的狂欢节可能导致了新奥尔良的一个集群。)我还将添加马萨诸塞州,该州的人口比路易斯安那州多50%,因为我在这里居住。 过滤数据后,我将创建数据的基本折线图: states2 <- filter(data, state %in% c("LA", "MA")) ggplot(states2, aes(x = date, y = positive, color = state)) + geom_line() +

clickHouse的安装配置流程:

clickHouse的安装配置流程: 本次CH集群设计:4个节点、2分片、2副本 1、首先下载CH的安装包: (默认下载最新版) 1. curl -s https://packagecloud.io/install/repositories/Altinity/clickhouse/script.rpm.sh | sudo bash 2. yum list 'clickhouse*' 3. yum install -y clickhouse-server clickhouse-client 指定版本安装: sudo yum install clickhouse-server-common-20.3.12.112-1.el7.x86_64 sudo yum install clickhouse-common-static-20.3.12.112-1.el7.x86_64 sudo yum install clickhouse-server-20.3.12.112-1.el7.x86_64 sudo yum install clickhouse-client-20.3.12.112-1.el7.x86_64 启动命令:service clickhouse-server start 2、更改配置文件: cd /etc/clickhouse-server 有一个config.xml配置文件 3、修改配置文件中的参数: config.xml如下 <?xml version="1.0"?> <!-- NOTE: User and query level settings are set up in "users.xml" file. --> <yandex> <logger> <!-- Possible levels: https://github.com/pocoproject/poco/blob/poco-1.9.4-release/Foundation/include/Poco/Logger.h#L105 --> <level>warning</level> <log>/var/log/clickhouse-server/clickhouse-server.

Java内存模型:解决可见性、有序性和原子性问题

在并发编程基础:线程安全问题的源头一文中,我们讲了在并发场景中导致线程安全的源头——可见性、原子性、有序性。这三者在编程领域属于共性问题,所有的编程语言都会遇到,Java 在诞生之初就支持多线程,自然也有针对这三者的技术方案,而且在编程语言领域处于领先地位。所以在这一篇中讲一下Java是如何保证多线程下的可见性、原子性、有序性的。 内存模型 每一种CPU的设计实现可能都是不同的,有的可能对CPU利用率和执行效率要求很高,所以它的乱序执行程度很高,有的可能要求更低,所以乱序执行程度很低。假如我们要编写一个跨平台的多线程程序,那么我们必须去深入了解每一款CPU的细节,来保证在正确的位置插入正确的、足够多的内存屏障。对程序员来说,这实在是太难了,我不能为了写一个多线程程序,去把所有的CPU都了解一遍,然后计算在哪个位置添加内存屏障才能保证对所有CPU都适用。 正确的做法应该是制定一套规范,然后让设备厂商去实现这个规范,然后使用这些统一的规范进行编程,然后在不同的平台下让编程语言、编译器来生成合适的内存屏障。因此,我们有了内存模型的概念(内存模型是一种规范)。 为了保证共享内存的正确性(可见性、有序性、原子性),内存模型定义了共享内存系统中多线程程序读写操作行为的规范。通过这些规则来规范对内存的读写操作,从而保证指令执行的正确性。它与处理器有关、与缓存有关、与并发有关、与编译器也有关。它解决了CPU多级缓存、处理器优化、指令重排等导致的内存访问问题,保证了并发场景下的一致性、原子性和有序性。 内存模型解决并发问题主要采用两种方式:限制处理器优化和使用内存屏障。 Java内存模型(JMM) 一、Java 内存模型(JMM) 1、JMM规范了Java虚拟机与计算机内存间协同工作 并不是所有的硬件架构都提供了相同的一致性保证(就算是MESI,也只解决CPU缓存层面的问题,没有涉及其他层面)。Java作为一门跨平台语言,JVM需要提供一个统一的语义来规范一致性保证,所以有了JMM;Java作为一个跨平台的语言,它的实现要面对不同的底层硬件系统和操作系统。为了统一这种差异性,Java虚拟机规范中定义了Java内存模型,用于屏蔽掉各种硬件和操作系统的内存访问差异,实现让Java程序在各种平台下都能达到一致的并发效果。通俗的来讲,就是描述Java中各种变量(线程共享变量)的访问规则,以及在JVM中将变量存储到内存和从内存中读取变量这样的底层细节。Java内存模型规定了不同线程如何以及何时可以看到其他线程写入共享变量的值以及如何在必要时同步对共享变量的访问。也可以说它规范了 JVM 如何提供按需禁用缓存和编译优化的方法(Java内存模型是一个很复杂的规范,只不过从我们程序员的角度来说更关注这一个方面)。具体来说,这些方法包括 volatile、synchronized 和 final 三个关键字,以及六项 Happens-Before 规则。并且支持大部分的主流硬件平台。 2、从抽象的角度来看,JMM定义了线程和主内存之间的抽象关系: 线程之间的共享变量存储在主内存(Main Memory)中;每个线程都有一个私有的工作内存,工作内存是JMM的一个抽象概念,并不真实存在,它涵盖了缓存、写缓冲区、寄存器以及其他的硬件和编译器优化。工作内存中存储了该线程以读/写共享变量的拷贝副本;从更低的层次来说,主内存就是硬件的内存,而为了获取更好的运行速度,虚拟机及硬件系统可能会让工作内存优先存储于寄存器和高速缓存中;Java内存模型中的线程的工作内存(working memory)是cpu的寄存器和高速缓存的抽象描述。而JVM的静态内存储模型(JVM内存模型)只是一种对内存的物理划分而已,它只局限在内存,而且只局限在JVM的内存。 3、JMM解决的问题 类似于物理内存模型面临的问题,JMM 也存在以下两个问题:工作内存数据一致性、指令重排序优化。我们知道导致可见性的原因是工作内存数据的不一致,导致有序性的原因是编译优化,那解决可见性、有序性最直接的办法就是禁用缓存和编译优化,但是缓存与编译优化的引入是为了提高CPU的执行效率,禁用虽然解决了问题,但是我们程序的性能会大打折扣。所以合理的方案应该是按需禁用缓存以及编译优化。所谓“按需禁用”其实就是指程序员按照自己的需求来选择是否禁用(对于并发程序,何时禁用缓存以及编译优化只有程序员知道)。所以,为了解决可见性和有序性问题,只需要提供给程序员按需禁用缓存和编译优化的方法即可: 工作内存数据一致性 - JMM主要通过一系列的数据同步协议、规则来保证数据的一致性;指令重排序优化 - Java中重排序通常是编译器或运行时环境为了优化程序性能而采取的对指令进行重新排序执行的一种手段。Java中的重排序分为两类:编译期重排序和运行期重排序,分别对应编译时和运行时环境。 同样的,指令重排序不是随意重排序,它需要满足以下两个条件: 在单线程环境下不能改变程序运行的结果。即时编译器(和处理器)需要保证程序能够遵守 as-if-serial 属性。通俗地说,就是在单线程情况下,要给程序一个顺序执行的假象。即经过重排序的执行结果要与顺序执行的结果保持一致。存在数据依赖关系的不允许重排序。多线程环境下,如果线程处理逻辑之间存在依赖关系,有可能因为指令重排序导致运行结果与预期不同。 二、JMM下的线程间通信 JMM下的线程间通信必须要经过主内存。如果线程A与线程B之间要通信的话,必须要经历下面两个步骤: 线程A把本地内存A中更新过的共享变量刷新到主内存中去;线程B到主内存中去读取线程A之前已更新过的共享变量。 关于主内存与工作内存之间的具体交互协议,即一个变量如何从主内存拷贝到工作内存、如何从工作内存同步到主内存之间的实现细节,Java内存模型定义了以下八种操作来完成。JVM 实现时必须保证下面介绍的每种操作都是原子的(对于 double 和 long 型的变量来说,load、store、read、和 write 操作在某些平台上允许有例外 )。 lock (锁定) - 作用于主内存的变量,它把一个变量标识为一条线程独占的状态;unlock (解锁) - 作用于主内存的变量,它把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定;read (读取) - 作用于主内存的变量,它把一个变量的值从主内存传输到线程的工作内存中,以便随后的 load 动作使用(从主内存 读取到工作内存中);write (写入) - 作用于主内存的变量,它把 store 操作从工作内存中得到的变量的值放入主内存的变量中(将工作内存中的值写回主内存);load (载入) - 作用于工作内存的变量,它把 read 操作从主内存中得到的变量值放入工作内存的变量副本中(给工作内存中的副本赋值);use (使用) - 作用于工作内存的变量,它把工作内存中一个变量的值传递给执行引擎,每当虚拟机遇到一个需要使用到变量的值得字节码指令时就会执行这个操作(程序执行过程中读取该值时调用);assign (赋值) - 作用于工作内存的变量,它把一个从执行引擎接收到的值赋给工作内存的变量,每当虚拟机遇到一个给变量赋值的字节码指令时执行这个操作(将运算完成后的新值赋回给工作内存中的变量,相当于修改工作内存中的变量);store (存储) - 作用于工作内存的变量,它把工作内存中一个变量的值传送到主内存中,以便随后 write 操作使用(将该值从变量中取出,写入工作内存中)。 JMM还规定了在执行上述八种基本操作时,必须满足如下规则:

图解|什么是缺页错误Page Fault

1.号外号外 各位老铁,大家好! 上周大白有事停更1次,最近在想如何让大家在10分钟中有所收获,于是准备搞一个"什么是xxx"系列,写一些精悍的知识点。 先抛一道阿里面试题给大家热热身,引出今天的主角-缺页异常Page Fault。 谈谈对缺页异常Page Fault的理解。 话不多说,集合上车。 2. 术语约定 VA:Virtual Address 虚拟地址 PA:Physical Address 物理地址 MMU:Memory Manage Unit 内存管理单元 TLB:Translation Lookaside Buffer 旁路快表缓存/地址变换高速缓存 PTE:Page Table Entry 分页表项 3. 内存的惰性分配 以32位的Linux系统为例,每个进程独立拥有4GB的虚拟地址空间,根据局部性原理没有必要也不可能为每个进程分配4GB的物理地址空间。 64位系统也是一样的道理,只不过空间寻址范围大了很多很多倍,进程的虚拟地址空间会分为几个部分: 实际上只有程序运行时用到了才去内存中寻找虚拟地址对应的页帧,找不到才可能进行分配,这就是内存的惰性(延时)分配机制。 对于一个运行中的进程来说,不是所有的虚拟地址在物理内存中都有对应的页,如图展示了部分虚拟地址存在对应物理页的情况: 虚拟地址空间根据固定大小一般是4KB进行划分,物理内存可以设置不同的页面大小,通常物理页大小和虚拟页大小是一样的,本文按照物理页4KB大小展开。 经过前面的分析,我们将面临一个问题:如何将虚拟地址准确快速地映射到物理页呢? >>>高能预警 敲黑板 本段小结<<< 1. Linux的虚拟地址空间就是空头支票,看着很大但是实际对应的物理空间只有很少的一部分。 2.内存的惰性分配是个有效的机制,可以保证内存利用率和服务器利用率,是资源合理配置的方法。 3.大量的虚拟地址到物理地址的快速准确地查询转换是一个难题。 4. CPU如果获取内存中的数据 CPU并不直接和物理内存打交道,而是把地址转换的活外包给了MMU,MMU是一种硬件电路,其速度很快,主要工作是进行内存管理,地址转换只是它承接的业务之一。 一起看看MMU是如何搞定地址转换的。 4.1 MMU和Page Table 每个进程都会有自己的页表Page Table,页表存储了进程中虚拟地址到物理地址的映射关系,所以就相当于一张地图,MMU收到CPU的虚拟地址之后开始查询页表,确定是否存在映射以及读写权限是否正常,如图: 对于4GB的虚拟地址且大小为4KB页,一级页表将有2^20个表项,页表占有连续内存并且存储空间大,多级页表可以有效降低页表的存储空间以及内存连续性要求,但是多级页表同时也带来了查询效率问题。 我们以2级页表为例,MMU要先进行两次页表查询确定物理地址,在确认了权限等问题后,MMU再将这个物理地址发送到总线,内存收到之后开始读取对应地址的数据并返回。 MMU在2级页表的情况下进行了2次检索和1次读写,那么当页表变为N级时,就变成了N次检索+1次读写。 可见,页表级数越多查询的步骤越多,对于CPU来说等待时间越长,效率越低,这个问题还需要优化才行。 >> 本段小结 敲黑板 划重点 << 1.页表存在于进程的内存之中,MMU收到虚拟地址之后查询Page Table来获取物理地址。 2.单级页表对连续内存要求高,于是引入了多级页表,但是多级页表也是一把双刃剑,在减少连续存储要求且减少存储空间的同时降低了查询效率。 4.2 MMU和TLB的故事 MMU和TLB的故事就这样开始了... CPU觉得MMU干活虽然卖力气,但是效率有点低,不太想继续外包给它了,这一下子把MMU急坏了。 MMU于是找来了一些精通统计的朋友,经过一番研究之后发现CPU用的数据经常是一小搓,但是每次MMU都还要重复之前的步骤来检索,害,就知道埋头干活了,也得讲究方式方法呀!

kafka从部署到Java springboot整合

一、部署zookeeper服务(单机) 温馨提示:部署zookeeper前请务必自己搭建并配置好java环境 服务器环境:centos7 zookeeper版本:zookeeper-3.4.6 zookeeper安装包:zookeeper-3.4.6.tar.gz 1、zookeeper下载 cd /home/root wget https://archive.apache.org/dist/zookeeper/zookeeper-3.4.6/zookeeper-3.4.6.tar.gz 2、解压、配置和启动zookeeper服务 # 解压 cd /home/root tar -xf zookeeper-3.4.6.tar.gz mv zookeeper-3.4.6 zookeeper # 进入conf目录修改zookeeper配置参数 cd /home/root/zookeeper/conf # 修改zoo_sample.cfg名为zoo.cfg # 因为zookeeper启动脚本zkServer.sh启动时会执行zkEnv.sh脚本,zkEnv.sh中会去找conf目录下的zoo.cfg文件作为配置文件加载 mv zoo_sample.cfg zoo.cfg # 修改dataDir值为/home/root/zookeeper/zookeeper/data # 添加dataLogDir=/home/root/zookeeper/zookeeper/logs vim zoo.cfg # 配置zookeeper环境变量 vim /etc/profile # 添加配置 export ZK_HOME=/home/root/zookeeper/zookeeper export PATH=.:$ZK_HOME/bin:$PATH # 环境变量生效 source /etc/profile # 启动zookeeper服务 zkServer.sh start # 查看zk状态 zkServer.sh status 3、查看zookeeper服务状态 二、部署kafka服务(单机) kafka版本:kafka_2.12-2.3.1 kafka安装包:kafka_2.12-2.3.1.tgz 1、kafka下载 cd /home/root wget https://mirrors.tuna.tsinghua.edu.cn/apache/kafka/2.3.1/kafka_2.12-2.3.1.tgz 2、解压、配置和启动kafka服务 cd /home/root/kafka/config # 修改server.

一文深入理解搞懂Java中的魔法类-Unsafe

一、Unsafe介绍 Unsafe类,全限定名是sun.misc.Unsafe,从名字中我们可以看出来这个类对普通程序员来说是“危险”的,一般应用开发者不会用到这个类。 Unsafe类位于JDK的rt.jar包中,它提供了硬件级别的原子性操作,Unsafe类中的方法都是native方法,它们使用JNI的方式访问本地C++实现库。因此Unsafe类主要提供一些用于执行低级别、不安全操作的方法,如直接访问系统内存资源、自主管理内存资源等,这些方法在提升Java运行效率、增强Java语言底层资源操作能力方面起到了很大的作用。但由于Unsafe类使Java语言拥有了类似C语言指针一样操作内存空间的能力,这无疑也增加了程序发生相关指针问题的风险。 Unsafe做操作的是直接内存区,所以该类没有办法通过HotSpot的GC进行回收,需要进行手动回收,因此在使用此类时需要注意内存泄漏(Memory Leak)和内存溢出(Out Of Memory)。 在程序中过度、不正确使用Unsafe类会使得程序出错的概率变大,使得Java这种安全的语言变得不再“安全”,因此对Unsafe的使用一定要慎重。 通过源码我们可以发现Unsafe类是"final"的,不允许继承。且构造函数是private的。 private Unsafe() { } @CallerSensitive public static Unsafe getUnsafe() { Class var0 = Reflection.getCallerClass(); if (!VM.isSystemDomainLoader(var0.getClassLoader())) { throw new SecurityException("Unsafe"); } else { return theUnsafe; } } 因为该类在sun.misc包下,默认是被BootstrapClassLoader加载的。如果我们在程序中去调用这个类的话,我们使用的类加载器肯定是AppClassLoader。同时我们可以发现在代码里面Unsafe限制了它的 ClassLoader,如果这个方法的调用实例不是由BootClassLoader加载的,则会报SecurityException错误。 那如若想使用这个类,该如何获取其实例?有如下两个可行方案。 从getUnsafe方法的使用限制条件出发,通过Java命令行命令-Xbootclasspath/a把调用Unsafe相关方法的类A所在jar包路径追加到默认的bootstrap路径中,使得A被引导类加载器加载,从而通过Unsafe.getUnsafe方法安全的获取Unsafe实例。 java -Xbootclasspath/a: ${path} // 其中path为调用Unsafe相关方法的类所在jar包路径 通过反射获取单例对象theUnsafe。 Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe"); theUnsafeField.setAccessible(true); Unsafe unsafe = (Unsafe) theUnsafeField.get(null); System.out.println(unsafe); 二、Unsafe类重要方法 Unsafe类功能介绍: 1、内存操作 下面是堆外内存的分配、拷贝、释放、给定地址值操作等方法 //分配内存, 相当于C++的malloc函数 public native long allocateMemory(long bytes); //扩充内存 public native long reallocateMemory(long address, long bytes); //释放内存 public native void freeMemory(long address); //在给定的内存块中设置值 public native void setMemory(Object o, long offset, long bytes, byte value); //内存拷贝 public native void copyMemory(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes); //获取给定地址值,忽略修饰限定符的访问限制。与此类似操作还有: getInt,getDouble,getLong,getChar等 public native Object getObject(Object o, long offset); //为给定地址设置值,忽略修饰限定符的访问限制,与此类似操作还有: putInt,putDouble,putLong,putChar等 public native void putObject(Object o, long offset, Object x); //获取给定地址的byte类型的值(当且仅当该内存地址为allocateMemory分配时,此方法结果为确定的) public native byte getByte(long address); //为给定地址设置byte类型的值(当且仅当该内存地址为allocateMemory分配时,此方法结果才是确定的) public native void putByte(long address, byte x); 通常,我们在Java中创建的对象都处于堆内内存(heap)中,堆内内存是由JVM所管控的Java进程内存,并且它们遵循JVM的内存管理机制,JVM会采用垃圾回收机制统一管理堆内存。与之相对的是堆外内存,存在于JVM管控之外的内存区域,Java中对堆外内存的操作,依赖于Unsafe提供的操作堆外内存的native方法。

某银行 科技岗位 数据工程师 面试题总结

1.python中 list和数组的区别 平时只是用很少总结积累他们的区别,这下被问蒙了,今天总结如下: python 中的数组: 1)数组一般是固定长度,不可中途修改 2)数组的各个数据项数据类型必须相同 3)两数组不可直接“链接”构成新的更大数组 python 中的列表: 1)可修改,list数据结构内容可以被程序修改 2)可动态增减,长度不固定 3)list里面的数据项可以是不同类型数据,也可以是list 4)两个list可“链接”(通过+加法)构成一个更大的list 2.归并排序 未完待续

利用numpy中的方法delete删除数组的整行和整列

1.首先要导入第三方库 numpy import numpy as np 2.利用delete()删除数组整行和整列的通用格式 np.delete(arr, obj, axis=None) 2.1.参数: arr: 输入数组 obj: 切片,整数,表示哪个子数组要被移除 axis: 删除子数组的轴 axis = 0: 表示删除数组的行 axis = 1: 表示删除数组的列 axis = None:表示把数组按一维数组平铺在进行索引删除 2.2.返回值:一个新的子数组 3.具体实现历程 删除单行操作: arr=np. array([[1,2,3],[4,5,6],[7,8,9]]) print arr arr=np. delete(arr,2, axis=0) print arr 删除多行操作: arr=np. array([[1,2,3],[4,5,6],[7,8,9]]) print arr arr=np. delete(arr,[1,2], axis=0) print arr 删除单列操作: arr=np. array([[1,2,3],[4,5,6],[7,8,9]]) print arr arr=np. delete(arr,1, axis=1) print arr 删除多列操作: arr=np. array([[1,2,3],[4,5,6],[7,8,9]]) print arr arr=np. delete(arr,[1,2], axis=1) print arr

钉钉机器人告警快速实现

1.建立钉钉群 2.群助手里添加自定义机器人。 3.安全方式里面勾选加签。 4.记录添加机器人时生成的密钥,已经机器人的地址。 5.zabbix里面建立报警媒介 6.创建动作 7.用户里面添加报警媒介 8.上传脚本到/usr/lib/zabbix/alertscripts/ 编译或者其他安装的 搜索一下alertscripts目录。 9.脚本地址:https://github.com/follow2015/wechat__dingding_alert

WWDC 2020 特别活动主题演讲 全套源文件下载 视频、幻灯片图片、中英文全稿 WWDC 2020 Special Event Keynote

文章目录 中文全稿英文全稿超高清幻灯片图片高清无字幕视频 这一届的WWDC还是有比较多的更新点,本来想到官网下载keynote的原文件看一下,发现在没有提供。于是就下载了官方视频,整理了一套包括原版高清视频、超高清幻灯片图片、中英文全稿资料。 已将无字幕的原版视频和自制的幻灯片图片、中英文全稿上传共享,希望能帮到和我一样需要的童鞋。 中文全稿 点击链接下载 全文约三万字 英文全稿 点击链接下载 超高清幻灯片图片 点击链接下载 共260P 高清无字幕视频 点击链接下载 1.2G大小

【opencv】图片放大缩小到指定大小或按指定比例f放大缩小(resize函数)c++

简介 本文实验是在Ubuntu下基于opencv3.4.6的resize()函数进行图片的大小变换的,主要有两种方式,一种是指定的变换后的图像大小,一种是给出图像放大缩小的比例,lena原图大小为 【512x512】 分别变换为【456x123】,和【512*0.5,512*3】,结果: 【此为原图】 【结果图比较畸形,就不做显示了--】 C++实现代码 之前项目比较急的时候,在设定图像变换大小的时候,总是将Size(x,y)漏写成(x,y),一直报错,以及不理解Size(空)的意义,通过输出,发现Size(空)等效与Size类构造一个Size(0,0)。(注意Size第一个S是大写) #include <opencv2/opencv.hpp> using namespace cv; using namespace std; int main() { Mat src =imread("lena.jpg"); Mat dst_resize; /* void cv::resize ( InputArray src, OutputArray dst, Size dsize, double fx = 0, double fy = 0, int interpolation = INTER_LINEAR dsize 表示输出图片的大小,当为Size(无参数)时,计算方法如下: 𝚍𝚜𝚒𝚣𝚎 = 𝚂𝚒𝚣𝚎(𝚛𝚘𝚞𝚗𝚍(𝚏𝚡*𝚜𝚛𝚌.𝚌𝚘𝚕𝚜), 𝚛𝚘𝚞𝚗𝚍(𝚏𝚢*𝚜𝚛𝚌.𝚛𝚘𝚠𝚜)) ) */ cout<<"src.size: "<<src.size<<endl; //方法一,给出指定的大小,以默认的双线性插值方式 INTER_LINEAR( bilinear interpolation ) // resize(src,dst_resize,Size(123,456)); //最简方式 resize(src,dst_resize,Size(123,456),0,0,INTER_LINEAR); //完整方式加其他插值 cout<<"Size(123,456): "<<Size(123,456)<<endl; cout<<"dst_resize.size: "

linux中的SGI(核间中断)IPI_RESCHEDULE详解

1、SGI中断(核间通信中断) 在gicv2/gicv3中,SGI中断(中断号0-15)是software generate interrupt,用户核间中断。 我们一般将0-7划分给linux中使用,8-15给TEE使用。在smp.c定义了linux中使用的SGI中断。 kernel/arch/arm/kernel/smp.c enum ipi_msg_type { IPI_WAKEUP, IPI_TIMER, IPI_RESCHEDULE, IPI_CALL_FUNC, IPI_CPU_STOP, IPI_IRQ_WORK, IPI_COMPLETION, /* * CPU_BACKTRACE is special and not included in NR_IPI * or tracable with trace_ipi_* / IPI_CPU_BACKTRACE, #ifdef CONFIG_TRUSTY IPI_CUSTOM_FIRST, IPI_CUSTOM_LAST = 15, #endif / * SGI8-15 can be reserved by secure firmware, and thus may * not be usable by the kernel. Please keep the above limited * to at most 8 entries.

类图、时序图、用例图简单介绍

文章目录 规范类图:时序图用例图总结 规范 UML规范用来描述建模的概念有,类、对象、关联、职责、行为、接口、用例、包、顺序、协作,以及状态。 类图: 概念: 类图(Class diagram)主要用于描述系统的结构化设计。类图也是最常用的UML图,用类图可以显示出类、接口以及它们之间的静态结构和关系。 符号: 虚线箭头:依赖:使用的关系,比如局部变量,方法的参数或者对静态方法的调用。 实线箭头:关联 虚线三角:接口 实线三角:父类 空心菱形:聚合:整体与部分的关系,部分离开整体仍然可以存在。 实心菱形:组合:整体与部分的关系,部分不能离开整体存在。 ps:聚合关系是关联关系的一种,关联和聚合在语法上无法区分。 时序图 概念: 描述了对象之间传递消息的时间顺序,它用来表示用例的行为顺序。 作用: 用对象间的交互来描述用例; 寻找类的操作 符号: 实线箭头:简单消息 实线三角:同步消息:消息的发送者把进程控制传递给消息的接收者,然后暂停活动,等待消息接收者的回应消息。 虚线箭头:返回消息:消息的发送者将消息发送给消息的接受者后,不用等待回应的消息,即可开始另一个活动。 (实线半箭头:异步消息) 长矩框:对象激活 高度表示对象执行一个操作所经历的时间段,顶部表示动作的开始,底部表示动作的结束。 图示例: 用例图 概念: 用例图是指由参与者(Actor)、用例(Use Case),边界以及它们之间的关系构成的用于描述系统功能的视图。 关系: 关联、泛化、包含、扩展 符号: 实线:关联 实线空三角:泛化(继承?) 虚线箭头:包含、拓展 虚线空三角:依赖(后来添加的) 图示例: 总结 参考链接: https://www.cnblogs.com/pangjianxin/p/7877868.html. 今天就到这里了如果有什么不对的地方欢迎大家在评论区留言交流改进!!