黄 凯高级讲师
多年移动互联网开发经验,精通Android与iOS开发,对JavaEE等后台技术也
有所研究。尤其精通Android平台的开发,对Android平台下的性能优化有极其丰富的经验。 曾就职于酷狗音乐担任高级Android软件工程师与Team
Leader一职,带领超过20人的开发团队,有丰富的开发与管理经验。参与开发了<酷狗音乐>,<繁星网>,<中国电信移动办公>,
<智慧天河>,<翼健康>,<创饷无限>,<外修管家>等20多款互联网热门应用。其不但开发经验丰富,教学幽默风趣,而且对
学生要求严格,坚持授人与鱼不如授人与渔的理念,注重培养学生的解决问题与自我思考的能力。
Java工程师就业前景
Java工程师就业前景
2015年,在美国、加拿大、澳大利亚、新加坡等发达国家和中等发达国家,
JAVA软件工程师年薪均在4—15万美金,而在国内,JAVA软件工程师也有极好的工作机会和很高的薪水。
在未来5年内,合格软件人才的需求将远大于供给。JAVA软件工程师是目前
国际高端计算机领域就业薪资非常高的一类软件工程师。
一般情况下的JAVA软件工程师是分四个等级,从软件技术员到助理软件工程
师,再到软件工程师,**后成为高级软件工程师。
根据IDC的统计数字,在所有软件开发类人才的需求中,对JAVA工程师的需
求达到全部需求量的60%—70%。同时,JAVA软件工程师的工资待遇相对较高。
通常来说,具有3—5年开发经验的工程师,拥有年薪15万元是很正常的一个
薪酬水平。80%的学生毕业后年薪都超过了8万元。
根据专业数据分析,由于我国经济发展不均衡因素,JAVA软件工程师工资待
遇在城市之间的差异也较大,一级城市(如北京、上海等),初级软件工程师的待遇大概在4000-6000之间,中级软件工程师的待遇在6000—8000之间,
而高级软件工程师的待遇基本破万。
一阶段:Java基础
内容有Java开发介绍、Java数组、Java面向对象、常用基础类、集合
、线程和I/O、异常处理、项目(坦克大战、打飞机等)。
二阶段:JavaWeb
内容有HTML5入门、CSS3入门、Javascript、MySQL使用、JDBC连接池
、Servlet、ajax、jQuery、项目。
三阶段:Java框架
内容有Struts2、Hibernate5、JPA、Spring4、BootStrap、echarts
图表插件使用、Maven、SpringData、SpringMVC。
四阶段:Java 云数据
亿级并发架构演进、Linux基础、搭建tomcat环境、MysQL高级、
memcached、Redis、MongoDB(而选一)、elasticsearch、cobar、Quartz、nginx反向代理和负载均衡、SSL证书配置、Keepalived双活、Haproxy、
LVS、nignx(三选一)、Rpc和Dobbo、ActiveMQ队列、Hadoop、项目(上亿人并发的抢票系统)。
十大排序算法
>
选择排序 选择排序的基本思想是对待排序的记录序列进行n-1遍的处理,第i遍处理是将L[i..n]中**小者与L[i]交换位置。这样,经过i遍处理之后,前i个记录的位置已经是正确的了。 选择排序是不稳定的。算法复杂度是O(n ^2 )。
class SelectionSorter
{
PRivate int min;
public void Sort(int[] arr)
{
for(int i=0;i<arr.Length-1; i)
{
min=i;
for(int j=i 1;j<arr.Length; i)
{
if(arr[j]<arr[min])
min=j;
}
int t=arr[min];
arr[min]=arr[i];
arr[i]=t;
}
}
}
冒泡排序 冒泡排序方法是**简单的排序方法。这种方法的基本思想是,将待排序的元素看作是竖着排列的“气泡”,较小的元素比较轻,从而要往上浮。在冒泡排序算法中我们要对这个“气泡”序列处理若干遍。所谓一遍处理,就是自底向上检查一遍这个序列,并时刻注意两个相邻的元素的顺序是否正确。如果发现两个相邻元素的顺序不对,即“轻”的元素在下面,就交换它们的位置。显然,处理一遍之后,“**轻”的元素就浮到了**高位置;处理二遍之后,“次轻”的元素就浮到了次高位置。在作第二遍处理时,由于**高位置上的元素已是“**轻”元素,所以不必检查。一般地,第i遍处理时,不必检查第i高位置以上的元素,因为经过前面i-1遍的处理,它们已正确地排好序。冒泡排序是稳定的。算法时间复杂度是O(n ^2)。
class EbullitionSorter
{
public void Sort(int[] arr)
{
int i,j,temp;
bool done=false;
j=1;
while((j<arr.Length)&&(!done)) //判断长度
{
done=true;
for(i=0;i<arr.Length-j;i )
{
if(arr[i]>arr[i 1])
{
done=false;
temp=arr[i];
arr[i]=arr[i 1]; //交换数据
}
}
j ;
}
}
}这里写代码片
快速排序 快速排序是对冒泡排序的一种本质改进。它的基本思想是**一趟扫描后,使得排序序列的长度能大幅度地减少。在冒泡排序中,一次扫描只能确保**大数值的数移到正确位置,而待排序序列的长度可能只减少1。快速排序**一趟扫描,就能确保某个数(以它为基准点吧)的左边各数都比它小,右边各数都比它大。然后又用同样的方法处理它左右两边的数,直到基准点的左右只有一个元素为止。 快速排序是不稳定的。**理想情况算法时间复杂度O(nlog2n),**坏O(n ^2)。
class QuickSorter
{
private void swap(ref int l,ref int r)
{
int temp;
temp=l;
l=r;
r=temp;
}
public void Sor(int[] list,int low,int high)
{
int pivot; //存储分支点
int l,r;
int mid;
if(high<=low)
return;
else if(high==low 1)
{
if(list[low]>list[high])
swap(ref list[low],ref list[high]);
return;
}
mid=(low high)>>1;
pivot=list[mid];
swap(ref list[low],ref list[mid]);
l=low 1;
r=high;
do
{
while(l<=r&&list[l]pivot)
l ;
while(list[r]>=pivot)
r--;
if(l<r)
swap(ref list[l],ref list[r]);
}while(l<r);
list[low]=list[r];
list[r]=pivot;
if(low 1<r)
Sort(list,low,r-1);
if(r 1<high)
Sort(list,r 1,high);
}
}
插入排序 插入排序的基本思想是,经过i-1遍处理后,L[1..i-1]己排好序。第i遍处理仅将L[i]插入L[1..i-1]的适当位置,使得L[1..i]又是排好序的序列。要达到这个目的,我们可以用顺序比较的方法。首先比较L[i]和L[i-1],如果L[i-1]≤ L[i],则L[1..i]已排好序,第i遍处理就结束了;否则交换L[i]与L[i-1]的位置,继续比较L[i-1]和L[i-2],直到找到某一个位置j(1≤j≤i-1),使得L[j] ≤L[j 1]时为止。直接插入排序是稳定的。算法时间复杂度是O(n ^2) 。
public class InsertionSorter
{
public void Sort(int[] arr)
{
for(int i=1;i<arr.Lenngth;i )
{
int t=arr[i];
int j=i;
while((j>0)&&(arr[j-1]>t))
{
arr[j]=arr[j-1]; //交换顺序
--j;
}
arr[j]=t;
}
}
}这里写代码片
希尔排序 希尔排序基本思想: 先取一个小于n的整数d1作为**个增量,把文件的全部记录分成d1个组。所有距离为dl的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2
public class ShellSorter
{
public void Sort(int[] arr)
{
int inc;
for(int=1;inc<=arr.Length/9;inc=38inc 1);
for(;inc>0;inc/=3)
{
for(int i=inc 1;i<=arr.Length;i =inc)
{
int t=arr[i-1];
int j=i;
while(j>inc)&&(arr[j-inc-1]>t)
{
arr[j-1]=arr[j-inc-1]; //交换数据
j-=inc;
}
arr[j-1]=t;
}
}
}
}
归并排序 设有两个有序(升序)序列存储在同一数组中相邻的位置上,不妨设为A[l..m],A[m 1..h],将它们归并为一个有序数列,并存储在A[l..h]。
其时间复杂度无论是在**好情况下还是在**坏情况下均是O(nlog2n)。
int[] Sort(int[] data)
{
//取数组中间下标
int middle=data.Length/2;
//初始化临时数组left,right,并定义result作为**终有序数组
int[] left=new int[middle],right=new int[middle],result=new int[data.Length];
if(data.Length%2!=0) //若数组元素有奇数个,重新初始化右临时数组
{
right=new int[middle 1];
}
if(data.Length<=1) //只剩下1或0个元素,返回,不排序
{
return data;
}
int i=0,j=0;
foreach(int x,int data) //开始排序
{
if(i<middle) //填充左数组
{
left[i]=x;
i ;
}
else //填充右数组
{
right[j]=x;
j ;
}
}
left=Sort(left); //递归左数组
right=Sort(right); //递归右数组
result=Merge(left,right); //开始排序
return result;
int[] Merge(int[]a,int[]b)
{
//定义结果数组,用来存储**终结果
int[] result=new int[a.Length b.Length];
int i=0;j=0;k=0;
while(i<a.Length&&j<b.Length)
{
if(a[i]<b[j]) //左数组中元素小于右数组中元素
{
result[k ]=a[i ]; //将小的那个放到结果数组
}
else //左数组中元素大于右数组中元素
{
result[k ]=b[j ]; //将小的那个放到结果数组
}
}
while(i<a.Length) //这里其实还有左元素,但没有右元素
{
result[k ]=a[i ];
}
while(j<b.Length) //有右元素,无左元素
{
result[k ]=b[j ];
}
return result; //返回结果数组
}
}
基数排序 基数排序法又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的比较性排序法。
public int[] RadixSort(int[] ArrayToSort, int digit)
{
//low to high digit
for (int k = 1; k <= digit; k )
{
//temp array to store the sort result inside digit
int[] tmpArray = new int[ArrayToSort.Length];
//temp array for countingsort
int[] tmpCountingSortArray = new int[10]{0,0,0,0,0,0,0,0,0,0};
//CountingSort
for (int i = 0; i < ArrayToSort.Length; i )
{
//split the specified digit from the element
int tmpSplitDigit = ArrayToSort[i]/(int)Math.Pow(10,k-1) - (ArrayToSort[i]/(int)Math.Pow(10,k))*10;
tmpCountingSortArray[tmpSplitDigit] = 1;
}
for (int m = 1; m < 10; m )
{
tmpCountingSortArray[m] = tmpCountingSortArray[m - 1];
}
//output the value to result
for (int n = ArrayToSort.Length - 1; n >= 0; n–)
{
int tmpSplitDigit = ArrayToSort[n] / (int)Math.Pow(10,k – 1) – (ArrayToSort[n]/(int)Math.Pow(10,k)) * 10;
tmpArray[tmpCountingSortArray[tmpSplitDigit]-1] = ArrayToSort[n];
tmpCountingSortArray[tmpSplitDigit] -= 1;
}
//copy the digit-inside sort result to source array
for (int p = 0; p < ArrayToSort.Length; p )
{
ArrayToSort[p] = tmpArray[p];
}
}
return ArrayToSort;
}
记数排序 数排序, 基数排序, 桶排序等非比较排序算法,平均时间复杂度都是O(n). 这些排序因为其待排序元素本身就含有了定位特征,因而不需要比较就可以确定其前后位置,从而可以突破比较排序算法时间复杂度O(nlgn)的理论下限.
计数排序是**简单的特例,它要 求待排序元素是位于0到k之间的正整数 , 因而它是很特殊的情况,基本上没有特别的应用价值; 但是另一方面, 它又是基数排序的基础,或者说是一部分,所以简单的描述一下:
输入数组 A : 元素特征是 0-k的正整数,可以有重复值;
输出数组 B : 输出A的一个非减序列
中间数组 C : 大小是k, 它的i( 0<= i <= k)索引位置存储的是A元素集合中值是k的元素的个数有关.
算法的基本思想是:
统计A中元素的值的集合, 以A中元素的值为索引, 将值的个数填写到中间数组C的对应处.
对C从头开始自累加, 这样C中存储的就是, 当输入数组A中的值为当前索引时, 它前面的元素数量(包含重复元素).
将C依次输出到输出数组B中.
///
/// counting sort
/// ///input array ///the value arrange in input array ///
public int[] CountingSort(int[] arrayA, int arrange)
{
//array to store the sorted result,
//size is the same with input array.
int[] arrayResult = new int[arrayA.Length];
//array to store the direct value in sorting process
//include index 0;
//size is arrange 1;
int[] arrayTemp = new int[arrange 1];
//clear up the temp array
for(int i = 0; i <= arrange; i )
{
arrayTemp[i] = 0;
}
//now temp array stores the count of value equal
for(int j = 0; j < arrayA.Length; j )
{
arrayTemp[arrayA[j]] = 1;
}
//now temp array stores the count of value lower and equal
for(int k = 1; k <= arrange; k )
{
arrayTemp[k] = arrayTemp[k - 1];
}
//output the value to result
for (int m = arrayA.Length-1; m >= 0; m–)
{
arrayResult[arrayTemp[arrayA[m]] – 1] = arrayA[m];
arrayTemp[arrayA[m]] -= 1;
}
return arrayResult;
}
根堆排序 堆排序是一种树形选择排序,在排序过程中,将A[n]看成是完全二叉树的顺序存储结构,利用完全二叉树中双亲结点和孩子结点之间的内在关系来选择**小的元素。 算法时间复杂度O(nlog n)。
private void HeapSort(ref double[] dblArray)
{
for (int i = dblArray.Length – 1; i >= 0; i–)
{
if (2 * i 1 < dblArray.Length)
{
int MinChildrenIndex = 2 * i 1;
//比较左子树和右子树,记录**小值的Index
if (2 * i 2 < dblArray.Length)
{
if (dblArray[2 * i 1] > dblArray[2 * i 2])
MinChildrenIndex = 2 * i 2;
}
if (dblArray[i] > dblArray[MinChildrenIndex])
{
ExchageValue(ref dblArray[i], ref dblArray[MinChildrenIndex]);
NodeSort(ref dblArray, MinChildrenIndex);
}
}
}
}
///
/// 节点排序
/// /// /// private void NodeSort(ref double[] dblArray, int StartIndex)
{
while (2 * StartIndex 1 < dblArray.Length)
{
int MinChildrenIndex = 2 * StartIndex 1;
if (2 * StartIndex 2 < dblArray.Length)
{
if (dblArray[2 * StartIndex 1] > dblArray[2 * StartIndex 2])
{
MinChildrenIndex = 2 * StartIndex 2;
}
}
if (dblArray[StartIndex] > dblArray[MinChildrenIndex])
{
ExchageValue(ref dblArray[StartIndex], ref dblArray[MinChildrenIndex]);
StartIndex = MinChildrenIndex;
}
}
}
///
/// 交换值
/// /// /// private void ExchageValue(ref double A, ref double B)
{
double Temp = A;
A = B;
B = Temp;
}
相关推荐:
苏州JAVA培训 苏州JAVA培训班 苏州JAVA培训机构