AI:人工智能
未读Zookeeper 是 Google 的 Chubby 一个开源的实现,是 Hadoop 的分布式协调服务 自 2010 年 10 月升级成 Apache Software Foundation(ASF) 顶级项目 分布式协调服务, 提供以下功能: 组管理服务 分布式配置服务 分布式同步服务 分布式命名服务 谁在使用 Zookeeper开源软件 HBase 开源的非关系型分布式数据库 Solr Apache Lucene 项目的开源企业搜索平台 Storm 分布式计算框架 Neo4j 高性能的,Nosql 图形数据库 … 公司 Yahoo LinkedIn Twitter Taobao … Zookeeper 架构 客户端随机连接集群中的任何一台 server 集群内所有的 server 基于 Zab(ZooKeeper Atomic Broadcast) 协议通信 集群内部根据算法自动选举出 leader, 负责向 follower 广播所有变化消息 集群中每个 follower 都和 leader 通信 follower 接收来自 leader 的所有变化 ...
Python 面向对象基础部分 中秋在家没事, 写了一个很久以前就想写的脚本 如果下午 6 点 10 分还连接着公司的 wifi, 就发邮件给老婆说要加班 为什么要发邮件而不发短信呢, 因为短信接口要钱….最近买了个 4k 的显示器, 拿来外接 mac 看代码, 爽翻了, 不过有点蛮烦的就是每次都要拖动鼠标到另一个屏幕上去, 不过全国最大的同性交友网站 GitHub上面有一款开源的软件叫 CatchMouse 解决了这个问题 下载地址: CatchMouse 另一个问题是如果想把软件从 mac 屏幕放到外接显示屏的话, 还是要拖过去, 但是….另一款神器 Moon 能帮我们快速的把当前应用移动到外接显示器上, 光标定位到需要移动的 app 上, 快捷键 contro+` 即可 接下来是脚本 我的思路是: 先检测当前连接的是哪里的 wifi如果是公司的 wifi, 且当前时间大于 6 点 10 分, 则给老婆发送邮件如果连接的是家里的 wifi, 则检测是否连接了外接显示器,如果连接了, 则检测是否开启了 CatchMouse.app, 没有则打开. 接下来开始撸代 ...
ERROR: Permission to ArrayDsj/git-test.git denied to dong4j.fatal: Could not read from remote repository. Please make sure you have the correct access rightsand the repository exists. 目前有 2 个 github 账号, 一个公司的 gitlab 账号 有一次遇到了 1ERROR: Permission to XXX.git denied to user 错误, 整理了一下,这里做一个记录 错误前提很久以前使用 ssh-keygen 生成一对默认名称的公私匙, 直接导入 github 中就能使用, 这是只在一个用户的情况下, 后台又申请了一个 github 账号, 还是使用 id_rsa.pub 这个默认的公匙, 这就造成了上面的错误. 解决方法为不同的账号生成不同的公私匙 1. 生成密匙对 1234567891011# 生成密匙对 名称为 user1-github-ssh-k ...
当程序使用某个类时, 如果该类还没被初始化, 加载到内存中, 则系统会通过加载、连接、初始化三个过程来对该类进行初始化. 该过程就被称为类的初始化 类加载指将类的 class 文件读入内存, 并为之创建一个 java.lang.Class 的对象 类文件来源 从本地文件系统加载的 class 文件 从 JAR 包加载 class 文件 从网络加载 class 文件 把一个 Java 源文件动态编译, 并执行加载 类加载器通常无须等到“首次使用”该类时才加载该类, JVM 允许系统预先加载某些类 类加载器类加载器就是负责加载所有的类, 将其载入内存中, 生成一个 java.lang.Class 实例. 一旦一个类被加载到 JVM 中之后, 就不会再次载入了. 根类加载器(Bootstrap ClassLoader): 其负责加载 Java 的核心类, 比如 String、System 这些类 拓展类加载器(Extension ClassLoader): 其负责加载 JRE 的拓展类库 系统类加载器(System ClassLoader): 其负责加载 CLA ...
介绍 Java 内存模型 3 大核心 原子性 可见性 顺序性 原文出处 https://segmentfault.com/a/1190000000435392 并发编程模型的分类在并发编程中,我们需要处理两个关键问题:线程之间如何通信及线程之间如何同步(这里的线程是指并发执行的活动实体)。通信是指线程之间以何种机制来交换信息。在命令式编程中,线程之间的通信机制有两种:共享内存和消息传递。 在共享内存的并发模型里,线程之间共享程序的公共状态,线程之间通过写 - 读内存中的公共状态来隐式进行通信。在消息传递的并发模型里,线程之间没有公共状态,线程之间必须通过明确的发送消息来显式进行通信。 同步是指程序用于控制不同线程之间操作发生相对顺序的机制。在共享内存并发模型里,同步是显式进行的。程序员必须显式指定某个方法或某段代码需要在线程之间互斥执行。在消息传递的并发模型里,由于消息的发送必须在消息的接收之前,因此同步是隐式进行的。 Java 的并发采用的是共享内存模型,Java 线程之间的通信总是隐式进行,整个通信过程对程序员完全透明。如果编写多线程程序的 Java程序员不理解隐式 ...
“异步调用”对应的是“同步调用”,同步调用指程序按照定义顺序依次执行,每一行程序都必须等待上一行程序执行完成之后才能执行;异步调用指程序在顺序执行时,不等待异步调用的语句返回结果就执行后面的程序。 同步调用下面通过一个简单示例来直观的理解什么是同步调用: 定义 Task 类,创建三个处理函数分别模拟三个执行任务的操作,操作消耗时间随机取(10 秒内) 123456789101112131415161718192021222324252627@Componentpublic class Task { public static Random random =new Random(); public void doTaskOne() throws Exception { System.out.println("开始做任务一"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); ...
我们在工作中有时候可能会遇到这样场景,需要在退出容器的时候执行某些操作。SpringBoot 中有两种方法可以供我们来选择(其实就是 spring 中我们常用的方式。只是 destory-method 是在 XML 中配置的,SpringBoot 是去配置化。所以这里就不提这种方式了),一种是实现 DisposableBean 接口,一种是使用@PreDestroy 注解。OK,下面我写两个例子看一下: DisposableBean 接口我们可以通过实现这个接口来在容器退出的时候执行某些操作。例子如下: 123456789101112131415161718@Componentpublic class TestImplDisposableBean implements DisposableBean, ExitCodeGenerator { @Override public void destroy() throws Exception { System.out.println("<<<<<&l ...
在大部分时候,我们讨论 API 的设计时,会从功能的角度出发定义出完善的,易用的 API。而很多时候,非功能需求如安全需求则会在很晚才加入考虑。而往往这部分会涉及很多额外的工作量,比如与外部的 SSO 集成,Token 机制等等。 这篇文章会以一个简单的例子,从应用程序和部署架构上分别讨论几种常见的模型。这篇文章是这个系列的第一篇,会讨论两个简单的主题: 基于 Session 的用户认证 基于 Token 的 RESTful API(使用 Spring Security) 使用 Session由于 HTTP 协议本身是无状态的,服务器需要某种机制来区分每个请求。比如在返回给客户的响应中加入一些 ID,客户端再次请求时带上这个 ID,这样服务器就可以区分出来每个请求,并完成事务性的操作(完成订单的创建,更新,商品派送等等)。 在多数 Web 容器中,这种机制通过 Session 来实现。Web 容器会为每个首次请求创建一个 Session,并将 Session 的 ID 以浏览器 Cookie 的方式返回给客户端。客户端(常常是浏览器)在后续的请求中带上这个 Session ...
写 Java 程序时会经常从 classpath 下读取文件, 是时候该整理一下了, 并在不断深入的过程中, 陆续补充上. 现在 Java project 都以 maven 项目居多, 比如像下面这样的一个项目结构: 编译后的 class 文件都到了 target 目录, 如下面的结构: 看代码: 123456789101112131415161718192021222324import java.io.File;import java.net.URL;public class Poem { public static void main(String[] args) { Poem poem = new Poem(); poem.getFile("extObj.txt"); } private void getFile(String fileName) { ClassLoader classLoader = getClass().getClassLoa ...
有时候,系统需要处理非常多的执行时间很短的请求,如果每一个请求都开启一个新线程的话,系统就要不断的进行线程的创建和销毁,有时花在创建和销毁线程上的时间会比线程真正执行的时间还长。而且当线程数量太多时,系统不一定能受得了。 使用线程池主要为了解决一下几个问题: 通过重用线程池中的线程,来减少每个线程创建和销毁的性能开销。 对线程进行一些维护和管理,比如定时开始,周期执行,并发数控制等等。 ExecutorExecutor 是一个接口,跟线程池有关的基本都要跟他打交道。下面是常用的 ThreadPoolExecutor 的关系。 Executor 接口很简单,只有一个 execute 方法。 ExecutorService 是 Executor 的子接口,增加了一些常用的对线程的控制方法,之后使用线程池主要也是使用这些方法。 AbstractExecutorService 是一个抽象类。ThreadPoolExecutor 就是实现了这个类。 ThreadPoolExecutor构造方法ThreadPoolExecutor 是线程池的真正实现,他通过构造方法的一系列参数,来构 ...
总结线程池的使用方式 Java 通过 Executors 提供四种线程池, 分别为: newCachedThreadPool 创建一个可缓存线程池, 如果线程池长度超过处理需要, 可灵活回收空闲线程, 若无可回收, 则新建线程. newFixedThreadPool 创建一个定长线程池, 可控制线程最大并发数, 超出的线程会在队列中等待. newScheduledThreadPool 创建一个定长线程池, 支持定时及周期性任务执行. newSingleThreadExecutor 创建一个单线程化的线程池, 它只会用唯一的工作线程来执行任务, 保证所有任务按照指定顺序 (FIFO, LIFO, 优先级) 执行. 线程池比较单线程的优势在于: 重用存在的线程, 减少对象创建、消亡的开销, 性能佳. 可有效控制最大并发线程数, 提高系统资源的使用率, 同时避免过多资源竞争, 避免堵塞. 提供定时执行、定期执行、单线程、并发数控制等功能. newCachedThreadPool 12345678910111213141516public static void main( ...
在 Java 中, GC 的对象是堆空间和永久区 引用计数算法 Java 不再使用 Python,COM,ActionScript3 使用 性能差 不能解决循环引用问题 标记 - 清除算法标记阶段在标记阶段,首先通过根节点,标记所有从根节点开始的可达对象 清除阶段清除所有未被标记的对象 标记 - 压缩算法 标记 - 压缩算法适合用于存活对象较多的场合,如老年代.它在标记 - 清除算法的基础上做了一些优化. 标记阶段从根节点开始,对所有可达对象做一次标记 压缩阶段将所有存活对象压缩到内存一端, 然后清除边界外的所有空间 复制算法 与标记 - 清除算法相比, 复制算法是一种相对高效的回收方式 不适合存活对象较多的场合, 如老年代 将原来的内存分为相同大小的两块, 每次只是用其中一块, 在垃圾回收时, 将正在是用的内存中的对象复制到未使用的内存块中, 之后清除正在是用的内存中的所有对象,交换两个内存的角色, 完成垃圾回收 问题: 空间浪费, 只是用了一半 是用标记清理和复制算法配置回收垃圾 在最上面那块大的区域产生新对象。 大对象不太适合在复制空间,因为复制空间的 ...
volatile 关键字的 2 个语义 内存可见性 阻止重排序 volatile 不能保证原子性 volatile 关键字的 2 层含义: 用 volatile 修饰的变量, 线程在每次使用变量的时候, 都会读取变量修改后的最新的值.作为指令关键字, 确保本条指令不会因编译器的优化而省略, 且要求每次直接读值. 可见性可见性是指 当一个线程修改了一个共享变量, 其他线程能够立刻得知这个修改.这里有必要了解一下 Java 的内存模型 被 volatile 修饰的变量, 当线程需要使用这个变量时, 回去主内存中读取, 然后加载到自己的工作线程中,工作线程中的变量只是主存变量的一个拷贝, 当使用完这个变量后, 会刷新会主存中. 当数据中主内存复制到工作内存存储时, 必须出现两个动作: 由主内存执行的 read 操作 有工作内存执行相应的 load 操作 当数据从工作内存拷贝到主内存时, 也会有两个操作: 用工作内存执行的 store 操作 用主内存执行相应的 write 操作 volatile 的特殊规则就是 read、load、use 必须连续出现. assig ...
生产者消费者问题是研究多线程程序时绕不开的经典问题之一, 它描述是有一块缓冲区作为仓库, 生产者可以将产品放入仓库, 消费者则可以从仓库中取走产品 生产者消费者问题生产者消费者问题是研究多线程程序时绕不开的经典问题之一, 它描述是有一块缓冲区作为仓库, 生产者可以将产品放入仓库, 消费者则可以从仓库中取走产品.解决生产者 / 消费者问题的方法可分为两类: 采用某种机制保护生产者和消费者之间的同步; 在生产者和消费者之间建立一个管道. 第一种方式有较高的效率, 并且易于实现, 代码的可控制性较好, 属于常用的模式. 第二种管道缓冲区不易控制, 被传输数据对象不易于封装等, 实用性不强. 同步问题核心在于:如何保证同一资源被多个线程并发访问时的完整性.常用的同步方法是采用信号或加锁机制, 保证资源在任意时刻至多被一个线程访问.Java 语言在多线程编程上实现了完全对象化, 提供了对同步机制的良好支持.在 Java 中一共有五种方法支持同步, 其中前四个是同步方法, 一个是管道方法. wait()/ notify() 方法 await()/ s ...