public ArrayList(int initialCapacity) //LinkedList不是数组就没有 public HashMap(int initialCapacity) public StringBuffer(int capacity) 你就会知道,数组扩容很耗性能(数据量大容易oom),尽量指定容量。
public final int getAndUpdate(IntUnaryOperator updateFunction) { int prev, next; do { prev = get(); next = updateFunction.applyAsInt(prev); } while (!compareAndSet(prev, next)); return prev; } 后来从思想上理解,才知道乐观锁的概念,就是很乐观,假设你不会出错,但你要是出错了我就重试有办法给你修复,对应的就是悲观锁,就是很悲观,觉得不锁就会出错,如synchronize关键字和reentrantlock。这体现了2种不同截然不同的管理思想。这种思想经常体现在多个系统集成的设计,有些时候如果你用悲观的思想设计,实现起来很麻烦或者无法实现,但如果你用乐观的思想,减少出错条件,然后出错了能解决,代价就会小很多。
获取Map集合中所有的key可以通过map集合的keySet()方法获取例如: Map map = new HashMap(); map.put(xx,xx); //存放数据 //.... 省略 Set set = map.keySet(); //可以通过迭代器进行测试 Iterator iter = set.iter...
public class Point { private int x; private int y; public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } ...
1, 基础的语法
常量:在程序运行过程中值不会改变的量叫常量,
从程序开始到结束,无论运行了多少个类,跨越过多少次调用,这个量都不变;
常量伴随着数据类型,有整型常量,布尔型常量,字符型常量等;
常量在类中,有静态常量,成员常量;
常量由于其值不可改变,那在声明时就必须完成初始化;
变量:也就是在程序运行过程中值能被改变的量。
不管它在哪里改变,不管是被谁,只要能被改变的量就叫变量;
变量是编程里很重要的传输媒介,它可以通过各种各样的方式进行传输,用各种各样的途径去做运算,判断或赋值;
伴随着数据类型,有整型浮点型变量,字符型变量,在类和对象上,有类变量,类成员变量, 属性变量等;
类(Class): 描述一组行为,状态和属性的模板叫类
类,也就是类型, 例如人类分为男性和女性,那男性和女性就可以分别是一个类,两个类可能在身高(属性),特征(属性)上不同,这就有两个类;
在类上, 有成员变量,有属性,也有方法;
类是一个静态的概念,它没有被实例化调用时,其实就是一个代码块,一旦被实例化,就产生了类实例,类对象
对象(Object): 一个具体,真实存在的类的实例称为对象。
方法(Method): 一段代码的集合,在非OOP编程里也叫函数(Function),一个方法就是一个小功能实现的集合。由于Java是完全面向对象(OOP)的,所以所有的方法都必须声明在类对象上;
成员变量: 在类中被声明的变量即为成员变量;
属性: 一种特殊的成员变量,它可以通过get/set方法被操作,然后对get/set方法名分别去掉get/set后,剩余的部分首字母小写,就称为属性
属性一定是在类里面被定义,不可以在类外面,属性也叫类属性
关键字:
关键字就是一个词,这个词在Java语言里被征用了,它在语言中有特定的意义,开发人员在编程时不能够使用它们来做变量,常量,类上的声明;
Java关键字主要用于在访问控制,如private,public, 或者程序定义,如new,native, final, 又或者用在保留字,如goto,const;
每一种语言都有很多关键字,Java语言的关键字主要有以下这些:
2. 基础的数据类型:
Java基础数据类型就是内置的这八种:
数字相关的: 整型4个:byte,short,int, long, 浮点型两个:float,double
字符相关的: char
布尔型: boolean
3. 基础运算符: 6大类运算符
算术运算符:做数字运算时用到, 加减乘除(+-*/),求余%,自增自减++,--
关系运算符:对变量常量比较时用到,等于=,不等于!,大于>,小于<,大于等于>=,小于等于<=
位运算符:(对其二进制01)上移位使用,
逻辑运算符:与或非,逻辑型运算用到
赋值运算符:变量赋值,常量赋值给变量,方法调用时赋值,这是最常见的运算符
其他运算符:例如条件运算符?:,还有实例判断运算符instanceof
4. 基础语句:
认识了类,属性,方法这些Java语言的基本元素后,那形成Java程序的其他组成就是语句了,Java基础语句主要有三种:循环,条件,复合
循环语句: for, while, do...while, 其意思完全一样,但使用场景上稍有不同
条件语句: if ..., if...else ,if ... else if ...,
复合语句: 也成为块语句,这是为了更好的阅读性,多语句放到一起,并用{}做包含,看一下就是一个符合语句:
5. 程序入口:
每一个程序在运行时都有一个入口,这也是程序运行的起点,第一句语句也在入口这里被执行;
程序入口是被Java语言直接定义好的,这相对于语言运行机制(JVM)与程序之间的一种约定,让JVM怎么找到你;
Java程序入口是一个名为main的public的静态方法,这个方法在你需要运行的类里面定义, 参数是String[]:
6. 第一个Java程序:大名鼎鼎(chou ming zhao zhu)的hello world
掌握了上面可以说是最基本的知识点,就可以开始第一个Java程序的编写了,我们来到著名的hello world上来,三行代码,在控制台屏幕上打印出这一行字:
近日里,很多人邀请我回答各种j2ee开发的初级问题,我无一都强调java初学者要先扎实自己的基础知识,那什么才是java的基础知识?又怎么样才算掌握了java的基础知识呢?这个问题还真值得仔细思考。
我做j2ee开发已经超过十载,作为过来人,心路历程估计和大家差不多。编码的前几年,很长一段时间觉得java简单,开发实现各种功能都很轻松,代码写起来根本不费劲(主要是因为写的代码都是一些功能业务逻辑)。但同时自己心里明白,自己其实没有什么水平,自己这3,4年以来学懂的东西就那么多,其他人几个月就可以学会,自己的竞争力在哪里?这种矛盾的心理,困扰了我非常长的时间,非常的苦恼!总有一种报国无门无处发力的感觉。
这个时期,热衷了使用各种框架,各种api,常以今天学习了某个api,组件,框架的使用就觉得自己学到了东西,设计模式也看过不止一次,但都没有啥感觉。一方面很努力学习,一方面又觉得不踏实,因为例如这个api我知道而你不知道,但我告诉你之后你就知道了,那我比你的优势在哪里呢?苦恼*2
过了很长一段这种惶惶不可终日的日子,决定自己要改变,改变的方向就是阅读自己用到的java相关的源代码,看看jdk是如何实现的。就从基本的数据结构看,然后看多线程相关,在学习前台等等。写的代码还是那些代码,代码还是那么简单,但我力求做到知道代码背后的真相,这就是我最开始努力的方向。于是不再把时间都花在追求各种新框架、新API的使用上,每天都花时间在看实现原理上。就这样过了大半年左右,终于不再迷茫,不会在觉得自己只懂api的使用,觉得自己没有那么肤浅了,说脱胎换骨也不为过。那段时间,是我成长最快的时期,也是最充实的一段时光。
Talk is cheap,show me the code。举例说明大家会比较有感觉。
如学习了hashmap的源代码知道了工作原理之后,使用hashmap
Map map = new HashMap<>();
代码还是那个代码,但我已经知道了hashmap背后的东西
数据结构是链表的数组(注:后面的版本为了提升性能,已经是改成链表或者树(节点较多)了)
思想上是空间换时间的算法
构造函数上有容量和负载因子2个参数以及作用
决定性能的是key的hashcode是否够快、结果够分散(不分散就会变成链表的性能了),和扩容的开销(什么时候扩容,和负载因子有关)
然后写代码的时候,如果知道了最终的容量(尤其是数据量大的时候),我都会指定初始化容量,类似如下
List list = doSomeThing();
Map map = new HashMap<>((int)(list.size()/0.75));//0.75为默认负载因子
如果工作中某个map使用特别多,性能还需要继续优化,我就会考虑从以下方面优化
如果key是自己定义的对象,那么hashcode方法是否够快(最少应该缓存保证只计算一次,而且放入之后不能改变,决定hashcode的字段不能改变)? hash的结果是否够分散?
可以考虑调小负载因子,花更多的空间来换时间
学习源代码的时候,特别有意思,你会强烈感觉到一个词:举一反三!触类旁通!学习api使用的时候,如果你只知道使用不知道原理,很难举一反三,感觉的是死记硬背。但学习了原理之后,知识成体系后,很容易举一反三,学的越多就容易,还是以hashmap为例,我举一个hashmap反三个点。
你会知道但凡有数组的数据结构,构造函数都有一个容量的初始化参数(或者说构造函数有初始化容量的可能都是数组的数据结构)。构造函数如下
public ArrayList(int initialCapacity) //LinkedList不是数组就没有
public HashMap(int initialCapacity)
public StringBuffer(int capacity)
你就会知道,数组扩容很耗性能(数据量大容易oom),尽量指定容量。
算法是空间换时间,还有没有其他算法是这种思想的?你最少能找到一个桶排序。
数据库的分库分表,思路和hashmap大同小异
各种分布式的hash一致性算法,第一步都是创建一个最大的数组(Integer.MAX_VALUE),就是避免了hashmap最耗性能的扩容运算。
学习了hashmap之后,你很自然就会去了解其他的map,如TreeMap,LinkedHashmap(超级有用),HashTable,ConcurrentSkipListMap(算法思路很有意思),ConcurrentHashMap等,你会知道set就是用map做的,都不需要学。到了这步,map相关就可以暂告一段落。
在学习中,我发现思想上的东西是最重要的,你理解了思想,一下子就豁然开朗了,在也不需要死记硬背了。如学习CAS的时候,大家都知道这是一种指令级的免锁实现。看代码的时候,我一度疑惑为什么会有个while死循环(原谅我天资驽钝)
public final int getAndUpdate(IntUnaryOperator updateFunction) {
int prev, next;
do {
prev = get();
next = updateFunction.applyAsInt(prev);
} while (!compareAndSet(prev, next));
return prev;
}
后来从思想上理解,才知道乐观锁的概念,就是很乐观,假设你不会出错,但你要是出错了我就重试有办法给你修复,对应的就是悲观锁,就是很悲观,觉得不锁就会出错,如synchronize关键字和reentrantlock。这体现了2种不同截然不同的管理思想。这种思想经常体现在多个系统集成的设计,有些时候如果你用悲观的思想设计,实现起来很麻烦或者无法实现,但如果你用乐观的思想,减少出错条件,然后出错了能解决,代价就会小很多。
说了这么多,我想说的就是,j2ee的基础知识就是你做项目中代码背后的东西。提高自己水平的方法很简单,就是把大部分时间去了解实现原理,了解思想,让自己的知识串起来,形成体系。j2ee的知识特别多,学得人想哭,千万不要一开始把时间花在各种框架、组件的使用上,在我看来那是本末倒置。简单来说:先修内功再练招式。
我觉得重要的、工作会用得到的知识就是一个请求从前台到后台处理的过程需要用到的东西,最少包括以下点:js,html,css,ajax,ajax跨域,跨站脚本,web缓存,web优化,nginx,apache作用,鉴权方式,cookie,session,servlet,filter,基本数据结构,线程池,线程并发,缓存,io等等,知识点非常多。如你前台用jq,你应该了解他的选择器和ajax是如何实现的(其实去了解就会发现不复杂)?而不是只是会用。后台你用springmvc,你要了解他是如何工作,每一个配置是做什么,为什么?
j2ee知识点特别多,每一个都能写很多,我也在不断学习中。具体要写我还真不知道如何下手,我就列举一下我觉得基础的东西(面试的时候问的问题),有简单有难,你觉得偏可能是你没有做过这块的开发或者做得比较浅:
map有哪些,特点和使用场景?(只知道hashmap,hashtable是不够的。。。)
哪些方面会影响hashmap的性能?
线程安全的map有哪些,concurrenthashmap是如何实现线程安全的(jdk1.8大不同)?
锁有哪几种?
公平锁,读写锁等如何实现?
synchronize能加在哪些地方?什么区别?
死锁的形成条件?现在很少死锁了,很少问
原子数据对象的原理?
reentrantlock相关知识,condition如何使用?(很重要的知识点,强烈推荐阅读ArrayBlockingQueue源码,教科书般)
volatile的相关知识(内存屏障,重排)
ThreadLocal原理和使用?(超级有用的知识点,工作中使用很多,让代码漂亮很多,后面专门开贴写)
多个线程同步等待?(CountDownLatch,CyclicBarrier,Semaphore信号量很多语言都有,实际上使用不是很多,线程池就可以实现大部分等待功能)
线程池?(种类,重要的方法,这个一般是使用层面,简单)
动态代理?反射?内省?(考察知识面)
session相关知识?和cookie关系?分布式session实现原理?
cookie相关知识?有哪些属性?(有些属性很有用,只是我们很少留意而已!)
nginx,apache 实际项目能做哪些?(鉴权,转发,缓存,反向代理等)和tomcat什么关系?最少了解
ajax跨域原因?解决方式?(重点知识,做SE避免不了的问题。这里很多知识点。)
jsonp原理?后台需要改动吗?(jsonp虽然现在落伍了,但还是会问问)
web优化知识点?(常规知识点)
前台缓存相关?(200cache,304,ajax缓存,如何实现缓存)
一列举就根本停不下来了。。。其他的spring框架的东西也很多,还有jvm的东西,系统集成相关,数据库相关,io做得很少也不懂问,后面再慢慢把我的学习过程和偶得写下来。很多东西我也是了解个大概,就是看看你有没有学习过,不断学习是程序员最重要的特征。
我不算高手,只能算一个合格的老程序员。这里只是说了一下自己之前学习的方向和列举了几个学习中的例子,大家见仁见智。帖子也是针对迷茫的初学者有感而发,希望能帮助到大家。
最后我总结一下:初学者先广在精,关注代码背后的实现,关注内功修炼,了解实现原理和思想,形成自己完整的技术体系,知识成片之后就容易触类旁通,进步的速度就会越来越快。最后以我在每一个项目组和开发人员聊天都会说的几个例子结尾:“少林功夫里面有功和拳之分,马步功,石锁功是功,蛇拳猴拳是拳,你不可能练会了蛇拳猴拳就能打人,你必须先重点练功。乔峰在聚贤庄用太祖长拳把大家打得落花流水,我们用太祖长拳就只是个广播体操。同样,我们要分清编程里面那些是功那些是拳,代码背后的实现和思想是功,各个框架、api使用是拳。初学者应该大部分时间花在练功上,功到了拳自然就有了,切勿本末倒置。”谢谢大家阅读!
相关问题推荐
对于每一位才开始接触JAVA的新手来说,先不要管算法和数据结构,大多数简单的程序不需要用到算法和数据结构,所以当你真正需要时再去学习。编程一段时间以后,你就会知道在哪些地方用到他们。这时知道算法的名字并了解它们的功能,然后动手去实践。当我们在去...
2个都很好就业,更关键的是要学得到东西
获取Map集合中所有的key可以通过map集合的keySet()方法获取例如: Map map = new HashMap(); map.put(xx,xx); //存放数据 //.... 省略 Set set = map.keySet(); //可以通过迭代器进行测试 Iterator iter = set.iter...
不同年龄,不同掌握程度,学历,找工作城市,面试能力这是一个多方面影响的结果,如果是平均值的话,全国平均薪资14k左右
具体学多久,根据自己的学习力,自律性、解决问题能力来决定若系统性学习,跟着讲师的节奏走,大概半年左右,有专业的讲师把课程进行规划,尽心系统学习,有问题,讲师会帮忙解决,学习的效率很高,避免了自学中出现各种问题解决不了,而耽误很多时间,可能会...
IO的方式通常分为几种,同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO。一、BIO 在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSocket,然后在客户端启动Socket来对服务端进行通信,默认情况下服务端需要...
(1)idea启动时会有两个快捷方式,安装完后默认生成在桌面的是32位的idea的快捷方式,如果我们使用这个快捷方式运行大项目,一般都会很卡。解决方法是找到idea的安装目录,然后进入bin文件夹,找到名称为idea64的应用程序,右键他生成桌面快捷方式。以后每次...
ava是一种区分字母的大小写的语言,所以我们在定义变量名的时候应该注意区分大小写的使用和一些规范,接下来我们简单的来讲讲Java语言中包、类、变量等的命名规范。(一)Package(包)的命名Package的名字应该都是由一个小写单词组成,例如com、xuetang9、compan...
public class Point { private int x; private int y; public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } ...
经典版单例模式public class Singleton { private static Singleton uniqueInstance;//利用一个静态常量来记录singleton类的唯一实例。 private Singleton() { } public static Singleton getInstance()...
哈希表的长度一般是定长的,在存储数据之前我们应该知道我们存储的数据规模是多大,应该尽可能地避免频繁地让哈希表扩容。但是如果设计的太大,那么就会浪费空间,因为我们跟不用不到那么大的空间来存储我们当前的数据规模;如果设计的太小,那么就会很容易发...
1. DOM(Document Object Model) DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才...
1)作用不同: throw用于程序员自行产生并抛出异常; throws用于声明在该方法内抛出了异常2) 使用的位置不同: throw位于方法体内部,可以作为单独语句使用; throws必须跟在方法参数列表的后面,不能单独使用。3)内容不同: throw抛出一个异常对象,且只能是...
基本执行过程如下:1)程序首先执行可能发生异常的try语句块。2)如果try语句没有出现异常则执行完后跳至finally语句块执行;3)如果try语句出现异常,则中断执行并根据发生的异常类型跳至相应的catch语句块执行处理。4)catch语句块可以有多个,分别捕获不同类型...
100-199 用于指定客户端应相应的某些动作。 200-299 用于表示请求成功。 300-399 用于已经移动的文件并且常被包含在定位头信息中指定新的地址信息。 400-499 用于指出客户端的错误。 400 语义有误,当前请求无法被服务器理解。 401 当前请求需要用户验证...
异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误,只要程序设计得没有问题通常就不会发生。受检异常跟程序运行的上下文环境有关,即使程序设计无误,仍然可能因使用的问题而引发。Java编译...