java中java所有的排序算法法有哪些

java算法面试题:排序都有哪几种方法_百度知道
java算法面试题:排序都有哪几种方法
我有更好的答案
&);}selectSort(sort);S &);}System.out.println();quickSort(int[] sort = new int[10];for (int i = 0一、冒泡排序[java] view plain copypackage sort, 89;/*** 选择排序* 每一趟从待排序的数据元素中选出最小(或最大)的一个元素,* 顺序放在已排好序的数列的最后,具有稳定性* 时间复杂度为O(n^2)* 不及堆排序,快速排序O(nlogn,底数为2)* @author liangge**&#47.out, 其中一部分的所有数据都比另外一部分的所有数据都要小,* 然后再按此方法对这两部分数据分别进行快速排序.print(&sort[i]){int temp = sort[j];排序前的数组为&);for (int i : sort) {System.out, 0, sort.length - 1);S).import java.System.out.print(&排序前的数组为:&);for (int data , 12;*** 依次比较相邻的两个数,将小数放在前面,大数放在后面* 冒泡排序, 整个排序过程可以递归进行;排序后的数组为;}buddleSort(sort);).*** 快速排序 通过一趟排序将要排序的数据分割成独立的两部分.j++){if(sort[j]& i & 10; i++) {sort[i] = ran.out.println()、选择排序[java] view plain copypackage sort.j&sort:&for (int data : sort) {System.length-i;j++){if(sort[j]&);private static void selectSort(int[] sort){for(int i =0;for(int i = 0 ; i &lt.print(&}}/*** 选择排序* @param sort*&#47,以此达到整个数据变成有序序列。* @author liangge**/public class Main {public static void main(String[] args) {int[] sort = { 54;i&sort: sort) {System.out.print(i + & &}}/*** 快速排序* @param sort 要排序的数组* @param start 排序的开始座标* @param end 排序的结束座标*/public static void quickSort(int[] sort, int start, int end) {// 设置关键数据key为要排序数组的第一个元素,// 即第一趟排序后,key右边的数全部比key大,key左边的数全部比key小int key = sort[start];// 设置数组左边的索引,往右移动判断比key大的数int i =// 设置数组右边的索引,往左移动判断比key小的数int j =// 如果左边索引比右边索引小,则还有数据没有排序while (i & j) {while (sort[j] & key && j & start) {j--;}while (sort[i] & key && i & end) {i++;}if (i & j) {int temp = sort[i];sort[i] = sort[j];sort[j] =}}// 如果左边索引比右边索引要大,说明第一次排序完成,将sort[j]与key对换,// 即保持了key左边的数比key小,key右边的数比key大if (i & j) {int temp = sort[j];sort[j] = sort[start];sort[start] =}//递归调用if (j & start && j & end) {quickSort(sort, start, j - 1);quickSort(sort, j + 1, end);}}}
[java] view plain copy/*** 快速排序** @param a* @param low* @param high*
voidTest*/public static void kuaisuSort(int[] a, int low, int high){if (low &= high){}if ((high - low) == 1){if (a[low] & a[high]){swap(a, low, high);}}int key = a[low];int left = low + 1;int right =while (left & right){while (left & right && left &= high)// 左边向右{if (a[left] &= key){}left++;}while (right &= left && right & low){if (a[right] &= key){}right--;}if (left & right){swap(a, left, right);}}swap(a, low, right);kuaisuSort(a, low, right);kuaisuSort(a, right + 1, high);}
四、插入排序[java] view plain copypackage sort./*** 直接插入排序* 将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据* 算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。*/import java.util.Rpublic class DirectMain {public static void main(String[] args) {Random ran = new Random();int[] sort = new int[10];for (int i = 0; i & 10; i++) {sort[i] = ran.nextInt(50);}System.out.print(&排序前的数组为&);for (int i : sort) {System.out.print(i + & &);}directInsertSort(sort);System.out.println();System.out.print(&排序后的数组为&);for (int i : sort) {System.out.print(i + & &);}}/*** 直接插入排序** @param sort*/private static void directInsertSort(int[] sort) {for (int i = 1; i & sort. i++) {int index = i - 1;int temp = sort[i];while (index &= 0 && sort[index] & temp) {sort[index + 1] = sort[index];index--;}sort[index + 1] =}}}
顺便添加一份,差不多的[java] view plain copypublic static void charuSort(int[] a){int len = a.for (int i = 1; i & i++){int temp = a[i];for (j = j & 0; j--)//遍历i之前的数字{//如果之前的数字大于后面的数字,则把大的值赋到后面if (a[j - 1] & temp){a[j] = a[j - 1];} else{}}a[j] =}}
把上面整合起来的一份写法:[java] view plain copy/*** 插入排序:**/public class InsertSort {public void sort(int[] data) {for (int i = 1; i & data. i++) {for (int j = (j & 0) && (data[j] & data[j - 1]); j--) {swap(data, j, j - 1);}}}private void swap(int[] data, int i, int j) {int temp = data[i];data[i] = data[j];data[j] =}}
五、顺便贴个二分搜索法[java] view plain copypackage search.public class Main {public static void main(String[] args) {int[] sort = {1,2,3,4,5,6,7,8,9,10};int mask = binarySearch(sort,6);System.out.println(mask);}/*** 二分搜索法,返回座标,不存在返回-1* @param sort* @return*/private static int binarySearch(int[] sort,int data){if(data&sort[0] || data&sort[sort.length-1]){return -1;}int begin = 0;int end = sort.int mid = (begin+end)/2;while(begin &= end){mid = (begin+end)/2;if(data & sort[mid]){begin = mid + 1;}else if(data & sort[mid]){end = mid - 1;}else{}}return -1;}}, 20 }.length-1;i++){for(int j = i+1.out.util.Random, 33;排序后的数组为&);for(int i , 68;for (int i .print(i + &sort[j] =}}}}}
二: sort){System、快速排序[java] view plain copypackage sort./sort[j+1]){int temp = sort[j+1]; 10 ; i++){sort[i] = ran.nextInt(50);}System.out.print(&排序前的数组为&quot, 66, 31;i& &);}}&#47.print(i+&quot,直到全部待排序的数据元素排完。* 选择排序是不稳定的排序方法。* @author liangge**/public class Main {public static void main(String[] args) {Random ran = new Random().sort[i] =}}}}}
三;);System.out.print(&排序后的数组为&sort[j] = sort[i].sort[j+1] = sort[j].print(data + & &}Sj&sort.nextInt(50).i++){for(int j=0;System.out.println();S);for(int i : sort){System.out.print(i+& &public class Main {public static void main(String[] args) {Random ran = new Random();int[] sort = new int[10]: sort) {System.out.print(data + &quot.print(&*** 冒泡排序* @param sort*/private static void buddleSort(int[] sort){for(int i=1;).R&#47
为您推荐:
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
标签:至少1个,最多5个
前面介绍了七大算法的思想与实现步骤,下面来做一个归总。
平均复杂度
最坏复杂度
最好复杂度
直接选择排序
直接插入排序
O(nlogn)~O(n^2)
O(logn)~O(n)
直接选择排序
,整体思想是将数据分成两个区域,有序区与无序区。排序的时候是每次从无序区中选择出最小的数,然后插入到有序区中的最末尾,从而形成更大的有序区。直到无序区中的数为零,结束排序。
假设排序数组为a[0...n-1];
首先有序区中的个数为0,令i = 0。从无序区中选择最小的数,加入到有序区a[i]中。使得有序区为a[0..i],无序区为a[i...n-1]
完成后 i++ ,然后继续前面的步骤,直到 i = n-1 为止。使得全部数都在有序区中。
主要是相邻的两个数两两进行比较,拿从小到大说明,进行冒泡排序后会将大的数沉到底部,将小得数浮到顶部。所以冒泡说法由此得名。
以从小到大为例,排序数组大小为n。
第N = 0趟排序开始都从a[0]开始与其下面的相邻的数进行比较,如果大于相邻的数则交换他们的位置。
继续与下一个相邻的数进行比较,大于相邻的就交换,最后进行比较n-1次后,第N = 0趟排序结束,最大的数就在数组的a[n-1]处。
重复前面的步骤,直到 N = n-1,排序结束。
直接插入排序
的基本思想是:将需要排序的关键数与前面已经排好序的数据从后往前进行比较,使其插入到合适的位置。
排序数组为a[0...n]
将a[0]作为起始数据,从a[1]开始作为关键字向前进行比较,若小于前面所遇到的比较数,则交换两个比较数的位置,否则直接进行下一个关键字的比较。
重复前面的步骤,直到将a[n]作为关键字进行比较。比较完以后则排序结束。
是一个效率相对较高的排序算法,它采用的是分治的思想,将待排序的序列分成若干组,保证每组都有序,然后再进行合并排序,最终使整个序列有序。
将待排序的序列采用分治思想将其划分成若干组,使其有序,其中可采用递归进行划分。
将有序的组分别进行归并操作,其中借助一个辅助数组,将左右划分的有序组从头开始进行比较,将较小的数加入到辅助数组中,且较小的所在有序数组向后自增,再与原来比较的数进行比较。
重复上面2的步骤,直到所有数据比较完毕,或者将还有剩余数未比较的有序数据直接按原有的顺序加入到辅助数组中,最后将已经排好序的辅助数组加入到原有数组的相应位置。
重复上面的2、3步骤,直到所有的左右划分归并完毕。
的主要思想是:将一个待排序序列分成两个部分,以其中的一个数据作为分界线,其中一部分小于这个分界线的数据,另一部分大于这个分界线的数据。因为采用递归的思想,再对这两个序列进行快速排序,直到所以的数据都是有序的。
假设待排序的数组为a[0...n-1]
一般都将第一个数a[i] (i = 0) 作为关键数,即快速排序的分界数。先从数组的后面开始即初值j = n-1,逐个向前进行遍历与选的的关键数进行比较(j--),若大于等于关键数则继续遍历,否则将其与关键数所在的位置进行交换,并停止遍历且i++记录此时的i、j。
停止前面的遍历,再从数组的第i个位置开始向后进行遍历,逐个与关键数进行比较(i++),若小于等于关键数则继续遍历,否则将其与关键数所在的位置进行交换,并停止遍历且j--记录此时的i、j。
重复上面的步骤,直到i==j就结束本次快速排序。
此时已经将其按关键数分成两个部分,再重复前面的步骤,对划分的部分进行快速排序,直到划分的组中的数据个数为1即此时所有数据有序。
是记录增量来进行分组,再对分组内部进行,随着增量的不断减小,直到增量减小到1时,即每个分组中的数据量为1,此时排序结束。
设待排序的数组为a[0...n-1]
一般开始取增量数d=n/2。从a[0]~a[d-1]将数组中数据之间的间隔为增量数d的倍数归为相同组。
依次对每组中的数据进行,使其有序。
再增量数d=d/2,重复上面的步骤,直到d=1为止。
是采用树的形式的数据结构来进行排序的,其中每一个堆都是完全二叉树。堆排序分为大根堆与小根堆,大根堆(小根堆)表示在完全二叉树中,所用的非叶子节点都大于等于(小于等于)他们左右子节点(存在)。所以堆的顶点不是最大数就是最小数。这样的话我们就可以借助这种性质,每次都取出大根堆(小根堆)的顶点数,形成有序序列。
首先生成小根堆或大根堆,这里以小根堆为例。我们可以将每一个非叶子节点都看做是一个最小的完全二叉树,将他们都生成小根堆,从最后一个非叶子节点开始,把其当做是根节点,逐步向前进行创建小根堆。
然后就是取出形成的小根堆得顶点值,将其与堆中第N(N=n)个节点互换位置,即a[N-1]。
此时小根堆被破坏,再重新生产小根堆N--,但此时要生成的数的范围为a[0...N-1]。
重复上面的步骤2、3,直到N=1,即a[0],排序结束。
如有不足之处欢迎指出,全部代码已经放到github上,有需要的可以下载。
github地址:
4 收藏&&|&&14
你可能感兴趣的文章
1 收藏,1.7k
14 收藏,2.3k
17 收藏,811
本作品采用 署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可
分享到微博?
我要该,理由是:
在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。45被浏览8,836分享邀请回答53 条评论分享收藏感谢收起112 条评论分享收藏感谢收起写回答博客分类:
&&&& java中常用的四种排序方法: 快速排序、冒泡排序、选择排序、插入排序。
&&&& 当然 程序中最简单的使用就是:快速排序和冒泡排序,插入排序的使用更具有技巧性,选择排序则过于复杂,冗杂的代码不利于程序的使用和软件的测试。
&&&& 快速排序主要是运用了Arrays中的一个方法Arrays.sort()实现。
&&&& 冒泡法则是利用遍历数组进行比较,通过不断的比较将最小值或者最大值一个一个的遍历出来。
&&&& 选择排序法是将数组的第一个数据作为最大或者最小的值,然后通过比较循环,输出有序的数组。
&&&& 插入排序是选择一个数组中的数据,通过不断的插入比较最后进行排序。
&&&&& 1.利用Arrays带有的排序方法快速排序
import java.util.A
public class Test{
public static void main(String[] args){
int[] a={5,4,2,4,9,1};
Arrays.sort(a);
//进行排序
for(int i: a){
System.out.print(i);
&&&&& 2.冒泡排序算法&
public static int[] bubbleSort(int[] args){
//冒泡排序算法
for(int i=0;i&args.length-1;i++){
for(int j=i+1;j&args.j++){
if (args[i]&args[j]){
int temp=args[i];
args[i]=args[j];
&&&&&&& 3.选择排序算法&&
public static int[] selectSort(int[] args){
//选择排序算法
for (int i=0;i&args.length-1 i++ ){
int min=i;
for (int j=i+1;j&args.length j++ ){
if (args[min]&args[j]){
if (min!=i){
int temp=args[i];
args[i]=args[min];
args[min]=
&&&&&& 4.插入排序算法
public static int[] insertSort(int[] args){//
for(int i=1;i&args.i++){
for(int j=i;j&0;j--){
if (args[j]&args[j-1]){
int temp=args[j-1];
args[j-1]=args[j];
&&& 以上就是java中的四种排序方法。
&&& 不同的方法效率不一样,下面是不同的算法的比较和数据交换时的大O表示。
&&& 冒泡排序:比较O(N2) 数据交换O(N2)&
&&& 选择排序:比较O(N2) 数据交换O(N)&
美君jiayou
浏览: 3327 次
来自: 上海
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'一遍记住 Java 常用的八种排序算法与代码实现10 months ago2.希尔排序对于直接插入排序问题,数据量巨大时。将数的个数设为n,取奇数k=n/2,将下标差值为k的书分为一组,构成有序序列。再取k=k/2 ,将下标差值为k的书分为一组,构成有序序列。重复第二步,直到k=1执行简单插入排序。如何写成代码:首先确定分的组数。然后对组中元素进行插入排序。然后将length/2,重复1,2步,直到length=0为止。代码实现如下:public
void sheelSort(int[] a){
while (d!=0) {
for (int x = 0; x & x++) {//分的组数
for (int i = x + i & a. i += d) {//组中的元素,从第二个数开始
int j = i -//j为有序序列最后一位的位数
int temp = a[i];//要插入的元素
for (; j &= 0 && temp & a[j]; j -= d) {//从后往前遍历。
a[j + d] = a[j];//向后移动d位
a[j + d] =
3.简单选择排序常用于取序列中最大最小的几个数时。(如果每次比较都交换,那么就是交换排序;如果每次比较完一个循环再交换,就是简单选择排序。)遍历整个序列,将最小的数放在最前面。遍历剩下的序列,将最小的数放在最前面。重复第二步,直到只剩下一个数。如何写成代码:首先确定循环次数,并且记住当前数字和当前位置。将当前位置后面所有的数与当前数字进行对比,小数赋值给key,并记住小数的位置。比对完成后,将最小的值与第一个数的值交换。重复2、3步。代码实现如下:
public void selectSort(int[] a) {
int length = a.
for (int i = 0; i & i++) {//循环次数
int key = a[i];
int position=i;
for (int j = i + 1; j & j++) {//选出最小的值和位置
if (a[j] & key) {
key = a[j];
position =
a[position]=a[i];//交换位置
4.堆排序对简单选择排序的优化。将序列构建成大顶堆。将根节点与最后一个节点交换,然后断开最后一个节点。重复第一、二步,直到所有节点断开。代码实现如下:public
void heapSort(int[] a){
System.out.println("开始排序");
int arrayLength=a.
//循环建堆
for(int i=0;i&arrayLength-1;i++){
buildMaxHeap(a,arrayLength-1-i);
//交换堆顶和最后一个元素
swap(a,0,arrayLength-1-i);
System.out.println(Arrays.toString(a));
void swap(int[] data, int i, int j) {
// TODO Auto-generated method stub
int tmp=data[i];
data[i]=data[j];
//对data数组从0到lastIndex建大顶堆
private void buildMaxHeap(int[] data, int lastIndex) {
// TODO Auto-generated method stub
//从lastIndex处节点(最后一个节点)的父节点开始
for(int i=(lastIndex-1)/2;i&=0;i--){
//k保存正在判断的节点
//如果当前k节点的子节点存在
while(k*2+1&=lastIndex){
//k节点的左子节点的索引
int biggerIndex=2*k+1;
//如果biggerIndex小于lastIndex,即biggerIndex+1代表的k节点的右子节点存在
if(biggerIndex&lastIndex){
//若果右子节点的值较大
if(data[biggerIndex]&data[biggerIndex+1]){
//biggerIndex总是记录较大子节点的索引
biggerIndex++;
//如果k节点的值小于其较大的子节点的值
if(data[k]&data[biggerIndex]){
//交换他们
swap(data,k,biggerIndex);
//将biggerIndex赋予k,开始while循环的下一次循环,重新保证k节点的值大于其左右子节点的值
5.冒泡排序一般不用。将序列中所有元素两两比较,将最大的放在最后面。将剩余序列中所有元素两两比较,将最大的放在最后面。重复第二步,直到只剩下一个数。如何写成代码:设置循环次数。设置开始比较的位数,和结束的位数。两两比较,将最小的放到前面去。重复2、3步,直到循环次数完毕。代码实现如下:public void bubbleSort(int[] a){
int length=a.
for(int i=0;i&a.i++){
for(int j=0;j&a.length-i-1;j++){
if(a[j]&a[j+1]){
temp=a[j];
a[j]=a[j+1];
6.快速排序要求时间最快时。选择第一个数为p,小于p的数放在左边,大于p的数放在右边。递归的将p左边和右边的数都按照第一步进行,直到不能递归。代码实现如下:public static void quickSort(int[] numbers, int start, int end) {
if (start & end) {
int base = numbers[start]; // 选定的基准值(第一个数值作为基准值)
// 记录临时中间值
int i = start, j =
while ((numbers[i] & base) && (i & end))
while ((numbers[j] & base) && (j & start))
if (i &= j) {
temp = numbers[i];
numbers[i] = numbers[j];
numbers[j] =
} while (i &= j);
if (start & j)
quickSort(numbers, start, j);
if (end & i)
quickSort(numbers, i, end);
7.归并排序速度仅次于快排,内存少的时候使用,可以进行并行计算的时候使用。选择相邻两个数组成一个有序序列。选择相邻的两个有序序列组成一个有序序列。重复第二步,直到全部组成一个有序序列。代码实现如下:public static void mergeSort(int[] numbers, int left, int right) {
int t = 1;// 每组元素个数
int size = right - left + 1;
while (t & size) {
int s =// 本次循环每组元素个数
while (i + (t - 1) & size) {
merge(numbers, i, i + (s - 1), i + (t - 1));
if (i + (s - 1) & right)
merge(numbers, i, i + (s - 1), right);
private static void merge(int[] data, int p, int q, int r) {
int[] B = new int[data.length];
int t = q + 1;
while (s &= q && t &= r) {
if (data[s] &= data[t]) {
B[k] = data[s];
B[k] = data[t];
if (s == q + 1)
B[k++] = data[t++];
B[k++] = data[s++];
for (int i = i &= i++)
data[i] = B[i];
8.基数排序用于大量数,很长的数进行排序时。将所有的数的个位数取出,按照个位数进行排序,构成一个序列。将新构成的所有的数的十位数取出,按照十位数进行排序,构成一个序列。代码实现如下:public void sort(int[] array) {
//首先确定排序的趟数;
int max = array[0];
for (int i = 1; i & array. i++) {
if (array[i] & max) {
max = array[i];
int time = 0;
//判断位数;
while (max & 0) {
max /= 10;
//建立10个队列;
List&ArrayList& queue = new ArrayList&ArrayList&();
for (int i = 0; i & 10; i++) {
ArrayList&Integer& queue1 = new ArrayList&Integer&();
queue.add(queue1);
//进行time次分配和收集;
for (int i = 0; i & i++) {
//分配数组元素;
for (int j = 0; j & array. j++) {
//得到数字的第time+1位数;
int x = array[j] % (int) Math.pow(10, i + 1) / (int) Math.pow(10, i);
ArrayList&Integer& queue2 = queue.get(x);
queue2.add(array[j]);
queue.set(x, queue2);
int count = 0;//元素计数器;
//收集队列元素;
for (int k = 0; k & 10; k++) {
while (queue.get(k).size() & 0) {
ArrayList&Integer& queue3 = queue.get(k);
array[count] = queue3.get(0);
queue3.remove(0);
439收藏分享举报文章被以下专栏收录不定期更新互联网技术文章、产品研究、工具干货。{&debug&:false,&apiRoot&:&&,&paySDK&:&https:\u002F\u002Fpay.zhihu.com\u002Fapi\u002Fjs&,&wechatConfigAPI&:&\u002Fapi\u002Fwechat\u002Fjssdkconfig&,&name&:&production&,&instance&:&column&,&tokens&:{&X-XSRF-TOKEN&:null,&X-UDID&:null,&Authorization&:&oauth c3cef7c66aa9e6a1e3160e20&}}{&database&:{&Post&:{&&:{&isPending&:false,&contributes&:[{&sourceColumn&:{&lastUpdated&:,&description&:&不定期更新互联网技术知识点、总结归纳、整理开发技巧,相互学习,共同进步!\n\n不定期更新移动端的产品研究、见解、归纳。 \n\n分享当前主流的界面设计尺寸、主流平台的设计规范、主流APP的设计规范。 \n设计类干货资源整合,设计类技能教程等。&,&permission&:&COLUMN_PUBLIC&,&memberId&:,&contributePermission&:&COLUMN_PUBLIC&,&translatedCommentPermission&:&all&,&canManage&:true,&intro&:&不定期更新互联网技术文章、产品研究、工具干货。&,&urlToken&:&lishichao&,&id&:14044,&imagePath&:&v2-05a3efacf81bef39a0f44.jpg&,&slug&:&lishichao&,&applyReason&:&0&,&name&:&互联网笔记&,&title&:&互联网笔记&,&url&:&https:\u002F\u002Fzhuanlan.zhihu.com\u002Flishichao&,&commentPermission&:&COLUMN_ALL_CAN_COMMENT&,&canPost&:true,&created&:,&state&:&COLUMN_NORMAL&,&followers&:10544,&avatar&:{&id&:&v2-05a3efacf81bef39a0f44&,&template&:&https:\u002F\u002Fpic1.zhimg.com\u002F{id}_{size}.jpg&},&activateAuthorRequested&:false,&following&:false,&imageUrl&:&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-05a3efacf81bef39a0f44_l.jpg&,&articlesCount&:427},&state&:&accepted&,&targetPost&:{&titleImage&:&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-59b7417aaba40d4b6bf9680_r.jpg&,&lastUpdated&:,&imagePath&:&v2-59b7417aaba40d4b6bf9680.png&,&permission&:&ARTICLE_PUBLIC&,&topics&:[,3123],&summary&:&原文链接:\u003Ca href=\&http:\u002F\u002Fwww.jianshu.com\u002Fp\u002F5e\& data-editable=\&true\& data-title=\&一遍记住Java常用的八种排序算法与代码实现\&\u003E一遍记住Java常用的八种排序算法与代码实现\u003C\u002Fa\u003E作者:breakingsword1.直接插入排序经常碰到这样一类排序问题:把新的数据插入到已经排好的数据列中。将第一个数和第二个数排序,然后构成一个有序序列将第三个数插入进去,构成一个新的有序序列。对第四…&,&copyPermission&:&ARTICLE_COPYABLE&,&translatedCommentPermission&:&all&,&likes&:0,&origAuthorId&:0,&publishedTime&:&T19:20:33+08:00&,&sourceUrl&:&&,&urlToken&:,&id&:2989457,&withContent&:false,&slug&:,&bigTitleImage&:false,&title&:&一遍记住 Java 常用的八种排序算法与代码实现&,&url&:&\u002Fp\u002F&,&commentPermission&:&ARTICLE_ALL_CAN_COMMENT&,&snapshotUrl&:&&,&created&:,&comments&:0,&columnId&:14044,&content&:&&,&parentId&:0,&state&:&ARTICLE_PUBLISHED&,&imageUrl&:&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-59b7417aaba40d4b6bf9680_r.jpg&,&author&:{&bio&:&有情怀→渴望做出一款颠覆性App的代码工作者&,&isFollowing&:false,&hash&:&fd983d762fb8&,&uid&:528000,&isOrg&:false,&slug&:&amin706&,&isFollowed&:false,&description&:&
码力全开工作室官网 → http:\u002F\u002Fmaliquankai.com\n
奇点日报创始人,追求产品交互和设计的产品经理一枚 \n
高逼格程序员技术分享平台 → http:\u002F\u002Fwww.qidianlife.com\n『心动屋』→ 发现令您心动的好物\n『壹日程』→ 专注任务管理和待办计划提醒
\n『拾光记』→ 拾起你走过的时光\n『口袋密码』→ 安全简洁的账号管家\n『破壳日』→ 精美的生日 · 节日 · 纪念日礼物提醒工具 \n
邮箱 → &,&name&:&Larry&,&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002Famin706&,&avatar&:{&id&:&v2-a5db75ec863beb&,&template&:&https:\u002F\u002Fpic1.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},&memberId&:,&excerptTitle&:&&,&voteType&:&ARTICLE_VOTE_CLEAR&},&id&:653388}],&title&:&一遍记住 Java 常用的八种排序算法与代码实现&,&author&:&amin706&,&content&:&\u003Cblockquote\u003E\u003Cp\u003E原文链接:\u003Ca href=\&https:\u002F\u002Flink.zhihu.com\u002F?target=http%3A\u002F\u002Fwww.jianshu.com\u002Fp\u002F5e\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E一遍记住Java常用的八种排序算法与代码实现\u003C\u002Fa\u003E\u003C\u002Fp\u003E\u003Cp\u003E作者:breakingsword\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Ch1\u003E1.直接插入排序\u003C\u002Fh1\u003E\u003Cblockquote\u003E\u003Cp\u003E经常碰到这样一类排序问题:把新的数据插入到已经排好的数据列中。\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Col\u003E\u003Cli\u003E将第一个数和第二个数排序,然后构成一个有序序列\u003C\u002Fli\u003E\u003Cli\u003E将第三个数插入进去,构成一个新的有序序列。\u003C\u002Fli\u003E\u003Cli\u003E对第四个数、第五个数……直到最后一个数,重复第二步。\u003C\u002Fli\u003E\u003C\u002Fol\u003E\u003Cbr\u003E\u003Cp\u003E如何写写成代码:\u003C\u002Fp\u003E\u003Col\u003E\u003Cli\u003E首先设定插入次数,即循环次数,for(int i=1;i&i++),1个数的那次不用插入。\u003C\u002Fli\u003E\u003Cli\u003E设定插入数和得到已经排好序列的最后一个数的位数。insertNum和j=i-1。\u003C\u002Fli\u003E\u003Cli\u003E从最后一个数开始向前循环,如果插入数小于当前数,就将当前数向后移动一位。\u003C\u002Fli\u003E\u003Cli\u003E将当前数放置到空着的位置,即j+1。\u003C\u002Fli\u003E\u003C\u002Fol\u003E\u003Cp\u003E代码实现如下:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Epublic void insertSort(int[] a){\n
int length=a.\u002F\u002F数组长度,将这个提取出来是为了提高速度。\n
int insertN\u002F\u002F要插入的数\n
for(int i=1;i&i++){\u002F\u002F插入的次数\n
insertNum=a[i];\u002F\u002F要插入的数\n
int j=i-1;\u002F\u002F已经排序好的序列元素个数\n
while(j&=0&&a[j]&insertNum){\u002F\u002F序列从后到前循环,将大于insertNum的数向后移动一格\n
a[j+1]=a[j];\u002F\u002F元素移动一格\n
a[j+1]=insertN\u002F\u002F将需要插入的数放在要插入的位置。\n
}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Ch1\u003E2.希尔排序\u003C\u002Fh1\u003E\u003Cblockquote\u003E\u003Cp\u003E对于直接插入排序问题,数据量巨大时。\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Col\u003E\u003Cli\u003E将数的个数设为n,取奇数k=n\u002F2,将下标差值为k的书分为一组,构成有序序列。\u003C\u002Fli\u003E\u003Cli\u003E再取k=k\u002F2 ,将下标差值为k的书分为一组,构成有序序列。\u003C\u002Fli\u003E\u003Cli\u003E重复第二步,直到k=1执行简单插入排序。\u003C\u002Fli\u003E\u003C\u002Fol\u003E\u003Cbr\u003E\u003Cp\u003E如何写成代码:\u003C\u002Fp\u003E\u003Col\u003E\u003Cli\u003E首先确定分的组数。\u003C\u002Fli\u003E\u003Cli\u003E然后对组中元素进行插入排序。\u003C\u002Fli\u003E\u003Cli\u003E然后将length\u002F2,重复1,2步,直到length=0为止。\u003C\u002Fli\u003E\u003C\u002Fol\u003E\u003Cp\u003E代码实现如下:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Epublic
void sheelSort(int[] a){\n
while (d!=0) {\n
d=d\u002F2;\n
for (int x = 0; x & x++) {\u002F\u002F分的组数\n
for (int i = x + i & a. i += d) {\u002F\u002F组中的元素,从第二个数开始\n
int j = i -\u002F\u002Fj为有序序列最后一位的位数\n
int temp = a[i];\u002F\u002F要插入的元素\n
for (; j &= 0 && temp & a[j]; j -= d) {\u002F\u002F从后往前遍历。\n
a[j + d] = a[j];\u002F\u002F向后移动d位\n
a[j + d] =\n
}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Ch1\u003E3.简单选择排序\u003C\u002Fh1\u003E\u003Cblockquote\u003E\u003Cp\u003E常用于取序列中最大最小的几个数时。\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Cp\u003E(如果每次比较都交换,那么就是交换排序;如果每次比较完一个循环再交换,就是简单选择排序。)\u003C\u002Fp\u003E\u003Col\u003E\u003Cli\u003E遍历整个序列,将最小的数放在最前面。\u003C\u002Fli\u003E\u003Cli\u003E遍历剩下的序列,将最小的数放在最前面。\u003C\u002Fli\u003E\u003Cli\u003E重复第二步,直到只剩下一个数。\u003C\u002Fli\u003E\u003C\u002Fol\u003E\u003Cbr\u003E\u003Cp\u003E如何写成代码:\u003C\u002Fp\u003E\u003Col\u003E\u003Cli\u003E首先确定循环次数,并且记住当前数字和当前位置。\u003C\u002Fli\u003E\u003Cli\u003E将当前位置后面所有的数与当前数字进行对比,小数赋值给key,并记住小数的位置。\u003C\u002Fli\u003E\u003Cli\u003E比对完成后,将最小的值与第一个数的值交换。\u003C\u002Fli\u003E\u003Cli\u003E重复2、3步。\u003C\u002Fli\u003E\u003C\u002Fol\u003E\u003Cp\u003E代码实现如下:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E
public void selectSort(int[] a) {\n
int length = a.\n
for (int i = 0; i & i++) {\u002F\u002F循环次数\n
int key = a[i];\n
int position=i;\n
for (int j = i + 1; j & j++) {\u002F\u002F选出最小的值和位置\n
if (a[j] & key) {\n
key = a[j];\n
position =\n
a[position]=a[i];\u002F\u002F交换位置\n
}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Ch1\u003E4.堆排序\u003C\u002Fh1\u003E\u003Cblockquote\u003E\u003Cp\u003E对简单选择排序的优化。\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Col\u003E\u003Cli\u003E将序列构建成大顶堆。\u003C\u002Fli\u003E\u003Cli\u003E将根节点与最后一个节点交换,然后断开最后一个节点。\u003C\u002Fli\u003E\u003Cli\u003E重复第一、二步,直到所有节点断开。\u003C\u002Fli\u003E\u003C\u002Fol\u003E\u003Cbr\u003E\u003Cp\u003E代码实现如下:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Epublic
void heapSort(int[] a){\n
System.out.println(\&开始排序\&);\n
int arrayLength=a.\n
\u002F\u002F循环建堆
for(int i=0;i&arrayLength-1;i++){\n
\u002F\u002F建堆
buildMaxHeap(a,arrayLength-1-i);\n
\u002F\u002F交换堆顶和最后一个元素
swap(a,0,arrayLength-1-i);\n
System.out.println(Arrays.toString(a));\n
void swap(int[] data, int i, int j) {\n
\u002F\u002F TODO Auto-generated method stub
int tmp=data[i];\n
data[i]=data[j];\n
data[j]=\n
\u002F\u002F对data数组从0到lastIndex建大顶堆
private void buildMaxHeap(int[] data, int lastIndex) {\n
\u002F\u002F TODO Auto-generated method stub
\u002F\u002F从lastIndex处节点(最后一个节点)的父节点开始
for(int i=(lastIndex-1)\u002F2;i&=0;i--){\n
\u002F\u002Fk保存正在判断的节点
int k=i;\n
\u002F\u002F如果当前k节点的子节点存在
while(k*2+1&=lastIndex){\n
\u002F\u002Fk节点的左子节点的索引
int biggerIndex=2*k+1;\n
\u002F\u002F如果biggerIndex小于lastIndex,即biggerIndex+1代表的k节点的右子节点存在
if(biggerIndex&lastIndex){\n
\u002F\u002F若果右子节点的值较大
if(data[biggerIndex]&data[biggerIndex+1]){\n
\u002F\u002FbiggerIndex总是记录较大子节点的索引
biggerIndex++;\n
\u002F\u002F如果k节点的值小于其较大的子节点的值
if(data[k]&data[biggerIndex]){\n
\u002F\u002F交换他们
swap(data,k,biggerIndex);\n
\u002F\u002F将biggerIndex赋予k,开始while循环的下一次循环,重新保证k节点的值大于其左右子节点的值
k=biggerI\n
}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Ch1\u003E5.冒泡排序\u003C\u002Fh1\u003E\u003Cblockquote\u003E\u003Cp\u003E一般不用。\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Col\u003E\u003Cli\u003E将序列中所有元素两两比较,将最大的放在最后面。\u003C\u002Fli\u003E\u003Cli\u003E将剩余序列中所有元素两两比较,将最大的放在最后面。\u003C\u002Fli\u003E\u003Cli\u003E重复第二步,直到只剩下一个数。\u003C\u002Fli\u003E\u003C\u002Fol\u003E\u003Cbr\u003E\u003Cp\u003E如何写成代码:\u003C\u002Fp\u003E\u003Col\u003E\u003Cli\u003E设置循环次数。\u003C\u002Fli\u003E\u003Cli\u003E设置开始比较的位数,和结束的位数。\u003C\u002Fli\u003E\u003Cli\u003E两两比较,将最小的放到前面去。\u003C\u002Fli\u003E\u003Cli\u003E重复2、3步,直到循环次数完毕。\u003C\u002Fli\u003E\u003C\u002Fol\u003E\u003Cp\u003E代码实现如下:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Epublic void bubbleSort(int[] a){\n
int length=a.\\n
for(int i=0;i&a.i++){\n
for(int j=0;j&a.length-i-1;j++){\n
if(a[j]&a[j+1]){\n
temp=a[j];\n
a[j]=a[j+1];\n
}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Ch1\u003E6.快速排序\u003C\u002Fh1\u003E\u003Cblockquote\u003E\u003Cp\u003E要求时间最快时。\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Col\u003E\u003Cli\u003E选择第一个数为p,小于p的数放在左边,大于p的数放在右边。\u003C\u002Fli\u003E\u003Cli\u003E递归的将p左边和右边的数都按照第一步进行,直到不能递归。\u003C\u002Fli\u003E\u003C\u002Fol\u003E\u003Cbr\u003E\u003Cp\u003E代码实现如下:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Epublic static void quickSort(int[] numbers, int start, int end) {
if (start & end) {
int base = numbers[start]; \u002F\u002F 选定的基准值(第一个数值作为基准值)
\ \u002F\u002F 记录临时中间值
int i = start, j =
while ((numbers[i] & base) && (i & end))
while ((numbers[j] & base) && (j & start))
if (i &= j) {
temp = numbers[i];
numbers[i] = numbers[j];
numbers[j] =
} while (i &= j);
if (start & j)
quickSort(numbers, start, j);
if (end & i)
quickSort(numbers, i, end);
\n}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Ch1\u003E7.归并排序\u003C\u002Fh1\u003E\u003Cblockquote\u003E\u003Cp\u003E速度仅次于快排,内存少的时候使用,可以进行并行计算的时候使用。\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Col\u003E\u003Cli\u003E选择相邻两个数组成一个有序序列。\u003C\u002Fli\u003E\u003Cli\u003E选择相邻的两个有序序列组成一个有序序列。\u003C\u002Fli\u003E\u003Cli\u003E重复第二步,直到全部组成一个有序序列。\u003C\u002Fli\u003E\u003C\u002Fol\u003E\u003Cbr\u003E\u003Cp\u003E代码实现如下:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Epublic static void mergeSort(int[] numbers, int left, int right) {
int t = 1;\u002F\u002F 每组元素个数
int size = right - left + 1;
while (t & size) {
int s =\u002F\u002F 本次循环每组元素个数
while (i + (t - 1) & size) {
merge(numbers, i, i + (s - 1), i + (t - 1));
if (i + (s - 1) & right)
merge(numbers, i, i + (s - 1), right);
\nprivate static void merge(int[] data, int p, int q, int r) {
int[] B = new int[data.length];
int t = q + 1;
while (s &= q && t &= r) {
if (data[s] &= data[t]) {
B[k] = data[s];
B[k] = data[t];
if (s == q + 1)
B[k++] = data[t++];
B[k++] = data[s++];
for (int i = i &= i++)
data[i] = B[i];
\n}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Ch1\u003E8.基数排序\u003C\u002Fh1\u003E\u003Cblockquote\u003E\u003Cp\u003E用于大量数,很长的数进行排序时。\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Col\u003E\u003Cli\u003E将所有的数的个位数取出,按照个位数进行排序,构成一个序列。\u003C\u002Fli\u003E\u003Cli\u003E将新构成的所有的数的十位数取出,按照十位数进行排序,构成一个序列。\u003C\u002Fli\u003E\u003C\u002Fol\u003E\u003Cbr\u003E\u003Cp\u003E代码实现如下:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Epublic void sort(int[] array) {\n
\u002F\u002F首先确定排序的趟数;
int max = array[0];\n
for (int i = 1; i & array. i++) {\n
if (array[i] & max) {\n
max = array[i];\n
int time = 0;\n
\u002F\u002F判断位数;
while (max & 0) {\n
max \u002F= 10;\n
\u002F\u002F建立10个队列;
List&ArrayList& queue = new ArrayList&ArrayList&();\n
for (int i = 0; i & 10; i++) {\n
ArrayList&Integer& queue1 = new ArrayList&Integer&();\n
queue.add(queue1);\n
\u002F\u002F进行time次分配和收集;
for (int i = 0; i & i++) {\n
\u002F\u002F分配数组元素;
for (int j = 0; j & array. j++) {\n
\u002F\u002F得到数字的第time+1位数;
int x = array[j] % (int) Math.pow(10, i + 1) \u002F (int) Math.pow(10, i);\n
ArrayList&Integer& queue2 = queue.get(x);\n
queue2.add(array[j]);\n
queue.set(x, queue2);\n
int count = 0;\u002F\u002F元素计数器;
\u002F\u002F收集队列元素;
for (int k = 0; k & 10; k++) {\n
while (queue.get(k).size() & 0) {\n
ArrayList&Integer& queue3 = queue.get(k);\n
array[count] = queue3.get(0);\n
queue3.remove(0);\n
count++;\n
}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cbr\u003E\u003Ca href=\&https:\u002F\u002Flink.zhihu.com\u002F?target=http%3A\u002F\u002Fwww.jianshu.com\u002Fp\u002F5e\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E阅读原文\u003C\u002Fa\u003E\u003Cfigure\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-9d70dd9d3a01aeb00034_b.jpg\& data-rawwidth=\&900\& data-rawheight=\&500\& class=\&origin_image zh-lightbox-thumb\& width=\&900\& data-original=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-9d70dd9d3a01aeb00034_r.jpg\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='900'%20height='500'&&\u002Fsvg&\& data-rawwidth=\&900\& data-rawheight=\&500\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&900\& data-original=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-9d70dd9d3a01aeb00034_r.jpg\& data-actualsrc=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-9d70dd9d3a01aeb00034_b.jpg\&\u003E\u003C\u002Ffigure\u003E&,&updated&:new Date(&T11:20:33.000Z&),&canComment&:false,&commentPermission&:&anyone&,&commentCount&:29,&collapsedCount&:0,&likeCount&:439,&state&:&published&,&isLiked&:false,&slug&:&&,&isTitleImageFullScreen&:false,&rating&:&none&,&titleImage&:&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-59b7417aaba40d4b6bf9680_r.jpg&,&links&:{&comments&:&\u002Fapi\u002Fposts\u002F2Fcomments&},&reviewers&:[],&topics&:[{&url&:&https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F&,&id&:&&,&name&:&Java&},{&url&:&https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F&,&id&:&&,&name&:&排序算法&},{&url&:&https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F&,&id&:&&,&name&:&代码&}],&adminClosedComment&:false,&titleImageSize&:{&width&:750,&height&:340},&href&:&\u002Fapi\u002Fposts\u002F&,&excerptTitle&:&&,&column&:{&slug&:&lishichao&,&name&:&互联网笔记&},&tipjarState&:&inactivated&,&annotationAction&:[],&sourceUrl&:&&,&pageCommentsCount&:29,&hasPublishingDraft&:false,&snapshotUrl&:&&,&publishedTime&:&T19:20:33+08:00&,&url&:&\u002Fp\u002F&,&lastestLikers&:[{&bio&:&自由职业&,&isFollowing&:false,&hash&:&6c314be8a8f2fbb3ecf14&,&uid&:558500,&isOrg&:false,&slug&:&mrchen-25-63&,&isFollowed&:false,&description&:&&,&name&:&Mr陈&,&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002Fmrchen-25-63&,&avatar&:{&id&:&v2-3607dedf647a1b1e38e1&,&template&:&https:\u002F\u002Fpic1.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:&&,&isFollowing&:false,&hash&:&ccda9353febedb19c75eeb897da358df&,&uid&:521000,&isOrg&:false,&slug&:&wedior&,&isFollowed&:false,&description&:&&,&name&:&Wedior&,&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002Fwedior&,&avatar&:{&id&:&v2-b51ba7ee771c426c89b655c7&,&template&:&https:\u002F\u002Fpic1.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:&码农一枚,正努力成为程序猿&,&isFollowing&:false,&hash&:&47d563b49c9af64a490fec&,&uid&:586000,&isOrg&:false,&slug&:&xiaoshuang66&,&isFollowed&:false,&description&:&间接性凌云壮志,持续性混吃等死&,&name&:&霜公子&,&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002Fxiaoshuang66&,&avatar&:{&id&:&a1e1db9f01dd96d385b5975&,&template&:&https:\u002F\u002Fpic1.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:&&,&isFollowing&:false,&hash&:&3c0c73a3b2cb299a91cbaeb&,&uid&:76,&isOrg&:false,&slug&:&wang-xiao-ren-69&,&isFollowed&:false,&description&:&&,&name&:&王小任&,&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002Fwang-xiao-ren-69&,&avatar&:{&id&:&da8e974dc&,&template&:&https:\u002F\u002Fpic4.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:&马拉松&,&isFollowing&:false,&hash&:&1bd3efa4a6c76f9e2024&,&uid&:373800,&isOrg&:false,&slug&:&ma-fei-35-15&,&isFollowed&:false,&description&:&&,&name&:&马飞&,&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002Fma-fei-35-15&,&avatar&:{&id&:&da8e974dc&,&template&:&https:\u002F\u002Fpic4.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false}],&summary&:&\u003Cimg src=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-9d70dd9d3a01aeb2.jpg\& data-rawwidth=\&900\& data-rawheight=\&500\& class=\&origin_image inline-img zh-lightbox-thumb\& data-original=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-9d70dd9d3a01aeb00034_r.jpg\&\u003E原文链接:\u003Ca href=\&http:\u002F\u002Fwww.jianshu.com\u002Fp\u002F5e\& data-editable=\&true\& data-title=\&一遍记住Java常用的八种排序算法与代码实现\&\u003E一遍记住Java常用的八种排序算法与代码实现\u003C\u002Fa\u003E作者:breakingsword1.直接插入排序经常碰到这样一类排序问题:把新的数据插入到已经排好的数据列中。将第一个数和第二个数排序,然后构成一个有序序列将第三个数插入进去,构成一个新的有序序列。对第四…&,&reviewingCommentsCount&:0,&meta&:{&previous&:{&isTitleImageFullScreen&:false,&rating&:&none&,&titleImage&:&https:\u002F\u002Fpic1.zhimg.com\u002F50\u002Fv2-efdb274f05e9_xl.jpg&,&links&:{&comments&:&\u002Fapi\u002Fposts\u002F2Fcomments&},&topics&:[{&url&:&https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F&,&id&:&&,&name&:&自学&},{&url&:&https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F&,&id&:&&,&name&:&记忆&},{&url&:&https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F&,&id&:&&,&name&:&记忆方法&}],&adminClosedComment&:false,&href&:&\u002Fapi\u002Fposts\u002F&,&excerptTitle&:&&,&author&:{&bio&:&有情怀→渴望做出一款颠覆性App的代码工作者&,&isFollowing&:false,&hash&:&fd983d762fb8&,&uid&:528000,&isOrg&:false,&slug&:&amin706&,&isFollowed&:false,&description&:&
码力全开工作室官网 → http:\u002F\u002Fmaliquankai.com\n
奇点日报创始人,追求产品交互和设计的产品经理一枚 \n
高逼格程序员技术分享平台 → http:\u002F\u002Fwww.qidianlife.com\n『心动屋』→ 发现令您心动的好物\n『壹日程』→ 专注任务管理和待办计划提醒
\n『拾光记』→ 拾起你走过的时光\n『口袋密码』→ 安全简洁的账号管家\n『破壳日』→ 精美的生日 · 节日 · 纪念日礼物提醒工具 \n
邮箱 → &,&name&:&Larry&,&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002Famin706&,&avatar&:{&id&:&v2-a5db75ec863beb&,&template&:&https:\u002F\u002Fpic1.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},&column&:{&slug&:&lishichao&,&name&:&互联网笔记&},&content&:&\u003Cblockquote\u003E\u003Cp\u003E\u003Cstrong\u003E版权声明\u003C\u002Fstrong\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E本文原创且首发自微信公众号:千古刘传(qiangulc)\u003C\u002Fp\u003E\u003Cp\u003E无需授权即可转载,但请自觉保留以上版权声明。\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Cbr\u003E\u003Cp\u003E这是一张关于知识与经验的示意图。\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E不少人看过此图,但该图仅呈现了知识与经验的关系,对于学习还没有太多指导意义。今天谈谈学习科学中一个重要的概念:组块(chunk)。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cbr\u003E\u003Cp\u003E当你接触到一个新知识(例如“递弱代偿原理”),这个新概念在你头脑中呈现的状态就像这样。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E组块化(chunking),能让我们将头脑中的信息组块,按照有意义的方式形成一个逻辑性、概念性的视野,帮助我们更好地理解新知识,让其呈现成这样。\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E当这个新知识经过理解、练习后,它就会形成一个新组块,存入我们的长期记忆,参与到下一次的组块化中。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E例如,书架上取书这一个动作,就包含了很多组块:识别目标,确定位置,取书时用手抓住书脊,控制抓的力度,取出的路径。每一个步骤都是一个小组块(mini-chunk),而对于成年人来说,这些小组块已经形成了一个大组块,所以成年人只会用取书这一个组块去解决问题,而不是用多个小组块。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E相较之下,对于一个2岁的小孩子,完成取书这个动作就必须掌握其中的小组块。每取一次书,他都必须按顺序思考每一个组块,一个组块使用完,再思考下一个组块如何运用。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E那么,组块是怎样被大脑运用的呢?\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E工作记忆(working memory),我在之前的文章《不明白大脑如何运作,自学是无效的》已经提到,简单来说,就是我们当前正在意识、思考的区域,比如你正在看这篇文章,这篇文章的信息以及你正在思考的内容,都在你的工作记忆中。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cbr\u003E\u003Cp\u003E工作记忆的容量有限,早期的研究认为其容量为7个有意义的组块(Miller,1956),而最新的研究得出结论为4个(Cowan,2001)。工作记忆位于大脑的前额皮质。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E我们从长期记忆中提取组块放入到工作记忆,利用这些组块来处理问题。由于容量有限,我们放入的组块只能有4个,如下图。\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E举一个形象的例子来说明这个进程。\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E你的工作记忆是一个章鱼,它只有四个角,当你处理问题时,它就会从长期记忆中抓取组块放到自己的肚子里。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E以上文提到的取书为例,对于成年人来说,取书这个动作本身就是一个组块,所以他们取书时,工作记忆中只需要放入一个组块即可。而对于2岁的儿童来说,这个过程就很困难了,他们需要同时提取四个组块放入工作记忆,每完成一步,就撤掉一个组块,再放入下一个组块,直到完成取书的工作。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E所以,一次高强度的学习,通常会让你产生认知力竭的感觉,也就是认知过载,需要动用的组块容量超过了工作记忆。而日常学习,能收获适量的认知力竭,是衡量学习有效性的标志之一。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E我写这篇文章,就是帮助自己去chunking一个小知识点(mini-chunk),而自学这个话题至少能写上万字。但现在就去写,就像小孩子学习如何取书,在没有熟练mini-chunk时去做一个big-chunk是极其困难的。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E在学校教育中,优秀的老师按照这个原理规划教学,学生跟着课堂按部就班地学习,能系统地建立知识体系。而脱离学校进入社会后,由于缺乏这样的引导,大部分人的学习都是盲人摸象,以读书来说,就有两种情况:把该学习的书当作娱乐消遣,把读娱乐消遣的书误当作学习。没按照组块的原理规划学习,这样微弱劣势的长期积累,使得很多人仅有碎片化的知识,而没有知识体系。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cbr\u003E\u003Cp\u003E明白组块这个概念,对于自学者来说极其重要。\u003C\u002Fp\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-9d70dd9d3a01aeb00034_b.jpg\& data-rawwidth=\&900\& data-rawheight=\&500\& class=\&origin_image zh-lightbox-thumb\& width=\&900\& data-original=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-9d70dd9d3a01aeb00034_r.jpg\&\u003E\u003C\u002Ffigure\u003E&,&state&:&published&,&sourceUrl&:&&,&pageCommentsCount&:0,&canComment&:false,&snapshotUrl&:&&,&slug&:,&publishedTime&:&T20:28:54+08:00&,&url&:&\u002Fp\u002F&,&title&:&你真的会自学吗?验证一下就知道了!&,&summary&:&\u003Cstrong\u003E版权声明\u003C\u002Fstrong\u003E 本文原创且首发自微信公众号:千古刘传(qiangulc)无需授权即可转载,但请自觉保留以上版权声明。 这是一张关于知识与经验的示意图。 不少人看过此图,但该图仅呈现了知识与经验的关系,对于学习还没有太多指导意义。今天谈谈学习科学中一个重要…&,&reviewingCommentsCount&:0,&meta&:{&previous&:null,&next&:null},&commentPermission&:&anyone&,&commentsCount&:17,&likesCount&:40},&next&:{&isTitleImageFullScreen&:false,&rating&:&none&,&titleImage&:&https:\u002F\u002Fpic1.zhimg.com\u002F50\u002Fv2-cab30f3c5b1_xl.jpg&,&links&:{&comments&:&\u002Fapi\u002Fposts\u002F2Fcomments&},&topics&:[{&url&:&https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F&,&id&:&&,&name&:&高效工作&},{&url&:&https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F&,&id&:&&,&name&:&移动开发&}],&adminClosedComment&:false,&href&:&\u002Fapi\u002Fposts\u002F&,&excerptTitle&:&&,&author&:{&bio&:&有情怀→渴望做出一款颠覆性App的代码工作者&,&isFollowing&:false,&hash&:&fd983d762fb8&,&uid&:528000,&isOrg&:false,&slug&:&amin706&,&isFollowed&:false,&description&:&
码力全开工作室官网 → http:\u002F\u002Fmaliquankai.com\n
奇点日报创始人,追求产品交互和设计的产品经理一枚 \n
高逼格程序员技术分享平台 → http:\u002F\u002Fwww.qidianlife.com\n『心动屋』→ 发现令您心动的好物\n『壹日程』→ 专注任务管理和待办计划提醒
\n『拾光记』→ 拾起你走过的时光\n『口袋密码』→ 安全简洁的账号管家\n『破壳日』→ 精美的生日 · 节日 · 纪念日礼物提醒工具 \n
邮箱 → &,&name&:&Larry&,&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002Famin706&,&avatar&:{&id&:&v2-a5db75ec863beb&,&template&:&https:\u002F\u002Fpic1.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},&column&:{&slug&:&lishichao&,&name&:&互联网笔记&},&content&:&\u003Cblockquote\u003E\u003Cp\u003E作者:小胡子哥 (@Barret李靖) \u003C\u002Fp\u003E\u003Ca href=\&http:\u002F\u002Flink.zhihu.com\u002F?target=http%3A\u002F\u002Fwww.barretlee.com\u002Fblog\u002F\u002F21\u002Fdonnot-repeat-yourself\u002F\& class=\& external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E\u003Cspan class=\&invisible\&\u003Ehttp:\u002F\u002Fwww.\u003C\u002Fspan\u003E\u003Cspan class=\&visible\&\u003Ebarretlee.com\u002Fblog\u002FC\u002Fspan\u003E\u003Cspan class=\&invisible\&\u003E\u002F07\u002F21\u002Fdonnot-repeat-yourself\u002F\u003C\u002Fspan\u003E\u003Cspan class=\&ellipsis\&\u003E\u003C\u002Fspan\u003E\u003C\u002Fa\u003E\u003C\u002Fblockquote\u003E\u003Cp\u003E当我们沉浸在旺盛的需求之中时,整个人便会成为一台工作的机器,切着类似的页面,写着同样的逻辑,重复着昨天或者上个月做的事情,时间久了,觉得腻味,没有什么创新,也没有明显的成长。用一句通俗的话来讲:工作五年,后面四年重复着第一年的活儿。\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E很多人尝试跳出这个怪圈,不过基于环境压力和思维受阻,最后又不得不选择放弃。今天想通过介绍如何高效有保障地开发一个无线页面来帮助大家找到突破口。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E\u003Cstrong\u003E日常开发状态\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E很多无线页面的开发有两种模式,一种是后台输出 JSON 数据,前端根据数据来渲染页面(同步模式);第二种是前端异步加载后端数据然后渲染(异步模式)。当然,两种模式夹杂在一起也是存在的,这种情况一般会有一个由前端控制的中间层提供同步数据和异步数据。为了减少前后端的沟通成本,往往采用第二种模式。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E拿到设计稿后,与后端同学约定接口格式,让后端同学尽快提供 mock 数据,如果提供不了,便自己构造测试数据。接着回到自己的工位上切图,切图过程中会解决好响应式问题和兼容性问题,待到后端产出真实数据时,更换 JS 中的接口地址,联调 ok 便发布页面,大功告成!\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E整个流程很顺畅,这对一个工作了三四年的程序员来说,没有任何压力便完成甚至提前完成了任务。但是,回过头来想一想,整个开发过程中我们留下了什么?沉淀了什么?\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E\u003Cstrong\u003E放慢节奏,我们再走一遍流程\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E对于上面的开发流程,先提出几个常见的问题:\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cul\u003E\u003Cli\u003E\u003Cp\u003E你是如何良好处理大、中、小等各型号手机的适配问题的?Media Query?等比布局?\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E模块如何渲染,模板和接口数据如何拼装?字符串拼接?正则替换?模板引擎?\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E本地、预发和线上三套环境,如何进行无痕切换?\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E如果开发时接口有变动,线上数据暂未产出,本地 mock 接口如何快速响应?\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E如何解决异步 JSONP 接口的安全问题?JSONP 接口请求异常、超时、失败等情况如何处理?\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E页面中的 Slide 和 Tab 逻辑如何写?复制之前写过的代码?找一个好用的组件?\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E图片的懒加载处理如何控制?脚本的懒执行如何控制?\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E首屏加载页面空白体验如何优化?\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E页面回退 Session 和 Token 失效如何处理?\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E…\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cbr\u003E\u003Cp\u003E上面提出的几个问题,列的不全面。有一些可能是你经常碰到的,甚至有了成熟的解决方案,而也有一些问题可能是你从未考虑过的。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E我们把整个前端开发流程做简单切割:切图、获取数据、渲染、事件绑定、数据统计、页面优化、监控。这种切割很暴力,也比较粗糙,不过它不妨碍我们在下面讨论,作为前端工程师,除了完成日常需求外,还要做什么?还能做什么?\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E\u003Cstrong\u003E切图\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E隐约还记得三年前,我接了一个无线页面的外包活儿,页面的结构很简单,但我做的很糟糕。为了适配不同尺寸的机型,我写了无数 Media Query,加上当时采用的 em 作单位,很多细节位置都没控制好。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E回到现在,已经有了很通用、主流的方案——使用 rem,动态计算 html 标签的 font-size,思路很简单,但是存在不少的坑,和一些较难理解的概念,Google 搜索下 lib-flexible 能够找到这些问题以及解决方案。不过我们切图时还可以思考一些其他的问题:\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cul\u003E\u003Cli\u003E\u003Cp\u003E各类静态资源(image\u002Fcss\u002Fjs\u002Ffont)如何放置?新建各种文件夹?\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E是否还是修改代码再刷新页面的调试手段?考虑过 liveload?\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003ECSS 复用率如何?跨项目的复用率呢?使用预处理语言封装基类?\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E还在心算从 px 折算为 rem?用计算器算?\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E身旁放 20 台机器测试页面兼容性?\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cbr\u003E\u003Cp\u003E以上问题,没有哪一个会让人特别苦恼,但是堆积起来,却让我们的开发效率和开发体验落后了好几个档次。这些问题并非无解,我们可以尝试着帮助同事和团队找到问题的答案,比如:\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cul\u003E\u003Cli\u003E\u003Cp\u003E统一团队的本地构建环境,初始化一个工程目录的脚手架\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E统一打包脚本,实时编译和预览\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E封装预处理基类,屏蔽 rem 计算,比如编译时自动转换 px 为 rem\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E构建云测平台,云端测试各种机型兼容性,打开网页输入网址即可批量测试\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cbr\u003E\u003Cp\u003E有些解决方案只需要几行脚本就能搞定,而有一些可能需要投入时间和精力。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E\u003Cstrong\u003E获取数据\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E本地、预发、线上三套环境,如何做到环境的顺滑切换?我在百度的时候,团队最常用的方案就是:\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cul\u003E\u003Cli\u003E\u003Cp\u003E线上测试,本地反向代理到预发或者线上环境;\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E本地测试,则使用 apache 开启服务提供 mock 接口\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cbr\u003E\u003Cp\u003E可一旦与后端约定的接口有变动,本地 mock 数据也要跟着一起变动。这个问题有什么好的处理方案?在团队中,好的方案一定不是几行文字的提示或指引,而是通过流程和监控来控制!\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E这里提到的获取数据,细想之下可不是什么轻松的事情。有很多问题需要思考:\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cul\u003E\u003Cli\u003E\u003Cp\u003E如何保障 JSONP 数据的安全问题?refer 限制?token 验证?\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E数据来源很多,如何减少页面的请求数量?让后端合并数据?如果是多个团队提供数据呢?\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E如何控制需求变化导致的接口格式变化?\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E如何处理接口的不稳定问题?\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E如何处理超时问题?\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E如何产生容灾数据?如何获取容灾数据?\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E如何控制数据缓存?如前端控制缓存一分钟?\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E如何对接口做监控?\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E如何减少数据的重复请求问题?\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cbr\u003E\u003Cp\u003E以上每个问题都有很多处理方案,而这些问题不仅仅是自己会遇到,身边的同事也会遇到。如果可以站在团队的角度去思考问题,很多思路会比较容易涌现出来,比如:\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cul\u003E\u003Cli\u003E\u003Cp\u003E构建一个平台,用于接口格式约定,通过约定好的格式,系统自动生成 mock 数据,用于本地开发,后端也必须遵循这个接口约定,任何接口的变动,mock 数据自动变动\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E构建一个平台,让不规范的数据进入这个平台,规范化输出,前端只考虑规范化的接口提示和解析,同时该平台产出数据的备份接口\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E前端添加一个请求 Hub,当页面有很多请求出来时,合并请求统一发出,当数据回来时,统一储存和过滤\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cbr\u003E\u003Cp\u003E数据是最容易出问题的地方,每一个接口请求都需要一大堆的逻辑处理异常。倘若接口格式、开发流程和前端模式都可以规范化,我们需要做的就剩下套公式,这种高效你能否想象?\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E\u003Cstrong\u003E渲染\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E大胆地揣测下大家在写一个模块的时候,跟我一样也是这么划分的函数:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Evar Module = function() {\n
this.init();\n}; \n
\n\u002F\u002F 初始化
\nModule.prototype.init = function() {
this.fetchData(function() {
\u002F\u002F do something\n
\n\n\u002F\u002F 绑定事件
\nModule.prototype.bindEvent = function() {
\n \u002F\u002F ...
\n\n\u002F\u002F 获取数据
\nModule.prototype.fetchData = function(cb) {
var self =\n
ajax({}).then(function(data) {\n
self.renderData(data);\n
}).catch(function() {\n
self._fetchDataFailed();\n
}).fin(function() {\n
cb && cb();\n
});\n}; \n\u002F\u002F 渲染数据
\nModule.prototype.renderData = function(data) {\n
data = this._resolveData(data);
\u002F\u002F ...\n
this.bindEvent();\n};
\n\n\u002F\u002F 处理数据
\nModule.prototype._resolveData = function() {
\n \u002F\u002F ...
\n}; \n\u002F\u002F 加载失败
\nModule.prototype._fetchDataFailed = function() {
\u002F\u002F ...
\n};\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E不管一个模块有多么简单,它基本都会包含以上步骤,倘若没有用函数隔离每步操作的意图,代码会显得十分散乱。我经常看到,有同学把「渲染」这一块的代码被放到「获取数据」甚至是「初始化」中,这种程序结构显然是不合理的。同时,也经常会看到渲染时,\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cul\u003E\u003Cli\u003E\u003Cp\u003E在代码中写大量的字符串模板\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E写一个工具函数,解析字符串模块中的循环逻辑\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E使用 replace 函数正则替换字符串变量\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E使用 innerHTML 函数插入拼装好的字符串\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E在渲染模块中添加大量逻辑\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cbr\u003E\u003Cp\u003E以上,没有哪一种是不正确的,我也没有对哪一种写法开喷的意图。但是至少我们可以在多次编程经验中提炼出一些有价值的内容:\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cul\u003E\u003Cli\u003E\u003Cp\u003E团队统一的模板引擎,并且提供模块的离线编译,提高线上运行效率\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E提供安全机制,保障插入的数据不会产生安全问题\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E严格编程范式,分离视图和逻辑层,把数据处理好了再送入模板\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cbr\u003E\u003Cp\u003E有一个可执行的编码规范,加上适当合理的 Code Review,整个团队代码便会如出一辙。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E\u003Cstrong\u003E后续操作\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E本想写成一篇长文,把每个环节可以综合考虑的问题都提出来,不过本文的目的,只是表述一些观点,期望大家在编程的时候,有更多基于团队的思考,针对具体问题提出一些通用的解决方案。比如下面,再提出几个问题:\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cul\u003E\u003Cli\u003E\u003Cp\u003E首屏加载白屏问题,如何处理?本地缓存?等待提示?假数据?同步输出?\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E如何减少页面的请求?资源内敛?如何做到自动内敛所有的资源?\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E页面报错的统计如何做?做了之后如何分析?分析之后如何推动线上错误减少?\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E页面发布时如何自动回归检测?点下链接看看是否 404?打开控制台看看是否有报错?滚屏看看图片是否加载正确?\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E…\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cbr\u003E\u003Cp\u003E以上问题,都有相当成熟的解决方案,那你们团队呢?\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E\u003Cstrong\u003E小结\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E当发现工作做起来索然无味的时候,我脑海中蹦出来的第一个念头是:最近是不是有点放纵了?\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E我喜欢用编程解决问题,只要是重复的事情,我一定会想尽办法简化,然后交给机器去做。我希望今年可以用程序解决更多的问题。\u003C\u002Fp\u003E\u003Cfigure\u003E\u003Cimg src=\&http:\u002F\u002Fpic1.zhimg.com\u002Fv2-9d70dd9d3a01aeb00034_b.jpg\& data-rawwidth=\&900\& data-rawheight=\&500\& class=\&origin_image zh-lightbox-thumb\& width=\&900\& data-original=\&http:\u002F\u002Fpic1.zhimg.com\u002Fv2-9d70dd9d3a01aeb00034_r.jpg\&\u003E\u003C\u002Ffigure\u003E&,&state&:&published&,&sourceUrl&:&&,&pageCommentsCount&:0,&canComment&:false,&snapshotUrl&:&&,&slug&:,&publishedTime&:&T23:26:10+08:00&,&url&:&\u002Fp\u002F&,&title&:&工作五年,后面四年重复着第一年的活儿?&,&summary&:&作者:小胡子哥 (@Barret李靖) \u003Ca href=\&http:\u002F\u002Fwww.barretlee.com\u002Fblog\u002F\u002F21\u002Fdonnot-repeat-yourself\u002F\&\u003Ehttp:\u002F\u002Fwww.barretlee.com\u002Fblog\u002F\u002F21\u002Fdonnot-repeat-yourself\u002F\u003C\u002Fa\u003E当我们沉浸在旺盛的需求之中时,整个人便会成为一台工作的机器,切着类似的页面,写着同样的逻辑,重复着昨天或者上个月做的事情,时间久了,觉得腻味,没有什么创新,也没有明显的成长。用一句通俗的话…&,&reviewingCommentsCount&:0,&meta&:{&previous&:null,&next&:null},&commentPermission&:&anyone&,&commentsCount&:2,&likesCount&:16}},&annotationDetail&:null,&commentsCount&:29,&likesCount&:439,&FULLINFO&:true}},&User&:{&amin706&:{&isFollowed&:false,&name&:&Larry&,&headline&:&
码力全开工作室官网 → http:\u002F\u002Fmaliquankai.com\n
奇点日报创始人,追求产品交互和设计的产品经理一枚 \n
高逼格程序员技术分享平台 → http:\u002F\u002Fwww.qidianlife.com\n『心动屋』→ 发现令您心动的好物\n『壹日程』→ 专注任务管理和待办计划提醒
\n『拾光记』→ 拾起你走过的时光\n『口袋密码』→ 安全简洁的账号管家\n『破壳日』→ 精美的生日 · 节日 · 纪念日礼物提醒工具 \n
邮箱 → &,&avatarUrl&:&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-a5db75ec863beb_s.jpg&,&isFollowing&:false,&type&:&people&,&slug&:&amin706&,&bio&:&有情怀→渴望做出一款颠覆性App的代码工作者&,&hash&:&fd983d762fb8&,&uid&:528000,&isOrg&:false,&description&:&
码力全开工作室官网 → http:\u002F\u002Fmaliquankai.com\n
奇点日报创始人,追求产品交互和设计的产品经理一枚 \n
高逼格程序员技术分享平台 → http:\u002F\u002Fwww.qidianlife.com\n『心动屋』→ 发现令您心动的好物\n『壹日程』→ 专注任务管理和待办计划提醒
\n『拾光记』→ 拾起你走过的时光\n『口袋密码』→ 安全简洁的账号管家\n『破壳日』→ 精美的生日 · 节日 · 纪念日礼物提醒工具 \n
邮箱 → &,&badge&:{&identity&:null,&bestAnswerer&:null},&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002Famin706&,&avatar&:{&id&:&v2-a5db75ec863beb&,&template&:&https:\u002F\u002Fpic1.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false}},&Comment&:{},&favlists&:{}},&me&:{},&global&:{&experimentFeatures&:{&ge3&:&ge3_9&,&ge2&:&ge2_1&,&navi&:&1&,&growthSearch&:&s2&,&nwebQAGrowth&:&experiment&,&qawebRelatedReadingsContentControl&:&close&,&liveStore&:&ls_a2_b2_c1_f2&,&nwebSearch&:&nweb_search_heifetz&,&vdlc&:&e&,&rt&:&y&,&isOffice&:&false&,&enableTtsPlay&:&post&,&newLiveFeedMediacard&:&new&,&newMobileAppHeader&:&true&,&androidPassThroughPush&:&all&,&hybridZhmoreVideo&:&yes&,&nwebGrowthPeople&:&default&,&nwebSearchSuggest&:&default&,&qrcodeLogin&:&qrcode&,&enableVoteDownReasonMenu&:&enable&,&isShowUnicomFreeEntry&:&unicom_free_entry_off&,&newMobileColumnAppheader&:&new_header&,&androidDbRecommendAction&:&open&,&biu&:&1&,&info&:&1&,&androidDbFeedHashTagStyle&:&button&,&appStoreRateDialog&:&close&,&default&:&None&,&isNewNotiPanel&:&no&,&biua&:&1&,&zcmLighting&:&zcm&,&adR&:&b&,&wechatShareModal&:&wechat_share_modal_show&,&growthBanner&:&default&,&androidProfilePanel&:&panel_b&}},&columns&:{&next&:{},&lishichao&:{&following&:false,&canManage&:false,&href&:&\u002Fapi\u002Fcolumns\u002Flishichao&,&name&:&互联网笔记&,&creator&:{&slug&:&amin706&},&url&:&\u002Flishichao&,&slug&:&lishichao&,&avatar&:{&id&:&v2-05a3efacf81bef39a0f44&,&template&:&https:\u002F\u002Fpic1.zhimg.com\u002F{id}_{size}.jpg&}}},&columnPosts&:{},&columnSettings&:{&colomnAuthor&:[],&uploadAvatarDetails&:&&,&contributeRequests&:[],&contributeRequestsTotalCount&:0,&inviteAuthor&:&&},&postComments&:{},&postReviewComments&:{&comments&:[],&newComments&:[],&hasMore&:true},&favlistsByUser&:{},&favlistRelations&:{},&promotions&:{},&switches&:{&couldSetPoster&:false},&draft&:{&titleImage&:&&,&titleImageSize&:{},&isTitleImageFullScreen&:false,&canTitleImageFullScreen&:false,&title&:&&,&titleImageUploading&:false,&error&:&&,&content&:&&,&draftLoading&:false,&globalLoading&:false,&pendingVideo&:{&resource&:null,&error&:null}},&drafts&:{&draftsList&:[],&next&:{}},&config&:{&userNotBindPhoneTipString&:{}},&recommendPosts&:{&articleRecommendations&:[],&columnRecommendations&:[]},&env&:{&edition&:{&baidu&:false,&yidianzixun&:false,&qqnews&:false},&isAppView&:false,&appViewConfig&:{&content_padding_top&:128,&content_padding_bottom&:56,&content_padding_left&:16,&content_padding_right&:16,&title_font_size&:22,&body_font_size&:16,&is_dark_theme&:false,&can_auto_load_image&:true,&app_info&:&OS=iOS&},&isApp&:false,&userAgent&:{&ua&:&Mozilla\u002F5.0 (compatible, MSIE 11, Windows NT 6.3; Trident\u002F7.0; rv:11.0) like Gecko&,&browser&:{&name&:&IE&,&version&:&11&,&major&:&11&},&engine&:{&version&:&7.0&,&name&:&Trident&},&os&:{&name&:&Windows&,&version&:&8.1&},&device&:{},&cpu&:{}}},&message&:{&newCount&:0},&pushNotification&:{&newCount&:0}}}

我要回帖

更多关于 java中排序算法 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信