1.引言html
毕业已经一年有余,这一年里特别感谢技术管理人员的器重,以及同事的帮忙,学到了很多东西。这一年里走过一些弯路,也碰到一些难题,也受到过作为一名开发却常常为系统维护和发布当救火队员的苦恼。遂决定梳理一下本身所学的东西,为你们分享一下。前端
通过一年意识到之前也有不少认识误区,好比:java
偏心收集,常常收集各类资料视频塞满一个个硬盘,而后心满意足的看着容量不行动。mysql
不重基础,总以为不少基础东西不须要再看了,其实不懂的地方不少,计算机程序方面任何一个结果都必有缘由,不要只会用不知道原理,那是加工厂出来的。如今ide查看代码那么方便,ctrl+点击就进入了JDK查看实现细节。linux
好高骛远,在计算机基础不牢固的状况下,总想着要作架构,弄分布式,搞大数据之类。nginx
不重视性能,只求能实现功能,sql查询是否是能够优化,是否有算法妙用,大对象是否要清除。git
不重视扩展性,模块之间紧密耦合,经常使用方法不提取成工具类,调用关系混乱等问题。程序员
……web
本文重点不在这些,故只列举了一小部分,下面进入正题。面试
2.语法基础
2.1 Java类初始化顺序
这是全部状况的类初始化顺序,若是实际类中没有定义则跳过:父类静态变量——父类静态代码块——子类静态代码块——父类非静态变量——父类非静态代码块——父类构造函数——子类非静态变量——子类非静态代码块——子类构造函数
2.2 值传递和引用传递
可能不少人对此不屑一顾,心想老子都工做一年了,对这些还不熟悉吗?但实际状况并不是这样,JDK中东西所有熟悉了吗?以一个最简单的例子开始,你以为下图中代码执行完以后fatherList中的元素是什么?
<img src="https://pic2.zhimg.com/50/v2-2c124a5cfaad73d04c5eeb42d83a1375_hd.jpg" data-caption="" data-size="normal" data-rawwidth="932" data-rawheight="266" class="origin_image zh-lightbox-thumb" width="932" data-original="https://pic2.zhimg.com/v2-2c124a5cfaad73d04c5eeb42d83a1375_r.jpg">
请点击此处输入图片描述
这是一个最基础的值传递和引用传递的例子,你以为好简单,已经想跃跃欲试的挑战了,那么请看下面的,StringBuffer很好理解,可是当你执行一遍以后发现是否是和预想中的输出不同呢?String不是引用类型吗,怎么会这样呢?若是你没法理解,那么请看下String的实现源码,了解下其在内存中分配的实现原理。
<img src="https://pic2.zhimg.com/50/v2-dda807c5b26618515b3c10f37fbd5245_hd.jpg" data-caption="" data-size="normal" data-rawwidth="1082" data-rawheight="896" class="origin_image zh-lightbox-thumb" width="1082" data-original="https://pic2.zhimg.com/v2-dda807c5b26618515b3c10f37fbd5245_r.jpg">
请点击此处输入图片描述
2.3 集合的使用
这部分几乎每一个人都会用到,并且你们还都不陌生。下图来源于互联网,供你们复习一下。可是利用集合的特性进行巧妙的组合运用能解决优化不少复杂问题。Set不可重复性,List的顺序性,Map的键值对,SortSet/SortMap的有序性,我在工做中有不少复杂的业务都巧妙的使用了这些,涉及到公司保密信息,我就不贴出代码了。工做越久愈加现这些和越巧妙。
<img src="https://pic2.zhimg.com/50/v2-d68c73a0ea3cd59d77e92390e3d00f99_hd.jpg" data-caption="" data-size="normal" data-rawwidth="530" data-rawheight="499" class="origin_image zh-lightbox-thumb" width="530" data-original="https://pic2.zhimg.com/v2-d68c73a0ea3cd59d77e92390e3d00f99_r.jpg">
请点击此处输入图片描述
2.3 异常处理
1.看着try、catch、finally很是容易,若是和事务传播结合在一块儿,就会变得极其复杂。
2.finally不必定必须执行,return在catch/finally中处理状况(建议亲自操刀试一下)。
3.catch中能够继续抛自定义异常(并把异常一步步传递到控制层,利用切面抓取封装异常,返回给调用者)。
2.4 面向对象思想
一提起面向对象,你们都知道抽象、封装、继承、和多态。可是实际工做经验中又知道多少呢,对于项目中如何巧用估计更不要提了。
共性的机会每一个都须要用的创建基类,如每一个控制层方法可能要经过security获取一个登陆用户id,用于根据不一样的用户操做不一样的数据,能够抽象出一个应用层基类,实现获取id的protect方法。同理DAO层能够利用泛型提取出一个包含增删改查的基类。
多态的Override:基类的引用变量不只能够指向基类的实例对象,也能够指向其子类的实例对象,若是指向子类的实例对象,其调用的方法应该是正在运行的那个对象的方法。在策略模式中使用很广泛。
提到面向对象,就不可避免的要说设计模式,在工做中,一个技术大牛写的一个相似策略模式(更复杂一点),十分巧妙的解决了各类业务同一个方法,而且实现了订单、工单、业务的解耦,看得我是很是佩服。我想不少面试中都会问道单例模式吧,尚未理解的建议去看一看。
3.多线程
3.1 线程安全
这个是老生常谈的问题了,可是确实是问题和bug高发区。线程同步问题不须要单独写了,想必你们都清楚,不太熟悉的建议百度一下。
3.1.1 线程安全问题
1.代码中若是有同步操做,共享变量要特别注意(这个通常都能意识到)
2多个操做能修改数据表中同一条数据的。(这个容易被忽略,业务A可能操做表a,业务B也能够操做表a,业务A、B即便在不一样的模块和方法中,也会引发线程安全问题。例如若是一我的访问业务A接口,另外一我的访问业务B接口,在web中每一个业务请求都是会有单独的一个线程进行处理的,就会出现线程安全问题)。
3.不安全的类型使用,例如StringBuffer、StringBuild,HashTable、HashMap等。在工做中我就遇到过有人在for循环进行list的remove,虽然编译器不报错,程序能够运行,可是结果却可想而知。
4.Spring的bean默认是单例的,若是有类变量就要特别当心了(通常状况下是没人在控制层、业务层、DAO层等用类变量的,用的话建议是final类型,例如日志log,gson等)。
5.多个系统共享数据库状况,这个其实和分布式系统相似
用户重复提交问题(即便代码中从数据库读取是否存在进行限制不能解决问题)
3.1.2 线程安全解决
在须要同步的地方采用安全的类型。
JDK锁机制,lock、tryLock,synchronized,wait、notify、notifyAll等
Concurrent并发工具包,在处理一些问题上,谁用谁知道。强烈建议查看源码!
数据表加锁。(除非某个表的访问频率极低,不然不建议使用)
涉及分布式的,采用中间件技术例如zookeeper等解决。
3.2 异步
异步使用场景不影响主线程,且响应较慢的业务。例如IO操做,第三方服务(短信验证码、app推送、云存储上传等)。
若是异步任务不少,就须要使用任务队列了,任务队列能够在代码级别实现,也能够利用redis(优点太明显了)。
3.3 多线程通讯
这方面文章很是多,这里不在详述。
1.共享变量方式(共享文件、全局变量,信号量机制等)
2.消息队列方式
3. 忙等,锁机制
3.4多线程实现
1.集成Thread类,重写(这里的重写指的是override)run方法,调用start方法执行。
2.实现Runable接口,实现run方法,以Runable实例建立thread对象。
3.实现Callable接口,实现call方法,FutureTask包装callable接口,FutureTask对象建立thread对象,经常使用语异步操做,建议使用匿名内部类,方便阅读和使用。
额外须要说明的是:
1.理解thread的join方法;
2.不要认为volitate是线程安全的(不明白缘由的建议去看jvm运行时刻内存分配策略);
3.sleep时间片结束后并不保证立马获取cpu。
4.ThreadLocal可以为每个线程维护变量副本,经常使用于在多线程中用空间换时间。
4. 开源框架
4.1 Hibernate、Mybatis
相信每个java程序员对这些都不陌生,这里再也不详述。
须要说明的主要如下几点:
1.hibernate一级缓存(内置session缓存),二级缓存(可装配sessionFactory缓存),二级缓存会引发并发问题。
2.hibernate延迟加载原理理解。
3.hibernate 的get、load方法,sava、persist、savaOrUpdate方法区别
4.session重建了关联关系却并无同数据库进行同步和更新
5.hibernate session关联关系:detached对象、persistent对象
6.Spring data集成,注解方式配置属性和实体。
7.mybatis 插件。
8.分页查询(数据库)。
9.链接池技术
4.2 Spring IOC
4.1.1 Spring bean
1.bean注入 注解方式方便易读,引用第三方(数据库链接,数据库链接池,JedisPool等)采用配置文件方式。
2. bean做用域:Singleton,prototype,request,session,global session
3.bean生命周期:以下图所示(图片来源于互联网):
<img src="https://pic4.zhimg.com/50/v2-0fe77174092501aaba1ee3f66e125727_hd.jpg" data-caption="" data-size="normal" data-rawwidth="565" data-rawheight="541" class="origin_image zh-lightbox-thumb" width="565" data-original="https://pic4.zhimg.com/v2-0fe77174092501aaba1ee3f66e125727_r.jpg">
请点击此处输入图片描述
4.3 Spring AOP
基本概念:关注点、切面Aspect、切入点pointcut、链接点joinpoint、通知advice、织入weave、引入introduction。
Spring AOP支持5中类型通知,分别是MethodBeforeAdvice、AfterReturningAdvice、ThrowsAdvice、MethodInterceptor、IntroductionInterceptor(吐槽一下名字太长)
实现方式以下:
1.基于代理的AOP
2.基于@Aspect注解驱动的切面。(强烈推荐:可读性好,易维护,易扩展,开发快)
3.纯POJO切面。
4.注入式Aspect切面。
4.4 Srping事务
4.4.1 事务传播
概念:某些操做须要保证原子性,若是中间出错,须要事务回滚。若是某个事务回滚,那么调用该事务的方法中的事务的做出如何的动做,就是事务传播。
短期内写不清楚,建议访问 http://www.cnblogs.com/yangy608/archive/2010/12/15/1907065.html 查看。
事务传播属性:
1. PROPAGATION_REQUIRED--支持当前事务,若是当前没有事务,就新建一个事务。这是最多见的选择。
2. PROPAGATION_SUPPORTS--支持当前事务,若是当前没有事务,就以非事务方式执行。
3. PROPAGATION_MANDATORY--支持当前事务,若是当前没有事务,就抛出异常。
4. PROPAGATION_REQUIRES_NEW--新建事务,若是当前存在事务,把当前事务挂起。
5. PROPAGATION_NOT_SUPPORTED--以非事务方式执行操做,若是当前存在事务,就把当前事务挂起。
6. PROPAGATION_NEVER--以非事务方式执行,若是当前存在事务,则抛出异常。
事务隔离级别:
1. ISOLATION_DEFAULT: 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.另外四个与JDBC的隔离级别相对应
2. ISOLATION_READ_UNCOMMITTED: 这是事务最低的隔离级别,充许令外一个事务能够看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。
3. ISOLATION_READ_COMMITTED: 保证一个事务修改的数据提交后才能被另一个事务读取。另一个事务不能读取该事务未提交的数据
4. ISOLATION_REPEATABLE_READ: 这种事务隔离级别能够防止脏读,不可重复读。可是可能出现幻像读。它除了保证一个事务不能读取另外一个事务未提交的数据外,还保证了避免下面的状况产生(不可重复读)。
5. ISOLATION_SERIALIZABLE 这是花费最高代价可是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读。
4.5 其余Spring 技术栈
spring boot 轻量级启动框架
spring security 用户权限管理,根据角色和用户,实现UserDetailsService,进行自定义权限管理。
spring task 代码级定时任务,注解方式,使用起来很是方便。须要注意的是,若是某次定时任务出了异常而没有进行处理,会致使接下来定时任务失效。若是各个任务相互独立,能够简单用try,catch包围(以前就吃过这方面的亏)。
spring data 注解方式定义实体,属性等
spring mvc 简单明了的mvc框架。url传值、数组传值、对象传值、对象数组等传值类型,上传/下载文件类型须要注意。
spring restful 注意命名,对命名要求很严格。
spring shell 命令行方式执行命令,救火、导入导出数据等用起来很是方便、制做报表。
5. Web基础
5.1 web容器启动
1.web.xml加载顺序: listener -> filter -> servlet
2.webt容器启动过程,java新手很怕配置文件,理解完这些有助于熟悉配置文件 http://blog.csdn.net/u014431852/article/details/47042895
5.2 Servlet、Interceptor、Listener、Filter
Servlet 接收请求返回响应,最原始的web业务处理类。
Interceptor 拦截器,能够实现HandlerInterceptor接口自定义拦截器,在日志记录、权限检查、性能监控、通用行为等场景使用,本质是AOP。
Listener 监听器 经常使用于统计在线人数等纵向功能。
Filter 过滤器 在请求接口处理业务以前改变requset,在业务处理以后响应用户以前改变response。若是某些数据不加密,很容易用抓包工具加filter做弊。
5.3 web项目结构
5.3.1 mvn结构
熟练掌握几种常见的mvn项目结构,mvn能够自动生成,这里再也不详述。
5.3.2 mvn包管理
1.版本号尽可能几种在一个文件中便于管理。
2.spring milestone包解决spring包冲突问题。
3.mvn dependency:tree命令分析全部包依赖,对于冲突的在pom文件中 包围起来
5.3.3 版本控制
1.git、svn等
2.代码冲突解决方案
3.分支管理。
对于某个稳定版本上线后,若是在此基础上开发新功能,必定要新建分支,在新分支上提交代码,最后在新版发布时合并分支。修改运营环境bug切换到主分支进行修改
5.4 Http请求
5.4.1 请求方法
post、get、put、head、delete、copy、move、connect、link、patch,最经常使用的是前四、5个。
5.4.2 请求头,状态码
经常使用的请求头有Accept(下载文件会特殊使用)、Accept-Charset(设置utf-8字符集)、Content-Type(json等配置)等
经常使用的响应头有Content-Type、Content-Type、Content-Length等,偏前端,再也不详述。
6. 系统架构
接触的不是特别多,目前用到的只是服务器主从备份。Nginx反向代理进行配置。
多个项目nginx配置
Spring Mvc 用json数据进行交互,配置json转换的servlet。
封装返回值
自定义RunEnvironmentException(状态码,缘由),覆盖原有Exception,切面ExceptionHandler抓取Exception并封装到返回值中(先后端松耦合)
使人头疼的用户重复(连续快速点击)提交问题,前端限制治标不治本;后端用sessonid在切面上实现,又须要前端存储,对全部请求数据加sessionId。最后用jedis中存储,用接口名+用户名当作key,根据不一样的接口对不一样的key能够单独设置时间,不只保证了重复提交问题,也避免了恶意请求问题,同时还能自定义请求间隔。(期初担忧redis缓存读写时间延误致使限制失效,后来发现多虑了,对通常的小系统来讲,经性能测试,发现即便请求频率再提升100被也不会致使限制失效)
testNg单元测试、性能测试,覆盖测试。
切面管理日期、权限。缓存等。
7. Nosql
1.Redis的java库Jedis。
Jedispool配置。
项目中用到的有任务队列、缓存。
2. neo4j图数据库
处理社交、推荐
8. 服务端
linux操做系统熟悉以centos为例:
经常使用简单命令:ssh、vim、scp、ps、gerp、sed、awk、cat、tail,df、top,shell、chmod、sh、tar、find、wc、ln、|
目录结构明细:/etc/、~/、/usr/、/dev/、/home/、/etc/init.d/
服务端:jdk、tomcat、nginx、mysql、jedis、neo4j启动与配置(特别说明的是该死的防火墙,nginx启动后一直访问不了,查找一下午查不到缘由,最后发现是防火墙问题)
监控服务器状态(cpu,磁盘,内存),定位pid,日志查看
nginx负载均衡、反向代理、配置
自动化部署脚本
简单shell脚本书写,避免大量人力劳动。
监控系统,代码抛fatal异常自动发邮件,系统指标持续偏高自动发邮件。
9. 数据库相关
10. 第三方接口对接
10.1 支付接口
微信支付坑比较多,用将近两周时间才把微信支付全部完成。须要在微信后台配置的地方太多。
而支付宝支付模块只用了2天时间就搞定了。
10.2 推送接口
为用户定义tag、定义alias,注意当数据更新时须要同步更新tag、更新alias。若是没采用异步实现(用户体验就是好卡啊)
10.3 云存储
大量文件上传云端(七牛云),注意建立bucket
10.4 短信验证
很简单的第三方接口,引入依赖,直接调用便可。须要在第三方后台设置模板等,注意限定用户访问次数。
10.5 邮件
很简单小功能,工具类。
时间有限,目前先写这么多技术栈。对于代码书写和、算法技巧问题,会抽时间写在(2)中。
一个程序员学习平台分享给大家,让你在实践中积累经验掌握原理。主要方向是JAVA工程师。若是你想拿高薪,想突破瓶颈,想跟别人竞争能取得优点的,想进BAT可是有担忧面试不过的,能够加个人Java学习交流群:282711949。
注:加群要求
一、大学学习的是Java相关专业,毕业后面试受挫,找不到对口工做能够
二、在公司待久了,如今过得很安逸,但跳槽时面试碰壁。须要在短期内进修、跳槽拿高薪的
三、参加过线下培训后,知识点掌握不够深入,就业困难,想继续深造
四、已经在Java相关部门上班的在职人员,对自身职业规划不清晰,混日子的
五、有必定的C语言基础,接触过java开发,想转行的
原做者姓名:木公松
原出处:博客园
原文连接:java后端程序员1年工做经验总结