Lambda表达式有这么重要的两点 Lambda表达式是一个很小且能被当作数据进行传递的函数。 集合对象在内部的遍历方式,这种遍历不同于当前已有的外部顺序化遍历。 1. 内部循环和外部循环的区别 先举个例子 List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6); for (int number : numbers) { System.out.println(number); } 这就是外部循环的写法,这样写有什么缺点呢,有这么几个: 只能顺序处理List中的元素(process one by one) 不能充分利用多核CPU 不利于编译器优化 而如果用内部循环,写成这样: List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6); numbers.forEach((Integer value) -> System.out.println(value)); 这种内部循环的写法,能带来这么几个好处: 不一定需要顺序处理List中的元素,顺序可以不....
昨天刚刚面完京东,乘着还记得一些细节,先写下了。 ####1. 前奏 和京东是这么联系上的:我在boss直聘上有简历,然后京东商城的一个研发经理找我要不要来面试一下。我那时候还在深圳,就说了还在深圳呢,最近还不找工作,就说后面找工作就找他。后来我找工作的时候主动联系了他。那时候是晚上刚吃完饭,我手机上聊了一下,说自己要找工作了,啥时候能聊一下,结果他反应很快。。。马上让人打电话给我先来个电话面。我那时候刚吃完饭,状态不好,算了,硬着头皮面吧!。 ####2. 电话面 不一会儿,有面试官打电话给我了。气氛比较轻松,面试官有说有笑,说这么晚面试,可能不太好,没关系,我们简单聊一下,面试官先开起了玩笑,后来就了解了一下我的基本情况。 面试正式开始了。先问我,从我在浏览器输入一个域名开始,到显示页面,中间发生了什么。。这种题我经常看到,以为面试官不会问这种题,结果还真问。我就按自己的理解说了一下。这种题答得不好。我没有专门去准备,如果这种题要答完美,还是要做很多功课的。 再就是问sql注入问题。我们项目中怎么预防的。先让我解释一下sql注入问题。再就是问数据库索引的东西,让我解释一下索引是怎么....
####1. 准备 欢聚时代是我开始认真面试的第一家公司。我让我一个朋友内推的。投递的是me直播Java开发工程师的职位。反馈也比较快,投了之后两天就有结果了。然后就约了一个时间去面试。yy搬到了番禺广场,不得不说,真的有点远并且有点偏哎。好处就是周围租房的选择比较多。yy在番禺广场买下来了一整栋楼,大概40多层,一个很大的www.yy.com logo,还是很有气势的。 我的面试安排在下午三点开始,去了之后先要在前台登记,让我拿出面试邀请邮件,可是发我谷歌邮箱了,手机上没翻墙打不开。。尴尬,最后打电话确认后才让我上去。我的面试在33楼进行,等了大概20分钟,终于等来了第一位面试官。 ####2. 一面 一面的面试官是个中年男子,看上去也很沉稳干练的那种。一开始让我介绍自己做过的项目,没有自我介绍环节了。我就讲了我做过的一个项目。我说的是我们做的一个公众号估值系统的项目,这个项目主要是如何去获取一个公众号所有的文章数,每篇文章的阅读数和点赞数。我们是通过fiddler进行抓包分析,伪造http请求的方式来实现。这个做起来挺有难度的。key失效一直是一个很头疼的大问题。我讲了大概十五分钟....
B树是为了磁盘或其他直接存取的辅助存储设备而设计的一种平衡搜索树。B树类似于红黑树,但是在降低磁盘IO操作数方面要更好一些。B树与红黑树的不同之处在于B树的结点可以有很多孩子。从几个到几千个都可以。和红黑树一样,有n个结点的B树的高度为O(lgn),然而一个b树的严格高度可能比一颗红黑树要小许多。这就是因为他的分支因子。表示高度的对数的底数可以非常大。 在了解B树之前先必须要弄明白磁盘存储的数据结构和随机访问的主存数据结构的不同。 ##1. 磁盘存储数据结构 一个典型的磁盘驱动器,它包括了n个绕主轴旋转的盘片,每个盘片通过磁臂末端的磁头来读写。这些磁臂围绕着一个共同的旋转轴旋转。当读写磁头静止时,它下方经过的磁盘表面就是一个磁道。磁盘的机械运动相比主存来说是非常慢的。目前磁盘的旋转速度在5400-15000转/分钟。服务器级别(15kRPM),台式机(7200RPM),笔记本(5400RPM)。对台式机来说,旋转一周需要8.33ms。每次读出多个页面。 在一个典型的B树应用中,所要处理的数据量非常大,所有数据无法一次装入内存中。b树算法通常只会在主存中保留一定数量的页面。对我们来说,一....
我觉得最重要的一点是,redis作为一个内存数据库,内存操作是很快的。网络io是瓶颈,如果用多线程,还要引起线程切换,线程切换的开销是很大的,切换线程之后要保留现场,要做很多预处理。所以用单线程反而能起到更好的作用。 线程切换为什么开销大呢?举个简单的例子,我在看一篇文章,有个单词不认识,那我要去查词典。在查词典之前,我得要先记录我阅读到了那一页的哪一行,方便下次来继续读。那这样肯定是要影响我读书效率的。 我总结几点redis为什么要设计成单线程的原因 都是通过网络来调用redis的,如果是内网调用情况稍微比外网调用好点。但是这些和内存操作的时间不是一个量级的。用单线程处理完全能应付。 redis是采用单线程-多路复用IO模型来实现高性能内存数据服务的。这样就避免了适用锁。网络层利用IO多路复用,这使用了内核级别的线程池,就是说还是存在并发的,只是在网络层的并发。但是网络Io本身是很慢的。是瓶颈。那么你在业务处理阶段设计再多的线程,使用再多的cpu内核,也没法逾越网络Io的瓶颈。 redis和传统的多线程服务器不同。比如tomcat这些,后端往往存在很重的IO操作,会产生长时间的等待....
内容来自网络,非本人原创。 查看原文 一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似。一致性哈希修正了CARP使用的简 单哈希算法带来的问题,使得分布式哈希(DHT)可以在P2P环境中真正得到应用。 ##1. 判断哈希算法好坏的标准 一致性hash算法提出了在动态变化的Cache环境中,判定哈希算法好坏的四个定义: 平衡性(Balance): 尽可能分布到所有缓冲中 单调性(Monotonicity): 已经分配好的缓冲,哈希值尽可能少的变动 分散性(Spread): 在分布式环境中,终端有可能看不到所有的缓冲,而是只能看到其中的一部分。当终端希望通过哈希过程将内容映射到缓冲上时,由于不同终端所见的缓冲范围有可能不同,从而导致哈希的结果不一致,最终的结果是相同的内容被不同的终端映射到不同的缓冲区中。这种情况显然是应该避免的,因为它导致相同内容被存储到不同缓冲中去,降低了系统存储的效率。分散性的定义就是上述情况发生的严重程度。好的哈希算法应能够尽量避免不一致的情况发生,也就....
我最近的很多工作围绕着微信公众号的开发进行的。对微信公众号开发的很多细节都比较清楚。扫码登录也基本是首选的登录方式。这里我就记录一下我们的微信扫码登录时怎么实现的。 我们是用websocket来实现的。大体思路就是 前端请求登录二维码的时候传token参数,后端保存token到数据库 手机扫码。后台判断扫码事件的参数是否合法,然后通过websocket把验证结果发送给客户端 客户端如果收到成功消息。则向服务端发送一条登录成功的确认消息。 服务端收到之后,进行用户登录状态的处理,session的保存,把处理结果返回给客户端 客户端再次收到成功标志之后,做登录跳转。标志着登录成功。 所有异常结果都由前端提示操作失败。 ##1. 进入登录页面,前端向后台请求二维码 在扫码登录页面,前端向后台发个Ajax请求,请求扫描登录二维码。这里需要一个传一个请求参数token,因为后面要用它进行验证。 token可用时间戳+随机数获取 var token = '' + new Date().getTime() + '_' + Math.floor(Math.random() * 1000); 后台接收....
JVM 1. 类加载的过程 加载->连接(验证->准备->解析)->初始化->使用->卸载 加载 1、通过一个类的全限定名来获取其定义的二进制字节流。 2、将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。 3、在Java堆中生成一个代表这个类的java.lang.Class对象,作为对方法区中这些数据的访问入口。 注意 : 虚拟机规范之中并没有规定要从哪里加载二进制字节流.所以就有开发人员玩出了很多有创造力的花样.比如从jar包,war包中加载.网络中获取,applet就是例子.运行时动态计算生成,用的是动态代理技术.由其他文件生成.典型的就是jsp应用. 验证 验证的目的是为了确保Class文件中的字节流包含的信息符合当前虚拟机的要求,而且不会危害虚拟机自身的安全。不同的虚拟机对类验证的实现可能会有所不同,但大致都会完成以下四个阶段的验证:文件格式的验证、元数据的验证、字节码验证和符号引用验证。 准备 准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些内存都将在方法区中分配。对于该阶段有以下几点需要注意: 1、这时候进行内....
Java并发多线程学习笔记 标签(): java 多线程 并发编程 艺术 原子操作的实现原理 #1、术语 比较并交换 compare and swap(一个新值和旧值,比较旧值有没有发生变化,如果没有发生变化则交换成新值) CPU流水线 CPU pipeline -- 内存顺序冲突 Memory order violation -- 一般由假共享内存引起,出现冲突时,cpu流水线必须清空 #2、处理器如何实现原子操作 32位IA-32处理器使用缓存加锁或总线加锁的方式来处理多处理器之间的原子操作 一般情况下处理器会自动保证基本内存操作的原子性,但是复杂的内存操作则并不能自动保证原子性。比如跨总线宽度,跨多个缓存行和跨页表的访问。 处理器提供总线锁定和缓存锁定两个机制来保证复杂内存操作的原子性。 ##1.总线锁 总线锁就是使用处理器提供的一个LOCK#信号,当一个处理器在总线上输出此信号时,其他处理器的请求将被阻塞,那该处理器可以独占共享内存。 ##2.缓存锁 频繁使用的内存会缓存在处理器的L1,L2,L3高速缓存里 缓存锁定是指内存区域如果被缓存在处理器的缓存行中,并且在lock操作期....
http请求都分为请求(响应)行,请求(响应)头(header),body三部分。 1. http首部 1.1 Host: 客户端通过host首部为服务器提供客户端想要访问的那台服务器的ip地址。告诉服务器我要访问哪台主机。 1.2 Expires 响应失效的日期和时间 1.3 Etag 为报文中的实体提供了实体标记。 1.4 Cache-Control 控制缓存的行为(no cache) 1.6 Upgrade 升级为其他协议(websocket的时候这个字段为websocket) 1.7 User-Agent HTTP 客户端设备信息。 1.8 Referer 意义 告诉服务器我是从哪个页面链接过来的,服务器籍此可以获得一些信息用于处理。比如从我主页上链接到一个朋友那里,他的服务器就能够从HTTP Referer中统计出每天有多少用户点击我主页上的链接访问他的网站。 作用 Referer可以记录访问的来源,统计访问量,可以用来防盗链。 客户端用js不能篡改Referer,用一些插件什么的可以达到伪造的目的。 可以使用Fiddler修改Referer。 利用Referer防止图片盗链....
##1. 理解OAuth2.0 首先我们通过一张图片来了解一下OAuth2.0的运作模式: 从上图我们可以看到,整个过程进行了2次“握手”,最终利用授权的AccessToken进行一系列的请求,相关的过程说明如下: A:由客户端向服务器发出验证请求,请求中一般会携带这些参数 ID标识,例如appId 验证后跳转到的URL(redirectUrl) 状态参数(可选) 授权作用域scope(可选) 响应类型(可选) B:服务器返回一个grant授权标识(微信默认情况下称之为code),类似于一个一次性的临时字符串密钥。如果在A中提供了redirectUrl,这里服务器会做一次跳转,带上grant和状态参数,访问redirectUrl。 C:客户端的redirectUrl对应页面,凭借grant再次发起请求,这次请求通常会携带一些敏感信息: ID标识 密码 grant字符串(code) grant类型(可选,微信中默认为code) D:服务器验证ID标识、密码、grant都正确之后,返回AccessToken(注意,这里的AccessToken和之前通用接口、高级接口介绍的AccessTok....
##1. 什么是sql注入 SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过让原SQL改变了语义,达到欺骗服务器执行恶意的SQL命令。其主要原因是程序没有细致地过滤用户输入的数据,致使非法数据侵入系统。 ##2. SQL注入实例 很多Web开发者没有意识到SQL查询是可以被篡改的,从而把SQL查询当作可信任的命令。殊不知,SQL查询是可以绕开访问控制,从而绕过身份验证和权限检查的。更有甚者,有可能通过SQL查询去运行主机系统级的命令。 下面将通过一些真实的例子来详细讲解SQL注入的方式。 考虑以下简单的登录表单: <form action="/login" method="POST"> <p>Username: <input type="text" name="username" /></p> <p>Password: <input type="password" name="password" /></p> <p><inp....
申明: 本文是从国外技术网站上看到的。觉得比较好久摘录下来了。仅做学习之用。 点击此处查看原文链接,需要翻墙 Recently at iHeartRadio we decided to migrate our one monolithic Java backend service into multiple microservices, more specifically we decided to implement these microservices as Akka apps and use Akka cluster to weave them into our microservice cluster. This post is about how we reached this decision. There are three main sections in this post: first a brief discussion of the goals we wanted to achieve with microservices, second, the speci....
数据库学习笔记 标签(空格分隔): 数据库 数据库 1. 数据库优化的一些手段 尽量避免null类型的列 使得索引、索引统计、值比较都比较复杂、使用更多的存储空间、null的列为索引时,每个索引记录需要额外一个字节、 datetime timestamp timestamp只使用datetime一半的存储空间。并且会根据时区变化。 整数类型 tinyint、smallint、mediumint、int、bigint分别使用8/16/24、32/64位存储空间 unsigned属性表示不允许负值 字符串类型 varchar char的区别 varchar存储可变长的字符串、需要用额外1、2一个字节记录字符串长度信息、适合最大长度比平均长度大很多。。列的更新很少,碎片不是问题 char是定长的,适合经常变更的数据、因为不容易产生碎片。也适合非常短的列、比如char(1)存储y和n的值,char只需要一个字节,而varchar需要两个字节,额外一个字节存储长度信息 2. 索引知识 分为btree索引和哈希索引 数据库索引的实现 为表设置索引要付出代价的:一是增加了数据库的存储空间,二是在插入....