小公司做小项目一般都用SSH+jsp大公司做项目都是根据不同的项目 采取不同的框架技术,比如银行大部分都用 EJB等
第一:先学习Java的核心库(JavaSE)
JavaSE的内容包括:环境搭建、基础语法、面向对象、数组、集合、常用类、IO流、反射机制、网络编程……
第二:MySQL数据库
搞定一门数据库相关的课程,例如:MySQL、Oracle,搞定一个就可以了,目前互联网公司,例如:京东、阿里等,他们都在使用MySQL,所以建议大家学习MySQL数据库,小巧轻盈,免费,由于互联网公司的项目访问量比较大,所以一般会搭建数据库的集群,可以一个数据库不够,所以需要搭建数据库集群,为了应付高并发。(搭建的比较多的时候,免费就很重要了。)
第三:WEB前端
以后从事Java开发,从事JavaEE开发,主要开发的系统结构是B/S结构的,B指的是Browser,S指的是Server。要开发这种系统,B端要会,S端也要精通。WEB前端的学习就是学习B端技术。包括:HTML 、CSS、JavaScript(JS)、jQuery框架(底层对JS进行了封装)…
第四:WEB后端(JavaWEB)
WEB后端其实可以是很多种不同的编程语言,例如:PHP、C、C++、Java,他们都可以进行WEB后端的开发,我们既然选择了比较火爆的Java,那么我们学习的后端一定是基于Java语言实现的,包括:Servlet、Filter、Jsp、EL、JSTL、MVC架构模式、数据库连接池(阿里巴巴的Druid连接池)、代理模式(动态代理)。另外后端学习了之后,还要学习一个异步编程技术AJAX。(完成网页的局部刷新,AJAX其实不属于后端,是前端浏览器上的程序。)
学习到这里为止,表示Java基本/基础的技术已经学完了。但是这些最基层的技术在实际的开发中不会使用的,一般为了开发效率,都会使用大量的提前封装好的框架。
第五:最好能够停留下来,做一个项目。
这个项目最好能将之前所学全部串起来。(对以前的知识点进行巩固。)
这个项目最好是基于:Servlet + Jsp+AJAX+jQuery+MySQL…
在这个项目的开发过程中:大家一定要记住,目前比较好的项目自动构建工具:Maven是一定要精通的。还有一个就是团队协作开发:Git/SVN是一定要会用的。(目前使用Git比较多一些。)
第六:学习高级框架
Spring、SpringMVC、MyBatis(持久层框架,这个框架互联网公司使用比较多,因为互联网项目需要进行SQL优化,MyBatis的SQL优化很方便,所以大部分都是使用MyBatis)
Struts2(很少使用了,使用这个的肯定是很老的项目)、Hibernate(传统企业,还有政府等可能会使用Hibernate。)
SpringBoot(新项目大部分使用的都是boot了。所以在项目中遇到还在使用SSM的一般都是遗留项目。)
当你走到这里之后,基本上你可以出山了。(去找工作,8K的薪资应该问题不大,但前提是你学的好。学习的深度够了,广度够了。)
第七:最好能有一个大型项目是使用框架来完成的。
SpringBoot做一个项目。
Spring SpringMVC MyBatis做一个项目。
这个项目最好是找几个人搭伙做一下。体验一下团队协作。(尤其是使用一些协作的工具。怎么沟通,怎么写日报,怎么开会,怎么使用Git,等等…)
第八:如果你的薪资想达到15K的话,你可能需要还要学习一些分布式相关的一些技术。
能够应付高并发的一些技术,例如:分布式框架Dubbo、SpringCloud、MQ、Nginx、Redis…
java的知识体系构架
祝 工作顺心 哈哈
gpu二缓一致,GPU的LLC是全部SM共享的,memory-side caching, 采用write-back policy,不存在一致性的问题,在异构架构中,我们可以在CPU和加速之间暴露一个全局的共享内存接口,我们假设CPU、GPU等设备共享相同的物理内存(如手机上的SoC这种情况),如下图所示。在这种系统中,共享内存会引发一些新的问题,如什么是内存一致性模型?内存一致性模型如何实现?加速和处理器的私有缓存如何保持一致?我们接下来首先讨论加速内的内存一致性和缓存一致性,重点是GPU,然后讨论跨加速的内存一致性和缓存一致性。
异构SoC系统模型
GPU的内存一致性和缓存一致性
早期GPU的架构与编程模型
早期GPU主要为并行图形工作负载设计,特点是数据并行度高,但数据共享、同步和通信程度低。
GPU架构
GPU通常有几十个内核,叫做流式多处理器(Streaming Multiprocessors,SM),每个SM都是高度多线程的,能够运行上千条线程,映射到SM上的线程共享L1缓存和本地scratchpad内存,所有的SM都共享一个L2缓存。GPU通常将线程分组执行,称为warps,一个warp中的所有线程共享PC和堆栈,可以使用掩码来执行独立的线程,表明哪些线程在执行,哪些线程没有在执行,这种并行方式就是我们常听说的SIMT。但是最近,GPU开始允许一个warp中的线程有独立的PC和堆栈,允许线程独立调度,我们接下来也假设线程是可以独立调度的。
由于图形工作负载并不经常共享数据或进行同步,早期GPU选择不在L1缓存实现硬件的缓存一致性。
GPU编程模型
和CPU类似,GPU也有一套虚拟ISA,同时也有一套更高级别的语言框架,如CUDA和OpenCL,框架中的高级语言被编译成虚拟的ISA,并被翻译为本地的二进制文件。GPU虚拟ISA和高级语言框架通过被称为作用域(scope)的线程结构,向程序员暴露GPU架构的层次结构。和CPU相比,GPU线程被分组为叫做Cooperative Thread Arrays(CTA)的集群。CTA作用域指来自同一个CTA的线程集合,保证映射到相同的SM,并共享同一个L1huancun。GPU作用域指的是来自同一个GPU的线程集合,可以来自相同或不同的CTA,并共享L2缓存。最后,系统作用域指整个系统所有线程的集合,共享LLC缓存或统一的共享内存。
这种方式可以在没有硬件缓存一致性的情况下,用软件的方式实现数据同步和通信。
GPU内存一致性
GPU支持宽松一致性模型,通过FENCE指令进行同步,但是由于没有硬件缓存一致性,GPU的FENCE只针对属于同一CTA的其他线程。GPU的store指令也不保证原子性。
因此,早期GPU明确禁止在CTA组之间进行数据同步,但实践中可以通过绕过L1,在L2上进行同步。这种方案也有一些问题,绕过L1会导致性能下降,且程序员需要仔细地编写程序。
测验问题8:GPU不支持硬件缓存一致性,因此无法实现内存一致性模型。
答:错误。早期的GPU不支持硬件缓存一致性,但是支持作用域内的宽松内存一致性模型。
GPGPU的内存一致性和缓存一致性
GPGPU最好满足以下特点:
严格而直观的内存一致性模型,允许在所有线程之间进行同步
一个能够实现内存一致性模型的缓存一致性协议,允许高效的数据共享和同步,且保持常规GPU架构的简单性,因为GPU的主要任务仍然是图形工作负载
我们可以使用类似多核CPU的方法来实现缓存一致性,使用一种与内存模型无关的协议。然而这种方法并不适用于GPU,主要有两个原因。首先,类似于CPU的缓存一致性协议在GPU环境下会产生很高的通信开销,因为L1缓存的总容量通常与L2相当,甚至更大,会产生很大的面积开销,设计也非常复杂;其次,由于GPU保持着数千个活跃的硬件线程,因此需要跟踪相应数量的一致性事务,需要大量的硬件开销。
具体的技术细节可以参考原书(埋坑,GPU的部分确实现在看来有些难理解,等之后学习了GPU的架构之后再回来填坑)。
其他异构系统
我们开始进一步讨论如何在多个设备的系统中暴露一个全局的共享内存接口,难点在于每个设备都可能通过不同的一致性协议来实现不同的内存模型,当多个内存模型不同的设备被集成在一起时,异构系统的内存模型是什么样的?如何对这种系统进行编程?如何整合多个设备的缓存一致性协议?我们接下来简单讨论这些问题,并概述设计空间。
异构系统的内存模型
如果两个设备A和B连接在一起并共享内存,这种情况下的内存模型是什么样的?一个符合直觉的答案是选择其中较弱的一个作为整体的内存模型,但如果两个内存模型无法比较,这种答案就不可行了。即使两者可以比较,可能也会有更好的答案。
四个设备组成的异构系统
在如上所示的异构系统中,C1和C2内存模型为SC,C3和C4内存模型为TSO。考虑下面的例子,在第一个例子中,有可能r1和r2同时读到0,但在第二个例子中插入了FENCE后,r1和r2就不能同时读到0了,但需要注意的是在SC的线程上仍然不需要插入FENCE,这种系统实际上产生了一个不同于SC和TSO的复合内存模型。
Dekker算法的例子
在这种系统中变成也是比较困难的,很难直接精确定义复合内存模型,更好的办法可能是使用HSA或OpenCL等进行编程。
异构系统的缓存一致性协议
通过分层缓存一致性来集成多个设备
考虑两个多核设备A和B,每个设备都有自己的内存模型,并通过不同的缓存一致性协议来实现内存模型,如上图所示。我们应该如何将两个设备集成到一个共享内存异构系统中,并将两个缓存一致性协议正确连接在一起?答案取决于每个设备的内存 *** 作是否满足自己的内存排序规则。
分层缓存一致性
在分层缓存一致性系统中,本地缓存一致性控制器收到请求后,首先试图在本地满足该请求,如果无法满足就转发到全局一致性控制器,再转发到另一个设备的本地缓存一致性控制器。在这种设计中,全局控制器必须有足够丰富的接口来满足各个设备本地控制器发起的请求,且每个本地控制器必须用shim来扩展,作为两个控制器之间的接口转换。相关的一些例子可以参考原文。
减少异构系统缓存一致性的带宽需求
在异构系统中,内核之间的缓存一致性通信带宽可能成为性能瓶颈。一种解决思路是采用粗粒度的缓存一致性,比如在GPU本地以page大小的粒度进行跟踪,如果缓存未命中且已知该位置对应的page对GPU来说是私有的或只读的,就不需要访问全局的目录,而是可以从高带宽的总线从内存直接访问。
CPU-GPU系统中缓存一致性的一个低复杂度解决方案
我们可以采用选择性的GPU缓存,任何被映射到CPU内存的数据都不会缓存在GPU中,任何来自GPU内存的数据,如果目前被缓存在CPU中,也不会被缓存在GPU中。这个简单的策略可以很好地实现缓存一致性。为了实现这种方法,GPU维护一个粗粒度的目录,维护当前由CPU缓存的数据,当CPU访问GPU内存中的一个缓存块时,这个缓存块所在的区域就被插入到目录中,目录中所有的位置都不会被缓存到GPU中。不过这种方法也有坏处,即任何被CPU缓存的数据都必须从CPU中取回,为了解决这个问题需要进行进一步的优化,如GPU对CPU的请求进行合并、在GPU上加入一个特殊的CPU侧的缓存等。
1Core
Java,就是Java基础、JDK的类库,很多童鞋都会说,JDK我懂,但是懂还不足够,知其然还要知其所以然,JDK的源代码写的非常好,要经常查看,对使用频繁的类,比如String,集合类(List,Map,Set)等数据结构要知道它们的实现,不同的集合类有什么区别,然后才能知道在一个具体的场合下使用哪个集合类更适合、更高效,这些内容直接看源代码就OK了
2多线程并发编程,现在并发几乎是写服务端程序必须的技术,那对Java中的多线程就要有足够的熟悉,包括对象锁机制、synchronized关键字,concurrent包都要非常熟悉,这部分推荐你看看《Java并发编程实践》这本书,讲解的很详细
3I/O,Socket编程,首先要熟悉Java中Socket编程,以及I/O包,再深入下去就是Java
NIO,再深入下去是 *** 作系统底层的Socket实现,了解Windows和Linux中是怎么实现socket的
4JVM的一些知识,不需要熟悉,但是需要了解,这是Java的本质,可以说是Java的母体,
了解之后眼界会更宽阔,比如Java内存模型(会对理解Java锁、多线程有帮助)、字节码、JVM的模型、各种垃圾收集器以及选择、JVM的执行参数(优化JVM)等等,这些知识在《深入Java虚拟机》这本书中都有详尽的解释,或者去oracle网站上查看具体版本的JVM规范
5一些常用的设计模式,比如单例、模板方法、代理、适配器等等,以及在Core
Java和一些Java框架里的具体场景的实现,这个可能需要慢慢积累,先了解有哪些使用场景,见得多了,自己就自然而然会去用。
6常用数据库(Oracle、MySQL等)、SQL语句以及一般的优化
7JavaWeb开发的框架,比如Spring、iBatis等框架,同样他们的原理才是最重要的,至少要知道他们的大致原理。
8其他一些有名的用的比较多的开源框架和包,Netty网络框架,Apache
common的N多包,Google的Guava等等,也可以经常去Github上找一些代码看看。
medis与Memcached的区别
传统MySQL+ Memcached架构遇到的问题
实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量的不断增加,和访问量的持续增长,我们遇到了很多问题:
1MySQL需要不断进行拆库拆表,Memcached也需不断跟着扩容,扩容和维护工作占据大量开发时间。
2Memcached与MySQL数据库数据一致性问题。
3Memcached数据命中率低或down机,大量访问直接穿透到DB,MySQL无法支撑。
4跨机房cache同步问题。
众多NoSQL百花齐放,如何选择
最近几年,业界不断涌现出很多各种各样的NoSQL产品,那么如何才能正确地使用好这些产品,最大化地发挥其长处,是我们需要深入研究和思考的问题,实际归根结底最重要的是了解这些产品的定位,并且了解到每款产品的tradeoffs,在实际应用中做到扬长避短,总体上这些NoSQL主要用于解决以下几种问题
1少量数据存储,高速读写访问。此类产品通过数据全部in-momery 的方式来保证高速访问,同时提供数据落地的功能,实际这正是Redis最主要的适用场景。
2海量数据存储,分布式系统支持,数据一致性保证,方便的集群节点添加/删除。
3这方面最具代表性的是dynamo和bigtable 2篇论文所阐述的思路。前者是一个完全无中心的设计,节点之间通过gossip方式传递集群信息,数据保证最终一致性,后者是一个中心化的方案设计,通过类似一个分布式锁服务来保证强一致性,数据写入先写内存和redo log,然后定期compat归并到磁盘上,将随机写优化为顺序写,提高写入性能。
4Schema free,auto-sharding等。比如目前常见的一些文档数据库都是支持schema-free的,直接存储json格式数据,并且支持auto-sharding等功能,比如mongodb。
面对这些不同类型的NoSQL产品,我们需要根据我们的业务场景选择最合适的产品。
Redis适用场景,如何正确的使用
前面已经分析过,Redis最适合所有数据in-momory的场景,虽然Redis也提供持久化功能,但实际更多的是一个disk-backed的功能,跟传统意义上的持久化有比较大的差别,那么可能大家就会有疑问,似乎Redis更像一个加强版的Memcached,那么何时使用Memcached,何时使用Redis呢
如果简单地比较Redis与Memcached的区别,大多数都会得到以下观点:
1 Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
2 Redis支持数据的备份,即master-slave模式的数据备份。
3 Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
抛开这些,可以深入到Redis内部构造去观察更加本质的区别,理解Redis的设计。
在Redis中,并不是所有的数据都一直存储在内存中的。这是和Memcached相比一个最大的区别。Redis只会缓存所有的 key的信息,如果Redis发现内存的使用量超过了某一个阀值,将触发swap的 *** 作,Redis根据“swappability = agelog(size_in_memory)”计 算出哪些key对应的value需要swap到磁盘。然后再将这些key对应的value持久化到磁盘中,同时在内存中清除。这种特性使得Redis可以 保持超过其机器本身内存大小的数据。当然,机器本身的内存必须要能够保持所有的key,毕竟这些数据是不会进行swap *** 作的。同时由于Redis将内存 中的数据swap到磁盘中的时候,提供服务的主线程和进行swap *** 作的子线程会共享这部分内存,所以如果更新需要swap的数据,Redis将阻塞这个 *** 作,直到子线程完成swap *** 作后才可以进行修改。
使用Redis特有内存模型前后的情况对比:
VM off: 300k keys, 4096 bytes values: 13G used
VM on: 300k keys, 4096 bytes values: 73M used
VM off: 1 million keys, 256 bytes values: 43012M used
VM on: 1 million keys, 256 bytes values: 16009M used
VM on: 1 million keys, values as large as you want, still: 16009M used
当 从Redis中读取数据的时候,如果读取的key对应的value不在内存中,那么Redis就需要从swap文件中加载相应数据,然后再返回给请求方。 这里就存在一个I/O线程池的问题。在默认的情况下,Redis会出现阻塞,即完成所有的swap文件加载后才会相应。这种策略在客户端的数量较小,进行 批量 *** 作的时候比较合适。但是如果将Redis应用在一个大型的网站应用程序中,这显然是无法满足大并发的情况的。所以Redis运行我们设置I/O线程 池的大小,对需要从swap文件中加载相应数据的读取请求进行并发 *** 作,减少阻塞的时间。
如果希望在海量数据的环境中使用好Redis,我相信理解Redis的内存设计和阻塞的情况是不可缺少的。
以上就是关于java去公司工作用到的是哪方面的知识全部的内容,包括:java去公司工作用到的是哪方面的知识、gpu二缓一致、互联网java高级工程师都什么要求等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)