死磕java并发
❶ 自学web和自学java哪一个更难一点
以web方向为基础的java学习路线:
(由于java真正的知识范围很广,这里只罗列出我个人觉得重要的,至少是web中用的上的东西。)
一.J2SE阶段
·java基础【变量、运算符、标识符等】
·面向对象【封装、继承、多态】;
·API;
·集合框架【List、Map】;
·泛型;
·IO流;
·多线程;
·JDBC;
·正则表达式;
·高级特性【枚举、装箱拆箱、反射、断言、注解等】三.Web前端基础
·html;
·CSS ;
·Javascript(JS);
·DOM;
·ajax;
·jQuery;四.Web后端基础
·JSP;
·JavaBean;
·Servlet;
·过滤器、监听器;
·EL表达式语言;
·jsp自定义标签;
·JSTL标准标签库;
·MVC开发模式(JSP+Servlet+JavaBean);五.开源框架
·Struts、
·Hibernate、
·Spring;
【SSH整合框架】·springMVC;
·Mybatis
·Ibatis;
【SSM、SSI整合框架】六.开发工具
初级开发工具:(这里需要在初学阶段掌握,为了模块分类清晰,放在此处)
·JDK、Tomcat;
·eclipse/Myeclipse;
·Navicat;高级开发工具:
·Maven项目管理工具;
·Git分布式版本控制系统;
·ANT代码生成工具;
·SVN/CVS/VSS版本控制工具;八.技术前沿
(处于该阶段的程序员都有可能成为引领互联网时代前进的业界精英。下面所列基本是各大技术论坛中讨论的热门技术话题,仅供参考)
·Node.js;
·AngularJS;
·EJB;
·集群;
·负载均衡;
·分布式架构;
·搜索引擎;
·规则引擎;
·事务JTA;
·JNDI;
·面向服务架构;
·面向云架构;
·NoSQL-MongoDB;
·Hadoop大数据;
·Docker云计算;
.
·机器学习;
·人工智能;
·虚拟现实;
在j2se阶段,重在熟练掌握if语句、for循环的运用,接口、继承、构造方法的理解和使用,学会查API文档。这个阶段的难点在于集合、泛型、jdbc等内容,需要了解其基本的用法和意义。
数据库阶段可以说是从只会编一些没什么实际作用的死程序,到能够开发小型项目的转折点,以上三种数据库至少掌握其中一种,个人建议从Mysql入手。当然数据库的种类不止这三个,这里所列的是行内使用最多的数据库。
做后端的人,前端的基础也是必不可少的。如果以后想做前端的话,js是关键,作为风口浪尖上的热门语言,js拥有一大批拥护者认为它将是十年后的大趋势,然而也有一些人认为js的灵活性又造成了其过于复杂的代码和混乱的逻辑,在开发中容易出错且难以调试。不过html和js的基础用法对于任何web开发人员来说都是尤为重要的。
后端基础个人建议以Servlet为中心来学习,因为servlet和java有着更紧密的联系,而jsp又是sevlet的简化抽离,就算是MVC的Model2开发模式(jsp+servlet+javabean),servlet也是作为核心的控制层,它更是开源框架的技术基础。
首个mvc模式的开源框架Struts以及后来的Struts2推出至今已经盛行了14年了,随着Spring等框架的推出和发展,使得Struts2由于大量的配置文件和独家标签库而显得相对笨重许多。这些开源框架,到底哪个好用,哪个会被取代之类的问题都不重要,因为他们都是开发的工具,作为工具来说,被更好用的工具替代是必然的,只是时间问题,所以在学习的过程中,一定要掌握工具的用法熟悉实现流程就可以了,不要死磕其实现原理。不过如果你想成为技术大牛,或者想自己也能开发一套框架出来用就另当别论了。
这里罗列的是一些用户量多、影响范围广的几种工具,看公司或个人的喜好来选择适合自己的开发工具。
在这里你可以选择你要从事的更加细致专业的开发任务,或者说选择做软件开发过程中的哪一个模块,技术要求更加的精益求精。
❷ it企业招聘,怎么写it求职简历
一、基本格调
即打开简历之后的第一印象。就好比我们看见一个人,会有一个整体的感觉,他是fashion的、小清新的还是老道的?有了第一印象之后再慢慢分解来看。
加分写法:
简洁明了,逻辑结构清晰。
字体,排版,顺畅,清晰整齐就好。
最好是PDF格式,兼容性强且不易乱序。
设计的过于浮夸或者过于简单的。(eg.有的简历五颜六色、非常酷炫,却半天找不到联系方式,抑或是只有个人基本信息和公司名称)
写了十几页,半天打不开的,或者加载了半天,打开还乱码。
清晰罗列出以上信息,这样HR就不用在接下来的电话沟通或面试中再去追问这些内容,建立我们接下来电话沟通对你的熟悉度。
再额外能加上QQ或者微信就更好了(以防有时候电话打不通哦,时不时会遇到这种情况)
大部分的基本信息没有写
甩给我一个Github链接,极致简洁的几句描述,需要通过你的链接来找你的联系方式。(如果不是博客写的特别好,基本是要放弃你了)
工作经历项目经历可参照万能的STAR法则来写,STAR不清楚的童鞋点这里啦
效力过哪些公司,我们匹配的公司? BAT? 知名大型互联网公司?
做过什么行业领域,和我们目前的行业是否匹配
擅长的技术语言,应用了哪些技术栈,(Java, Scala,Ruby, React, Vue, Microservice…)
经历的项目复杂度,及在项目中承担什么样的角色(人的变化/技术的变化/环境的变化/不同工作经历相同角色的不同点)
时间节点(空档期)
看了半天,不知所云,没有任何亮点,没有让人有去和你聊一聊深扒的信息。
XX(全栈工程师)2013.06 — 至今
参与需求分析及实现方案设计。
设计数据库表结构,实现后台功能及web页面展示。
产品线上部署及运维。
ay 配置管理工程师 2010.03 — 2013.03
负责公司产品性能测试,及线上数据分析
负责公司配置管理,环境维护等工作
MOGU是一款时尚资讯app,负责推荐页面资讯feed流的展示及用户历史的展示
负责数据层,处理前端逻辑整个开发工作,分布式rpc服务搭建
负责进行压测监测、缓存处理,对接又进行改进优化,主用redis缓存
使用java搭建爬虫server平台,进行配置和开发,进行网页改版监测功能开发
爬取淘宝时尚品牌与其他电商网站商品品牌与详情等
通过频率、ip池、匿名代理等应对一些网站的反爬
在调研了kafka的优势和我们的具体需求之后,用kafka作为消费者,保证高吞吐处理消息,并持久化消息的同时供其它服务使用,进行了系统的设计和搭建使用。 本地日志保证消息不丢失,并通过记录游标滑动重复读取数据。
使用storm 负责搭建消息处理架构,并完成基于业务的消息落地,提供后续的数据 统计分析实时和离线任务,诸如pv、uv等数据,为运营做决策
网站用户行为埋点和基于js的日志收集器开发,定义接又和前端部门配合。主用go 2、hadoop集群搭建和数据分析处理
对自己有一个全方位的一个描述总结,让别人更好的解读你。或者在此处,高亮你的优点特长有哪些。
即使不写个人评价,也一定记得写上工作期望。
我对自己的定位: 主攻前端,同时在其他方面打打辅助。我不希望过于依赖别人,即使没有后端没有设计没有产品经理,我依然想要把这个产品做到完美。毕竟全栈才能最高效地解决问题。
我对工作的态度: 第一,要高效完成自己的本职工作。第二,要在完成的基础上寻找完美。第三,要在完美的基础上,与其他同事 互相交流学习,互相提升。工作是一种生活方式,不是一份养家糊口的差事。
我怎样克服困难: 不用网络是第一原则,在遇到技术问题时我往往会去Google、Stack over flow上寻找答案。但通常很多问题 并不一定已经被人解决,所以熟练地阅读源码、在手册、规范甚至 REPL的环境自己做实验才是最终解决问题的办法。相信事实的结果,自己动手去做。
怎样保持自己的视野:我一直认为软件开发中视野极其重要,除了在 Twitter 上关注业界大牛,Github Trending 也是每周必刷。 另外 Podcast、Hacker News、Reddit 以及TechRadar 也是重要的一手资料。保持开阔视野才能找到更酷的解决方案。
我的优势: 热爱技术、自学能力强,有良好的自我认知。全面的技能树与开阔的视野,良好的心态、情商与沟通能力。
我的劣势: 非科班出身没有科班同学对算法的熟练掌握,但我决定死磕技术,弥补不足。
极客、热爱技术、热爱开源
Ruby on Rails:精通
Agile/Lean:精通
ReactJS:掌握
Docker:掌握
AWS:掌握
减分写法:
二、基本信息(姓名/性别/毕业院校/电话/邮箱/居住地/期望地)
加分写法:
减分写法:
三、工作经历&项目经历
加分写法:
减分写法:
来几个栗子
栗子1错误打开方式:
点评:看不出来他做的什么事情,没有逻辑性,甚至不知道他做的什么技术语言。
栗子2正确打开方式:
西安XXX公司 Java工程师 — 2016.2月-2017.2月
1、MOGU推荐架构数据与缓存层设计开发
2、基于JAVA的电商爬虫开发
3、同图搜索Solr服务开发
基于算法组的同图策略,使用solr做java接又实现rpc服务搭建,进行索引构建和solr实现
北京XXX
java大数据工程师— 2013.4月-2015.12月
1、负责实时流消息处理应用系统构建和实现
2、基于CDH的集群搭建工作,后期进行维护
编写MapRece程序,能将复杂工作逻辑化,尽最大能力发挥大数据应用的特点, 对程序高要求,监控自己程序运行情况,使用内存合理,注重增量和全量运算的利弊
3、调度系统设计与实现 基于quartz2搭建调度平台,带徒弟实现相关功能并定期review代码
4、数据库调优 负责主从搭建,并掌握主从搭建的利弊,了解业界mycat原理,有数据库优化经验,能 正确并擅长使用索引,对锁有深刻的认识
5、网站开发 java web网站业务开发,并能很好的使用缓存技术,对重构有实际的经验,并对面向对 象开发有全面的实战经验。了解java数据结构的使用场景,虽然对于大并发没有太大的 发挥余地,但是掌握了数据结构,对于并发和阻塞等有自己的见解。
点评:非常清晰的告诉简历阅读者自己做了什么事情,负责了什么样的事情,用了什么技术栈,且逻辑连贯。
四、 工作期望&个人评价
加分写法:
减分写法:
完全看不出个性特点,写和没写没什么区别。 来几个栗子
栗子1 错误打开方式
为人性格,诚实谦虚,勤奋,能吃苦耐劳,有耐心,有团队意识,能和同学和谐相处,能虚心接受别人的建议的人。
责任心强,善于沟通,具有良好的团队合作精神;专业扎实,具有较强的钻研精神和学习能力;性格比较乐观外向,喜欢打羽毛球。
栗子2正确打开方式
栗子3正确打开方式
❸ G1从入门到放弃(一)
最近在看关于G1垃圾收集的文章,看了很多国内与国外的资料,本文对G1的这些资料进行了整理。这篇合适JVM垃圾回收有一定基础的同学,作为G1入门可以看一下,如果要死磕G1实现的内容细节。大家可以找 R大 。 个人认为R大是目前国内JVM领域研究的先驱了,当然R大也是不建议大家去看JVM的源码的。 为啥别读HotSpot VM的源码
G1系列第一篇文章会介绍G1的理论知识,不会做JVM源码的深入分析。第二篇准备介绍G1实践中的日志分析。
G1(Garbadge First Collector)作为一款JVM最新的垃圾收集器,可以解决CMS中Concurrent Mode Failed问题,尽量缩短处理超大堆的停顿,在G1进行垃圾回收的时候完成内存压缩,降低内存碎片的生成。G1在堆内存比较大的时候表现出比较高吞吐量和短暂的停顿时间,而且已成为Java 9的默认收集器。未来替代CMS只是时间的问题。
G1的内存结构和传统的内存空间划分有比较的不同。G1将内存划分成了多个大小相等的Region(默认是512K),Region逻辑上连续,物理内存地址不连续。同时每个Region被标记成E、S、O、H,分别表示Eden、Survivor、Old、Humongous。其中E、S属于年轻代,O与H属于老年代。
示意图如下:
H表示Humongous。从字面上就可以理解表示大的对象(下面简称H对象)。 当分配的对象大于等于Region大小的一半 的时候就会被认为是巨型对象。H对象默认分配在老年代,可以防止GC的时候大对象的内存拷贝。通过如果发现堆内存容不下H对象的时候,会触发一次GC操作。
在进行Young GC的时候,Young区的对象可能还存在Old区的引用, 这就是跨代引用的问题。为了解决Young GC的时候,扫描整个老年代,G1引入了 Card Table 和 Remember Set 的概念,基本思想就是用空间换时间。这两个数据结构是专门用来处理Old区到Young区的引用。Young区到Old区的引用则不需要单独处理,因为Young区中的对象本身变化比较大,没必要浪费空间去记录下来。
下图展示的是 RSet 与 Card 的关系。每个 Region 被分成了多个 Card ,其中绿色部分的 Card 表示该 Card 中有对象引用了其他 Card 中的对象,这种引用关系用蓝色实线表示。 RSet 其实是一个HashTable,Key是Region的起始地址,Value是 Card Table (字节数组),字节数组下标表示 Card 的空间地址,当该地址空间被引用的时候会被标记为 dirty_card 。
关于RSet结构的维护,可以参考这篇 文章 ,这里不做过多的深入。
SATB的全称(Snapshot At The Beginning)字面意思是开始GC前存活对象的一个快照。SATB的作用是保证在并发标记阶段的正确性。如何理解这句话?
首先要介绍三色标记算法。
在GC扫描C之前的颜色如下:
在并发标记阶段,应用线程改变了这种引用关系
得到如下结果。
在重新标记阶段扫描结果如下
这种情况下C会被当做垃圾进行回收。Snapshot的存活对象原来是A、B、C,现在变成A、B了,Snapshot的完整遭到破坏了,显然这个做法是不合理。
G1采用的是 pre-write barrier 解决这个问题。简单说就是在并发标记阶段,当引用关系发生变化的时候,通过 pre-write barrier 函数会把这种这种变化记录并保存在一个队列里,在JVM源码中这个队列叫 satb_mark_queue 。在remark阶段会扫描这个队列,通过这种方式,旧的引用所指向的对象就会被标记上,其子孙也会被递归标记上,这样就不会漏标记任何对象,snapshot的完整性也就得到了保证。
这里引用R大对SATB的解释:
SATB的方式记录活对象,也就是那一时刻对象snapshot, 但是在之后这里面的对象可能会变成垃圾, 叫做浮动垃圾(floating garbage),这种对象只能等到下一次收集回收掉。在GC过程中新分配的对象都当做是活的,其他不可达的对象就是死的。
如何知道哪些对象是GC开始之后新分配的呢?
在Region中通过top-at-mark-start(TAMS)指针,分别为prevTAMS和nextTAMS来记录新配的对象。示意图如下:
每个region记录着两个top-at-mark-start(TAMS)指针,分别为prevTAMS和nextTAMS。在TAMS以上的对象就是新分配的,因而被视为隐式marked。 这里引用R大的解释。
其中top是该region的当前分配指针,[bottom, top)是当前该region已用(used)的部分,[top, end)是尚未使用的可分配空间(unused)。
(1): [bottom, prevTAMS): 这部分里的对象存活信息可以通过prevBitmap来得知
(2): [prevTAMS, nextTAMS): 这部分里的对象在第n-1轮concurrent marking是隐式存活的
(3): [nextTAMS, top): 这部分里的对象在第n轮concurrent marking是隐式存活的
Young GC 回收的是所有年轻代的Region。 当E区不能再分配新的对象时就会触发 。E区的对象会移动到S区,当S区空间不够的时候,E区的对象会直接晋升到O区,同时S区的数据移动到新的S区,如果S区的部分对象到达一定年龄,会晋升到O区。
Yung GC过程示意图如下:
Mixed GC 翻译过来叫混合回收。之所以叫混合是因为回收所有的年轻代的Region+部分老年代的Region。
1、为什么是老年代的 部分 Region?
2、什么时候触发Mixed GC?
这两个问题其实可以一并回答。回收 部分 老年代是参数 -XX:MaxGCPauseMillis ,用来指定一个G1收集过程目标停顿时间,默认值200ms,当然这只是一个期望值。G1的强大之处在于他有一个停顿预测模型(Pause Prediction Model),他会有选择的挑选 部分 Region,去尽量满足停顿时间,关于G1的这个模型是如何建立的,这里不做深究。
Mixed GC的触发也是由一些参数控制。比如 XX: 表示老年代占整个堆大小的百分比,默认值是45%,达到该阈值就会触发一次Mixed GC。
Mixed GC主要可以分为两个阶段:
1、全局并发标记(global concurrent marking)
全局并发标记又可以进一步细分成下面几个步骤:
2、拷贝存活对象(Evacuation)
Evacuation阶段是全暂停的。它负责把一部分region里的活对象拷贝到空region里去(并行拷贝),然后回收原本的region的空间。Evacuation阶段可以自由选择任意多个region来独立收集构成收集集合(collection set,简称CSet),CSet集合中Region的选定依赖于上文中提到的 停顿预测模型 ,该阶段并不evacuate所有有活对象的region,只选择收益高的少量region来evacuate,这种暂停的开销就可以(在一定范围内)可控。
Mixed GC的清理过程示意图如下:
G1的垃圾回收过程是和应用程序并发执行的,当Mixed GC的速度赶不上应用程序申请内存的速度的时候,Mixed G1就会降级到Full GC,使用的是Serial GC。Full GC会导致长时间的STW,应该要尽量避免。
导致G1 Full GC的原因可能有两个:
PS: 本文主要参考的国内文章:
java Hotspot G1 GC的一些关键技术
Garbage First G1收集器 理解和原理分析
G1: One Garbage Collector To Rule Them All
请教G1算法的原理
深入理解 Java G1 垃圾收集器
Getting Started with the G1 Garbage Collector !