├── .gitignore ├── README.md ├── algorithm ├── ProgrammerInterview │ ├── .idea │ │ ├── .name │ │ ├── ant.xml │ │ ├── compiler.xml │ │ ├── copyright │ │ │ └── profiles_settings.xml │ │ ├── encodings.xml │ │ ├── inspectionProfiles │ │ │ ├── Project_Default.xml │ │ │ └── profiles_settings.xml │ │ ├── misc.xml │ │ ├── modules.xml │ │ ├── scopes │ │ │ └── scope_settings.xml │ │ ├── uiDesigner.xml │ │ ├── vcs.xml │ │ └── workspace.xml │ ├── ProgrammerInterview.iml │ └── src │ │ └── com │ │ └── nowcoder │ │ ├── q1_1 │ │ └── Different.java │ │ ├── q1_2 │ │ └── Reverse.java │ │ ├── q1_3 │ │ └── Same.java │ │ ├── q1_4 │ │ └── Replacement.java │ │ ├── q1_5 │ │ └── Zipper.java │ │ ├── q1_6 │ │ └── Transform.java │ │ ├── q1_7 │ │ └── Clearer.java │ │ ├── q1_8 │ │ └── ReverseEqual.java │ │ ├── q2_2 │ │ ├── ListNode.java │ │ └── Solution.java │ │ ├── q2_3 │ │ ├── ListNode.java │ │ └── Remove.java │ │ ├── q2_4 │ │ ├── ListNode.java │ │ ├── Partition.java │ │ └── TestPartition.java │ │ ├── q2_5 │ │ ├── ListNode.java │ │ └── Plus.java │ │ ├── q2_7 │ │ ├── ListNode.java │ │ └── Palindrome.java │ │ ├── q3_3 │ │ └── SetOfStacks.java │ │ ├── q3_5 │ │ └── Solution.java │ │ ├── q3_6 │ │ └── TwoStacks.java │ │ └── q3_7 │ │ └── CatDogAsylum.java ├── README.md └── Sort │ ├── .idea │ ├── .name │ ├── compiler.xml │ ├── copyright │ │ └── profiles_settings.xml │ ├── encodings.xml │ ├── misc.xml │ ├── modules.xml │ ├── scopes │ │ └── scope_settings.xml │ ├── uiDesigner.xml │ ├── vcs.xml │ └── workspace.xml │ ├── Sort.iml │ └── src │ └── com │ └── code │ └── sort │ ├── BubbleSort.java │ └── SelectionSort.java ├── pics ├── etc │ └── IloveStudy.jpg └── sql │ └── sql_student_01.jpg ├── question └── README.md └── sql ├── README.md ├── 练习用的建表数据 └── forsql.sql ├── 走向面试之数据库基础:你必知必会的SQL语句练习-Part 1 └── README.md └── 走向面试之数据库基础:你必知必会的SQL语句练习-Part 2 └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | /algorithm/ProgrammerInterview/out/* 2 | /algorithm/Sort/out/* -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 概述 2 | 这个库用来放置一些自己练习的东西,作为一个转行者,很多知识点都有残缺,特别是在算法上其实有着很大的弱点。
3 |
4 | 都说木桶原理木桶原理,就算不情愿也自然不能坐视不管。
5 |
6 | 还有其他很多例如sql的编写,很多面试题中知识点的挖掘,也都需要去提炼和学习。 7 |
8 |
9 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/.idea/.name: -------------------------------------------------------------------------------- 1 | ProgrammerInterview -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/.idea/ant.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/.idea/scopes/scope_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/.idea/uiDesigner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 61 | 62 | 63 | 64 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 86 | 87 | 88 | 89 | 103 | 104 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 138 | 139 | 159 | 160 | 161 | 164 | 165 | 170 | 171 | 172 | 173 | 174 | 175 | Inspections 176 | 177 | 178 | Spelling 179 | 180 | 181 | 182 | 183 | SpellCheckingInspection 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 227 | 228 | 229 | 230 | 233 | 234 | 237 | 238 | 239 | 240 | 243 | 244 | 247 | 248 | 251 | 252 | 255 | 256 | 259 | 260 | 261 | 262 | 265 | 266 | 269 | 270 | 273 | 274 | 277 | 278 | 281 | 282 | 283 | 284 | 287 | 288 | 291 | 292 | 295 | 296 | 299 | 300 | 303 | 304 | 305 | 306 | 309 | 310 | 313 | 314 | 317 | 318 | 321 | 322 | 325 | 326 | 327 | 328 | 331 | 332 | 335 | 336 | 339 | 340 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 380 | 381 | 402 | 403 | 404 | 405 | 408 | 409 | 430 | 431 | 432 | 433 | 436 | 437 | 458 | 459 | 460 | 461 | 464 | 465 | 486 | 487 | 488 | 489 | 492 | 493 | 514 | 515 | 516 | 525 | 526 | 537 | 538 | 539 | 544 | 545 | 546 | 547 | 563 | 564 | 565 | 566 | 584 | 596 | 597 | 598 | 616 | 617 | 618 | 619 | 633 | 634 | 635 | 636 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | localhost 651 | 5050 652 | 653 | 654 | 655 | 656 | 671 | 672 | 673 | 674 | 1483253733128 675 | 1483253733128 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 734 | 735 | 763 | 764 | 797 | 798 | 799 | 800 | 801 | 804 | 805 | 806 | 807 | 808 | 809 | 810 | 811 | 812 | 813 | 814 | 815 | 816 | 817 | 818 | 819 | 820 | 821 | 822 | 823 | 824 | 825 | 826 | 827 | 828 | 829 | 830 | 831 | 832 | 833 | 834 | 835 | 836 | 837 | 838 | 839 | 840 | 841 | 842 | 843 | 844 | 845 | 846 | 847 | 848 | 849 | 850 | 851 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | 860 | 861 | 862 | 863 | 864 | 865 | 866 | 867 | 868 | 869 | 870 | 871 | 872 | 873 | 874 | 875 | 876 | 877 | 878 | 879 | 880 | 881 | 882 | 883 | 884 | 885 | 886 | 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | 899 | 900 | 905 | 906 | 907 | 908 | 909 | 910 | 911 | 912 | 913 | 914 | 915 | Android 916 | 917 | 922 | 923 | 924 | 925 | 926 | 927 | 928 | 933 | 934 | 935 | 936 | 937 | 938 | 1.6 939 | 940 | 945 | 946 | 947 | 948 | 949 | 950 | ProgrammerInterview 951 | 952 | 958 | 959 | 960 | 961 | 962 | 963 | 964 | 969 | 970 | 971 | 972 | 973 | 974 | 975 | 976 | 977 | 978 | 979 | 980 | 981 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/ProgrammerInterview.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/src/com/nowcoder/q1_1/Different.java: -------------------------------------------------------------------------------- 1 | package com.nowcoder.q1_1; 2 | 3 | public class Different { 4 | 5 | /** 6 | 请实现一个算法,确定一个字符串的所有字符是否全都不同。这里我们要求不允许使用额外的存储结构。 7 | 给定一个string iniString,请返回一个bool值,True代表所有字符全都不同,False代表存在相同的字符。 8 | 保证字符串中的字符为ASCII字符。字符串的长度小于等于3000。 9 | 测试样例: 10 | "aeiou" 11 | 返回:True 12 | "BarackObama" 13 | 返回:False 14 | */ 15 | public boolean checkDifferent(String str) { 16 | //要求ASCII编码(8位,共能显示0-255,共256个不同字符); 17 | //即就算字符串中每个字符都不同,长度也最多在256,一旦超出,说明一定有重复。 18 | if (str.length() > 256) { 19 | return false; 20 | } 21 | for (int i = 0; i < str.length(); i++) { 22 | for (int j = i + 1; j < str.length(); j++) { 23 | if (str.charAt(i) == str.charAt(j)) { 24 | return false; 25 | } 26 | } 27 | } 28 | return true; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/src/com/nowcoder/q1_2/Reverse.java: -------------------------------------------------------------------------------- 1 | package com.nowcoder.q1_2; 2 | 3 | public class Reverse { 4 | /** 5 | 请实现一个算法,在不使用额外数据结构和储存空间的情况下,翻转一个给定的字符串(可以使用单个过程变量)。 6 | 给定一个string iniString,请返回一个string,为翻转后的字符串。保证字符串的长度小于等于5000。 7 | 测试样例: 8 | "This is nowcoder" 9 | 返回:"redocwon si sihT" 10 | */ 11 | public String reverseString(String str) { 12 | if (str.length() > 5000) { 13 | return null; 14 | } 15 | String revStr = ""; 16 | for (int i = str.length() - 1; i >= 0; i--) { 17 | revStr = revStr + str.charAt(i); 18 | } 19 | return revStr; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/src/com/nowcoder/q1_3/Same.java: -------------------------------------------------------------------------------- 1 | package com.nowcoder.q1_3; 2 | 3 | import java.util.Arrays; 4 | 5 | public class Same { 6 | 7 | /** 8 | 给定两个字符串,请编写程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串。这里规定大小写为不同字符,且考虑字符串重点空格。 9 | 给定一个string stringA和一个string stringB,请返回一个bool,代表两串是否重新排列后可相同。保证两串的长度都小于等于5000。 10 | 测试样例: 11 | "This is nowcoder","is This nowcoder" 12 | 返回:true 13 | "Here you are","Are you here" 14 | 返回:false 15 | */ 16 | public boolean checkSam(String stringA, String stringB) { 17 | //字符串长度不等,那么一定不能重排转换 18 | if (stringA.length() != stringB.length()) { 19 | return false; 20 | } 21 | //利用Arrays类的静态方法sort对byte[]进行排序后再new为String,判断String是否相等 22 | byte[] bytesA = stringA.getBytes(); 23 | byte[] bytesB = stringB.getBytes(); 24 | Arrays.sort(bytesA); 25 | Arrays.sort(bytesB); 26 | //或在此直接使用 return Arrays.equals(bytesA, bytesB); 27 | String strA = new String(bytesA); 28 | String strB = new String(bytesB); 29 | if (strA.equals(strB)) { 30 | return true; 31 | } else { 32 | return false; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/src/com/nowcoder/q1_4/Replacement.java: -------------------------------------------------------------------------------- 1 | package com.nowcoder.q1_4; 2 | 3 | public class Replacement { 4 | /** 5 | 请编写一个方法,将字符串中的空格全部替换为“%20”。 6 | 假定该字符串有足够的空间存放新增的字符,并且知道字符串的真实长度(小于等于1000),同时保证字符串由大小写的英文字母组成。 7 | 给定一个string iniString 为原始的串,以及串的长度 int len, 返回替换后的string。 8 | 测试样例: 9 | "Mr John Smith”,13 10 | 返回:"Mr%20John%20Smith" 11 | ”Hello World”,12 12 | 返回:”Hello%20%20World” 13 | */ 14 | public String replaceSpace(String iniString, int length) { 15 | if (iniString.length() != length) { 16 | return null; 17 | } 18 | return iniString.replaceAll(" ", "%20"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/src/com/nowcoder/q1_5/Zipper.java: -------------------------------------------------------------------------------- 1 | package com.nowcoder.q1_5; 2 | 3 | public class Zipper { 4 | /** 5 | 利用字符重复出现的次数,编写一个方法,实现基本的字符串压缩功能。 6 | 比如,字符串“aabcccccaaa”经压缩会变成“a2b1c5a3”。若压缩后的字符串没有变短,则返回原先的字符串。 7 | 给定一个string iniString为待压缩的串(长度小于等于10000),保证串内字符均由大小写英文字母组成,返回一个string,为所求的压缩后或未变化的串。 8 | 测试样例 9 | "aabcccccaaa" 10 | 返回:"a2b1c5a3" 11 | "welcometonowcoderrrrr" 12 | 返回:"welcometonowcoderrrrr" 13 | */ 14 | public String zipString(String iniString) { 15 | String temp = iniString; 16 | String str = ""; 17 | 18 | while (true) { 19 | //截取首字母 20 | str = str + iniString.charAt(0); 21 | 22 | //计算首字母连续数,并续在新字符串串尾 23 | int i = 0; 24 | int count = 1; 25 | for (; i + 1 < iniString.length(); i++) { 26 | if (iniString.charAt(i) != iniString.charAt(i + 1)) { 27 | break; 28 | } else { 29 | count++; 30 | } 31 | } 32 | str = str + count; 33 | 34 | //判断是否越界 35 | if (i + 1 != iniString.length()) { 36 | //已经压缩的那部分字符串去掉,提取后部分字符串,并继续循环 37 | iniString = iniString.substring(i + 1); 38 | } else { 39 | //如果越界,表示已经提取完了,通过return跳出while并返回值 40 | return str.length() < temp.length() ? str:temp; 41 | } 42 | 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/src/com/nowcoder/q1_6/Transform.java: -------------------------------------------------------------------------------- 1 | package com.nowcoder.q1_6; 2 | 3 | public class Transform { 4 | /** 5 | 有一副由NxN矩阵表示的图像,这里每个像素用一个int表示,请编写一个算法,在不占用额外内存空间的情况下(即不使用缓存矩阵),将图像顺时针旋转90度。 6 | 给定一个NxN的矩阵,和矩阵的阶数N,请返回旋转后的NxN矩阵,保证N小于等于500,图像元素小于等于256。 7 | 测试样例: 8 | [[1,2,3],[4,5,6],[7,8,9]],3 9 | 返回:[[7,4,1],[8,5,2],[9,6,3]] 10 | */ 11 | public int[][] transformImage(int[][] mat, int n) { 12 | //最基础的解法,同时不符题意地使用额外内存空间 13 | int[][] done = new int[n][n]; 14 | for (int j = 0; j < n; j++) { 15 | for (int i = 0; i < n; i++) { 16 | done[j][i] = mat[n - 1 - i][j]; 17 | } 18 | } 19 | return done; 20 | } 21 | 22 | /**这个算法参考网友的思路,注意矩阵中次对角线互换的方式*/ 23 | /* 24 | 首先上下翻转,再按照主对角线翻转 25 | 1 2 3 7 8 9 7 4 1 26 | 4 5 6 --> 4 5 6 --> 8 5 2 27 | 7 8 9 1 2 3 9 6 3 28 | 如果是逆时针翻转则先翻主对角线,再上下翻转 29 | */ 30 | public int[][] transformImage2(int[][] mat, int n) { 31 | int a; 32 | for (int i = 0; i < n / 2; i++) { 33 | for (int j = 0; j < n; j++) { 34 | a = mat[i][j]; 35 | mat[i][j] = mat[n - i - 1][j]; 36 | mat[n - i - 1][j] = a; 37 | } 38 | } 39 | 40 | for (int i = 0; i < n; i++) { 41 | for (int j = 0; j < i; j++) { 42 | a = mat[i][j]; 43 | mat[i][j] = mat[j][i]; 44 | mat[j][i] = a; 45 | } 46 | } 47 | 48 | return mat; 49 | } 50 | 51 | 52 | 53 | } 54 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/src/com/nowcoder/q1_7/Clearer.java: -------------------------------------------------------------------------------- 1 | package com.nowcoder.q1_7; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class Clearer { 6 | /** 7 | 请编写一个算法,若N阶方阵中某个元素为0,则将其所在的行与列清零。 8 | 给定一个N阶方阵int[][](C++中为vector>)mat和矩阵的阶数n,请返回完成操作后的int[][]方阵(C++中为vector>),保证n小于等于300,矩阵中的元素为int范围内。 9 | 测试样例: 10 | [[1,2,3],[0,1,2],[0,0,1]] 11 | 返回:[[0,0,3],[0,0,0],[0,0,0]] 12 | */ 13 | public int[][] clearZero(int[][] mat, int n) { 14 | //思路: 15 | //找到元素为0的位置,记录其坐标 16 | //记录方式,i和j分别存入两个不同容器 17 | //遍历每个元素的坐标,如果其坐标存在容器中,则清零 18 | 19 | ArrayList listI = new ArrayList(); 20 | ArrayList listJ = new ArrayList(); 21 | 22 | for (int i = 0; i < n; i++) { 23 | for (int j = 0; j < n; j++) { 24 | if (mat[i][j] == 0) { 25 | listI.add(i); 26 | listJ.add(j); 27 | } 28 | } 29 | } 30 | 31 | for (int i = 0; i < n; i++) { 32 | for (int j = 0; j < n; j++) { 33 | if (listJ.contains(j) || listI.contains(i)) { 34 | mat[i][j] = 0; 35 | } 36 | } 37 | } 38 | 39 | return mat; 40 | } 41 | 42 | /** 43 | 这个是在讨论帖看到的网友的版本,思路是类似的,可是更加巧妙,没有用到集合类;相当于建立了一个映射板,把要清零的元素进行了标记。 44 | 这里还巧妙利用了数组初始化的特性: 45 | 如果没有明确的初始化数组元素,那么数组就会用默认的类型值初始化, 46 | 例如假若没有初始化整型数组,元素都将默认值为0,没有初始化的boolean值是false,对象数组是null。 47 | */ 48 | public int[][] clearZero2(int[][] mat, int n) { 49 | boolean[] rowArray = new boolean[n]; 50 | boolean[] columnArray = new boolean[n]; 51 | //记录为0的位置,把相应的行列位置设为true 52 | for(int i=0; iBCDA->CDAB->DABC->ABCD ....... 19 | //假设我们把前面移走的数据进行保留: 20 | //ABCD->ABCDA->ABCDAB->ABCDABC->ABCDABCD..... 21 | //因此看出,对s1做循环移位,所得字符串都将是字符串s1s1的子字符串。如果s2可以由s1循环移位得到,则一定可以在s1s1上。 22 | 23 | int length1 = s1.length(); 24 | int length2 = s2.length(); 25 | if (length1 == 0 || length2 == 0) { 26 | return false; 27 | } 28 | String str = s1 + s1; 29 | if (str.indexOf(s2) != -1) { 30 | return true; 31 | } else { 32 | return false; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/src/com/nowcoder/q2_2/ListNode.java: -------------------------------------------------------------------------------- 1 | package com.nowcoder.q2_2; 2 | 3 | public class ListNode { 4 | int val; 5 | ListNode next = null; 6 | 7 | ListNode(int val) { 8 | this.val = val; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/src/com/nowcoder/q2_2/Solution.java: -------------------------------------------------------------------------------- 1 | package com.nowcoder.q2_2; 2 | 3 | public class Solution { 4 | /** 5 | 输入一个链表,输出该链表中倒数第k个结点。 6 | */ 7 | public ListNode FindKthToTail(ListNode head,int k) { 8 | //看样子数据结构需要好好补补... 9 | //思路:参考网友 10 | //两个指针,先让第一个指针和第二个指针都指向头结点,然后再让第一个指针走(k-1)步,到达第k个节点。 11 | //然后两个指针同时往后移动,当第一个结点到达末尾的时候,第二个结点所在位置就是倒数第k个节点了。 12 | 13 | if (head == null || k <= 0) { 14 | return null; 15 | } 16 | 17 | ListNode pre = head; 18 | ListNode last = head; 19 | 20 | for (int i = 1; i < k; i++) { 21 | //防止k大于链表长度 22 | if (pre.next != null) { 23 | pre = pre.next; 24 | } else { 25 | return null; 26 | } 27 | } 28 | 29 | //第二个指针开始移动 30 | while (pre.next != null) { 31 | pre = pre.next; 32 | last = last.next; 33 | } 34 | 35 | return last; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/src/com/nowcoder/q2_3/ListNode.java: -------------------------------------------------------------------------------- 1 | package com.nowcoder.q2_3; 2 | 3 | public class ListNode { 4 | int val; 5 | ListNode next = null; 6 | 7 | ListNode(int val) { 8 | this.val = val; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/src/com/nowcoder/q2_3/Remove.java: -------------------------------------------------------------------------------- 1 | package com.nowcoder.q2_3; 2 | 3 | /** 4 | 实现一个算法,删除单向链表中间的某个结点,假定你只能访问该结点。 5 | 给定带删除的节点,请执行删除操作,若该节点为尾节点,返回false,否则返回true 6 | */ 7 | public class Remove { 8 | //思路:参考网友 9 | //首先,不能访问之前的节点,但是可以访问后续节点。 10 | //然后,对于尾节点,直接delete掉,返回false即可。 11 | //最后,对于中间节点简记为A = pNode,利用其后续节点B = pNode->next和C = pNode->next->next变相删除。 12 | //即 A--->B--->C,要删除A。这样变相删除:把B的值给A的值域,把C的地址赋给A的地址域。 13 | public boolean removeNode(ListNode pNode) { 14 | //判断是否尾节点 15 | if (pNode.next == null) { 16 | return false; 17 | } else { 18 | //通过覆盖变相删除节点 19 | pNode.val = pNode.next.val; //将下个节点的值移动到当前节点 20 | pNode.next = pNode.next.next; //然后指向下下个节点 21 | } 22 | return true; 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/src/com/nowcoder/q2_4/ListNode.java: -------------------------------------------------------------------------------- 1 | package com.nowcoder.q2_4; 2 | 3 | public class ListNode { 4 | int val; 5 | ListNode next = null; 6 | 7 | ListNode(int val) { 8 | this.val = val; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/src/com/nowcoder/q2_4/Partition.java: -------------------------------------------------------------------------------- 1 | package com.nowcoder.q2_4; 2 | 3 | /** 4 | 编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前 5 | 给定一个链表的头指针 ListNode* pHead,请返回重新排列后的链表的头指针。注意:分割以后保持原来的数据顺序不变。 6 | */ 7 | public class Partition { 8 | //思路:参考网友 9 | //创建两个链表,一个链表是存放小于x的元素,另一个链表存放大于等于x的元素 10 | //然后遍历一遍原有链表,将小于x元素的节点加到第一个链表上,将大于等于x元素的节点加到第二个链表上。便可实现分割。 11 | public ListNode partition(ListNode pHead, int x) { 12 | //如果为空或只有当前节点 13 | if (pHead == null || pHead.next == null) { 14 | return pHead; 15 | } 16 | 17 | ListNode curNode = pHead; 18 | ListNode sListNode = new ListNode(-1); 19 | ListNode bListNode = new ListNode(-1); 20 | ListNode sTemp = sListNode; 21 | ListNode bTemp = bListNode; 22 | 23 | while (curNode != null) { 24 | if (curNode.val < x) { 25 | sTemp.next = new ListNode(curNode.val); 26 | sTemp = sTemp.next; 27 | } else { 28 | bTemp.next = new ListNode(curNode.val); 29 | bTemp = bTemp.next; 30 | } 31 | 32 | if (curNode.next == null) { 33 | break; 34 | } 35 | 36 | curNode = curNode.next; 37 | } 38 | 39 | sTemp.next = bListNode.next; 40 | 41 | return sListNode.next; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/src/com/nowcoder/q2_4/TestPartition.java: -------------------------------------------------------------------------------- 1 | package com.nowcoder.q2_4; 2 | 3 | public class TestPartition { 4 | 5 | 6 | public static void main(String[] args) { 7 | ListNode n1 = new ListNode(1); 8 | ListNode n2 = new ListNode(2); 9 | ListNode n3 = new ListNode(3); 10 | ListNode n4 = new ListNode(4); 11 | ListNode n5 = new ListNode(5); 12 | 13 | //2,4,3,1,5 14 | n2.next = n4; 15 | n4.next = n3; 16 | n3.next = n1; 17 | n1.next = n5; 18 | 19 | ListNode result = new Partition().partition(n2, 3); 20 | while (result != null) { 21 | System.out.println(result.val); 22 | result = result.next; 23 | } 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/src/com/nowcoder/q2_5/ListNode.java: -------------------------------------------------------------------------------- 1 | package com.nowcoder.q2_5; 2 | 3 | public class ListNode { 4 | int val; 5 | ListNode next = null; 6 | 7 | ListNode(int val) { 8 | this.val = val; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/src/com/nowcoder/q2_5/Plus.java: -------------------------------------------------------------------------------- 1 | package com.nowcoder.q2_5; 2 | 3 | /** 4 | 有两个用链表表示的整数,每个结点包含一个数位。这些数位是反向存放的,也就是个位排在链表的首部。 5 | 编写函数对这两个整数求和,并用链表形式返回结果。 6 | 给定两个链表ListNode* A,ListNode* B,请返回A+B的结果(ListNode*)。 7 | 测试样例: 8 | {1,2,3},{3,2,1} 9 | 返回:{4,4,4} 10 | */ 11 | public class Plus { 12 | //思路:按照小学数学中学习的加法原理从末尾到首位,对每一位对齐相加即可 13 | public ListNode plusAB(ListNode a, ListNode b) { 14 | /* 15 | //结果的head,最终其next就为所需的ListNode 16 | ListNode resultHead = new ListNode(-1); 17 | 18 | //用来进行运算 19 | ListNode resultCurrent = resultHead; 20 | 21 | //进位 22 | int addToNextDigit = 0; 23 | 24 | //只有在a为null、b为null且进位为0的情况下,该循环才终止 25 | while (a != null || b != null || addToNextDigit != 0) { 26 | //确定数位上的值(都为空时算为0) 27 | int aVal = a != null ? a.val : 0; 28 | int bVal = b != null ? b.val : 0; 29 | 30 | //计算同位相加再加上进位的总和 31 | int sum = aVal + bVal + addToNextDigit; 32 | //计算加后的位值 33 | int nodeDigit = sum % 10; 34 | //计算加后的进位值 35 | addToNextDigit = sum / 10; 36 | 37 | //存储计算结果 38 | resultCurrent.next = new ListNode(nodeDigit); 39 | 40 | //移位,以进行下一位的计算(三元计算避免nullPointer) 41 | resultCurrent = resultCurrent.next; 42 | a = a != null ? a.next : null; 43 | b = b != null ? b.next : null; 44 | } 45 | 46 | return resultHead.next; 47 | */ 48 | 49 | ListNode headNode = new ListNode(-1); 50 | ListNode curNode = headNode; 51 | int nextVal = 0; 52 | 53 | while (!(a == null && b == null && nextVal == 0)) { 54 | int addA = a == null ? 0 : a.val; 55 | int addB = b == null ? 0 : b.val; 56 | 57 | int sum = addA + addB + nextVal; 58 | 59 | 60 | curNode.next = new ListNode(sum % 10); 61 | nextVal = sum / 10; 62 | 63 | curNode = curNode.next; 64 | a = a == null ? null : a.next; 65 | b = b == null ? null : b.next; 66 | } 67 | 68 | return headNode.next; 69 | 70 | } 71 | 72 | public static void main(String[] args) { 73 | //192 + 169 = 361 --> 163 74 | ListNode n1 = new ListNode(1); 75 | ListNode n2 = new ListNode(1); 76 | ListNode n3 = new ListNode(0); 77 | 78 | ListNode n4 = new ListNode(0); 79 | /* 80 | ListNode n5 = new ListNode(6); 81 | ListNode n6 = new ListNode(1); 82 | */ 83 | 84 | n1.next = n2; 85 | n2.next = n3; 86 | 87 | 88 | 89 | Plus test = new Plus(); 90 | ListNode result = test.plusAB(n1, n4); 91 | while (true) { 92 | System.out.println(result.val); 93 | result = result.next; 94 | if (result.next == null) { 95 | System.out.println(result.val); 96 | break; 97 | } 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/src/com/nowcoder/q2_7/ListNode.java: -------------------------------------------------------------------------------- 1 | package com.nowcoder.q2_7; 2 | 3 | public class ListNode { 4 | int val; 5 | ListNode next = null; 6 | 7 | ListNode(int val) { 8 | this.val = val; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/src/com/nowcoder/q2_7/Palindrome.java: -------------------------------------------------------------------------------- 1 | package com.nowcoder.q2_7; 2 | 3 | import java.util.ArrayList; 4 | 5 | /** 6 | 请编写一个函数,检查链表是否为回文。 7 | 给定一个链表ListNode* pHead,请返回一个bool,代表链表是否为回文。 8 | 测试样例: 9 | {1,2,3,2,1} 10 | 返回:true 11 | {1,2,3,2,3} 12 | 返回:false 13 | */ 14 | public class Palindrome { 15 | //思路: 16 | //回文的特性,逆序和正序内容一样,那么得到一个逆序的链表,来相互比较,相同则true,否则false 17 | public boolean isPalindrome(ListNode pHead) { 18 | //得到正序的链表 19 | ListNode normalNode = pHead; 20 | 21 | /* 22 | //得到逆序的链表(将其值存到集合中,再反向取出变成逆序链表) 23 | ArrayList normalSeq = new ArrayList(); 24 | while (pHead != null) { 25 | normalSeq.add(pHead.val); 26 | if (pHead.next == null) { 27 | break; 28 | } 29 | pHead = pHead.next; 30 | } 31 | ListNode inverseNode = new ListNode(-1); 32 | ListNode curNode = inverseNode; 33 | for (int i = normalSeq.size() - 1; i >= 0; i--) { 34 | curNode.next = new ListNode((Integer) normalSeq.get(i)); 35 | curNode = curNode.next; 36 | } 37 | inverseNode = inverseNode.next; 38 | 39 | //将逆序的链表值分别取出和原链表对比,一旦出现不同则false 40 | while (inverseNode != null) { 41 | if (inverseNode.val != normalNode.val) { 42 | return false; 43 | } else { 44 | inverseNode = inverseNode.next == null? null: inverseNode.next; 45 | normalNode = normalNode.next == null? null: normalNode.next; 46 | } 47 | } 48 | 49 | return true; 50 | */ 51 | 52 | 53 | //看了网友思路,其实这里我走了弯路,可以直接与集合中的数比较,没必要再来个反向链表 54 | //所以优化的话如下: 55 | 56 | //得到逆序的链表(将其值存到集合中,再反向取出和正向链表比较) 57 | ArrayList normalSeq = new ArrayList(); 58 | while (pHead != null) { 59 | normalSeq.add(pHead.val); 60 | if (pHead.next == null) { 61 | break; 62 | } 63 | pHead = pHead.next; 64 | } 65 | 66 | for (int i = normalSeq.size() - 1; i >= 0; i--) { 67 | if (normalNode.val != (Integer) normalSeq.get(i)) { 68 | return false; 69 | } else { 70 | normalNode = normalNode.next; 71 | } 72 | } 73 | 74 | return true; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/src/com/nowcoder/q3_3/SetOfStacks.java: -------------------------------------------------------------------------------- 1 | package com.nowcoder.q3_3; 2 | 3 | import java.util.ArrayList; 4 | 5 | /** 6 | 请实现一种数据结构SetOfStacks,由多个栈组成,其中每个栈的大小为size,当前一个栈填满时,新建一个栈。 7 | 该数据结构应支持与普通栈相同的push和pop操作。 8 | 给定一个操作序列int[][2] ope,每个元素中({1, 1024})的第一个数代表操作类型, 9 | 若为1,则为push操作,后一个数为应push的数字; 10 | 若为2,则为pop操作,后一个数无意义。 11 | 请返回一个int[][],为完成所有操作后的SetOfStacks,顺序应为从下到上,默认初始的SetOfStacks为空。保证数据合法。 12 | */ 13 | public class SetOfStacks { 14 | //思路: 15 | //把所有的操作集成在单个List上,最终再根据size将List分割返回 16 | public ArrayList> setOfStacks(int[][] ope, int size) { 17 | 18 | ArrayList collection = new ArrayList(); 19 | ArrayList> result = new ArrayList>(); 20 | 21 | //把push和pop的结果整合到一个List中 22 | for (int i = 0; i < ope.length; i++) { 23 | if (ope[i][0] == 1) { //push 24 | collection.add(ope[i][1]); 25 | 26 | } else if (ope[i][0] == 2) { //pop 27 | if (collection.size() == 0) { //如果在栈为空的情况下使用pop,出错返回null 28 | System.out.println("Error Input"); 29 | return null; 30 | } 31 | collection.remove(collection.size() - 1); 32 | } 33 | } 34 | 35 | //输出分割后的结果 36 | if (collection.size() == 0) { 37 | return null; 38 | } else { 39 | //如果只有一个栈元素 40 | if (collection.size() < size) { 41 | result.add(collection); 42 | return result; 43 | } 44 | 45 | //如果有多个栈元素 46 | //确定要分割的份数 47 | int count = collection.size() % size == 0 ? collection.size() / size : collection.size() / size + 1; 48 | 49 | //循环添加 50 | int index = 0; 51 | for (int i = 0; i < count; i++) { 52 | ArrayList temp = new ArrayList(size); 53 | for (int j = 0; j < size; j++) { 54 | if (index < collection.size()) { 55 | temp.add(collection.get(index)); 56 | index++; 57 | } 58 | } 59 | result.add(temp); 60 | } 61 | } 62 | 63 | return result; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/src/com/nowcoder/q3_5/Solution.java: -------------------------------------------------------------------------------- 1 | package com.nowcoder.q3_5; 2 | 3 | import java.util.Stack; 4 | 5 | /** 6 | 用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。 7 | */ 8 | public class Solution { 9 | //思路: 10 | //入队:将元素进栈A 11 | //出队:判断栈B是否为空,如果为空,则将栈A中所有元素pop,并push进栈B,栈B出栈;如果不为空,栈B直接出栈。 12 | Stack stack1 = new Stack(); 13 | Stack stack2 = new Stack(); 14 | 15 | public void push(int node) { 16 | stack1.push(node); 17 | } 18 | 19 | public int pop() { 20 | if(stack1.empty()&&stack2.empty()){ 21 | throw new RuntimeException("Queue is empty!"); 22 | } 23 | if(stack2.empty()){ 24 | while(!stack1.empty()){ 25 | stack2.push(stack1.pop()); 26 | } 27 | } 28 | return stack2.pop(); 29 | } 30 | 31 | /** 32 | 扩展:关于java.util.Stack 33 | 34 | E push(E item) 35 | 把项压入堆栈顶部。 36 | 37 | E pop() 38 | 移除堆栈顶部的对象,并作为此函数的值返回该对象。 39 | 40 | E peek() 41 | 查看堆栈顶部的对象,但不从堆栈中移除它。 42 | 43 | boolean empty() 44 | 测试堆栈是否为空。 45 | 46 | int search(Object o) 47 | 返回对象在堆栈中的位置,以 1 为基数。 48 | */ 49 | } 50 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/src/com/nowcoder/q3_6/TwoStacks.java: -------------------------------------------------------------------------------- 1 | package com.nowcoder.q3_6; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Stack; 5 | 6 | /** 7 | 请编写一个程序,按升序对栈进行排序(即最大元素位于栈顶) 8 | 要求最多只能使用一个额外的栈存放临时数据,但不得将元素复制到别的数据结构中。 9 | 给定一个int[] numbers(C++中为vector<int>),其中第一个元素为栈顶,请返回排序后的栈。 10 | 请注意这是一个栈,意味着排序过程中你只能访问到第一个元素。 11 | 测试样例: 12 | [1,2,3,4,5] 13 | 返回:[5,4,3,2,1] 14 | */ 15 | public class TwoStacks { 16 | //思路: 17 | //将原栈A的栈顶弹出放到栈B后,继续弹出栈顶和B的栈顶比较 18 | //如果A.top > B.top,则直接压入 19 | //如果A.top < B.top,B.top压入A,A.top循环比较后再压入B。 20 | public ArrayList twoStacksSort(int[] numbers) { 21 | //如果传参为空或元素为0 22 | if (numbers.length == 0 || numbers == null) { 23 | return null; 24 | } 25 | 26 | //初始化栈 27 | Stack origin = new Stack(); 28 | int index = numbers.length - 1; 29 | for (int i = index; i >= 0; i--) { 30 | origin.push(numbers[i]); 31 | } 32 | 33 | //初始化临时栈和临时变量 34 | Stack tempStack = new Stack(); 35 | int temp; 36 | 37 | 38 | if (tempStack.empty()) { 39 | tempStack.push(origin.pop()); 40 | } 41 | while (!origin.empty()) { 42 | //弹出a.top and b.top 43 | int a = origin.pop(); 44 | int b = tempStack.pop(); 45 | 46 | //如果a.top < b.top 47 | if (a < b) { 48 | //b.top 压入到 a 49 | origin.push(b); 50 | //循环比较b.top,凡是大于a.top的均压入a,最后将a.top压入 51 | while (!tempStack.empty()) { 52 | b = tempStack.pop(); 53 | if (a < b) { 54 | origin.push(b); 55 | } else { 56 | tempStack.push(b); 57 | break; 58 | } 59 | } 60 | tempStack.push(a); 61 | } else { 62 | //如果a.top > b.top,直接压入 63 | tempStack.push(b); 64 | tempStack.push(a); 65 | } 66 | } 67 | 68 | ArrayList result = new ArrayList(); 69 | while (!tempStack.empty()) { 70 | result.add(tempStack.pop()); 71 | } 72 | 73 | return result; 74 | } 75 | 76 | 77 | public static void main(String[] args) { 78 | int[] testStack = new int[]{1, 2, 3, 4, 5}; 79 | ArrayList result = new TwoStacks().twoStacksSort(testStack); 80 | for (Integer bean : result) { 81 | System.out.print(bean + ","); 82 | } 83 | 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /algorithm/ProgrammerInterview/src/com/nowcoder/q3_7/CatDogAsylum.java: -------------------------------------------------------------------------------- 1 | package com.nowcoder.q3_7; 2 | 3 | 4 | import java.util.ArrayList; 5 | 6 | /** 7 | 有家动物收容所只收留猫和狗,但有特殊的收养规则,收养人有两种收养方式: 8 | 1、直接收养所有动物中最早进入收容所的; 9 | 2、选择收养的动物类型(猫或狗),并收养该种动物中最早进入收容所的。 10 | 给定一个操作序列int[][2] ope代表所有事件。 11 | 若第一个元素为1,则代表有动物进入收容所,第二个元素为动物的编号,正数代表狗,负数代表猫; 12 | 若第一个元素为2,则代表有人收养动物,第二个元素若为0,则采取第一种收养方式,若为1,则指定收养狗,若为-1则指定收养猫。 13 | 请按顺序返回收养的序列。若出现不合法的操作,即没有可以符合领养要求的动物,则将这次领养操作忽略。 14 | 测试样例: 15 | {{1,1},{1,-1},{2,0},{2,-1}} 16 | 返回:{1,-1} 17 | */ 18 | public class CatDogAsylum { 19 | //思路: 20 | //按顺序思路执行即可 21 | public ArrayList asylum(int[][] ope) { 22 | //创建动物序列和结果序列 23 | ArrayList animals = new ArrayList(); 24 | ArrayList result = new ArrayList(); 25 | 26 | //遍历将动物序列,判断并执行操作 27 | for (int i = 0; i < ope.length; i++) { 28 | if (ope[i][0] == 1) { 29 | animals.add(ope[i][1]); 30 | } else { 31 | //输入了范围外的数字,不符要求 32 | if (ope[i][0] != 2) { 33 | return null; 34 | } 35 | 36 | switch (ope[i][1]) { 37 | //收养最早进入收养所的动物 38 | case 0: 39 | if (animals.size() == 0) { 40 | break; 41 | } 42 | result.add(animals.get(0)); 43 | animals.remove(0); 44 | break; 45 | 46 | //收养最早进入的狗 47 | case 1: 48 | if (animals.size() == 0) { 49 | break; 50 | } 51 | 52 | int countDog = 0; //初始为0,如果遍历完仍为0,说明没有狗可以取,操作取消 53 | for (int j = 0; j < animals.size(); j++) { 54 | if (animals.get(j) > 0) { 55 | countDog++; 56 | result.add(animals.get(j)); 57 | animals.remove(j); 58 | break; 59 | } 60 | } 61 | 62 | if (countDog == 0) { 63 | break; 64 | } 65 | 66 | break; 67 | 68 | //收养最早进入的猫 69 | case -1: 70 | if (animals.size() == 0) { 71 | break; 72 | } 73 | 74 | int countCat = 0; //初始为0,如果遍历完仍为0,说明没有猫可以取,操作取消 75 | for (int j = 0; j < animals.size(); j++) { 76 | if (animals.get(j) < 0) { 77 | countCat++; 78 | result.add(animals.get(j)); 79 | animals.remove(j); 80 | break; 81 | } 82 | } 83 | 84 | if (countCat == 0) { 85 | break; 86 | } 87 | 88 | break; 89 | 90 | //输入了规定范围外的数字,不符要求 91 | default: 92 | return null; 93 | } 94 | } 95 | } 96 | 97 | return result; 98 | } 99 | 100 | //测试 101 | public static void main(String[] args) { 102 | int[][] ope = {{1,-3},{1,-6},{1,10},{1,3},{2,0},{1,19},{2,-1},{1,-81},{1,36},{2,0},{2,1},{1,66},{2,0},{1,-13},{2,0},{2,-1},{2,0},{1,29},{2,1},{2,1},{2,1},{1,56},{1,-99},{2,-1},{2,-1},{1,79},{1,-25},{1,-6},{1,63},{1,48},{1,-40},{1,56},{2,1},{1,28},{1,78},{1,20},{1,18},{1,20},{1,-92},{1,87},{2,0},{1,34},{2,-1},{1,96},{1,38},{2,0},{2,-1},{1,17},{1,13},{1,3},{1,-26},{2,0},{2,0},{2,-1},{2,1},{2,0},{1,-78},{1,57},{1,71},{1,-11},{2,-1},{1,-28},{1,-28},{1,-87},{1,-86},{1,-9},{1,50},{2,1},{2,0},{1,65},{1,-98},{1,-54},{2,0},{2,-1},{1,84},{1,-72},{1,-42},{1,77},{1,-61},{1,-61},{1,-11},{1,94},{2,1},{1,93},{2,-1},{2,-1},{1,43},{2,-1},{1,-72},{2,-1},{1,-31},{1,-41},{1,-85},{1,-2},{2,0},{1,94},{1,80},{1,-86},{1,-83},{1,-20},{1,49},{1,-47},{1,46},{1,34},{2,1},{2,0},{1,-41},{2,1},{2,-1},{1,-44},{1,100},{1,-85},{1,-25},{1,-8},{1,-69},{1,13},{1,82},{2,1},{1,-41},{1,-44},{1,22},{1,-72},{1,-16},{1,-11},{1,65},{1,-66},{1,25},{1,-31},{1,-63},{2,1},{1,86},{1,2},{1,6},{1,-42},{1,-9},{1,76},{1,54},{2,0},{2,1}} ; 103 | CatDogAsylum test = new CatDogAsylum(); 104 | ArrayList result = test.asylum(ope); 105 | for (Integer temp : result) { 106 | System.out.print(temp + " "); 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /algorithm/README.md: -------------------------------------------------------------------------------- 1 | # 概述 2 | 该内容主要来源于牛客网的几个编程训练题库: 3 | - [程序员面试金典][1] 4 | - [2016校招真题][2] 5 | - [华为机试在线训练][3] 6 |
7 |
8 | 我啊,就一道一道地来练习吧。
9 | 详见代码。 10 | 11 | [1]: https://www.nowcoder.com/ta/cracking-the-coding-interview 12 | [2]: https://www.nowcoder.com/ta/2016test 13 | [3]: https://www.nowcoder.com/ta/huawei 14 | 15 | 16 | -------------------------------------------------------------------------------- /algorithm/Sort/.idea/.name: -------------------------------------------------------------------------------- 1 | Sort -------------------------------------------------------------------------------- /algorithm/Sort/.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /algorithm/Sort/.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /algorithm/Sort/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /algorithm/Sort/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 27 | 28 | 29 | 30 | 31 | 1.6 32 | 33 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /algorithm/Sort/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /algorithm/Sort/.idea/scopes/scope_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /algorithm/Sort/.idea/uiDesigner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /algorithm/Sort/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /algorithm/Sort/.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 13 | 14 | 15 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 39 | 40 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 134 | 135 | 136 | 137 | 140 | 141 | 144 | 145 | 146 | 147 | 150 | 151 | 154 | 155 | 158 | 159 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 190 | 191 | 206 | 207 | 208 | 209 | 212 | 213 | 228 | 229 | 230 | 234 | 235 | 242 | 243 | 244 | 245 | 263 | 270 | 271 | 272 | 283 | 284 | 285 | 298 | 299 | 300 | 301 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | localhost 331 | 5050 332 | 333 | 334 | 335 | 336 | 337 | 338 | 1483765590676 339 | 1483765590676 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 377 | 378 | 389 | 431 | 432 | 433 | 434 | 435 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | -------------------------------------------------------------------------------- /algorithm/Sort/Sort.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /algorithm/Sort/src/com/code/sort/BubbleSort.java: -------------------------------------------------------------------------------- 1 | package com.code.sort; 2 | 3 | /** 4 | * 冒泡排序是交换排序中一种简单的排序方法。 5 | * 它的基本处理思想是通过对相邻两个数据的比较及其交换来达到排序的目的。 6 | */ 7 | public class BubbleSort { 8 | 9 | /** 10 | * 冒泡排序法(升序,从小到大) 11 | * @param arr 12 | * @return 13 | */ 14 | public static int[] bubbleSortMinToMax(int[] arr) { 15 | int len = arr.length - 1; 16 | while (len >= 1) { 17 | for (int i = 0; i < len; i++) { 18 | int temp; 19 | if (arr[i] > arr[i + 1]) { 20 | temp = arr[i]; 21 | arr[i] = arr[i + 1]; 22 | arr[i + 1] = temp; 23 | } 24 | } 25 | len--; 26 | } 27 | return arr; 28 | } 29 | 30 | /** 31 | * 冒泡排序法(降序,从大到小) 32 | * @param arr 33 | * @return 34 | */ 35 | public static int[] bubbleSortMaxToMin(int[] arr) { 36 | int len = arr.length - 1; 37 | while (len >= 1) { 38 | for (int i = 0; i < len; i++) { 39 | int temp; 40 | if (arr[i] < arr[i + 1]) { 41 | temp = arr[i]; 42 | arr[i] = arr[i + 1]; 43 | arr[i + 1] = temp; 44 | } 45 | } 46 | len--; 47 | } 48 | return arr; 49 | } 50 | 51 | /** 52 | * test 53 | */ 54 | public static void main(String[] args) { 55 | int[] test = new int[]{51, 38, 49, 27, 62, 5, 16}; 56 | test = BubbleSort.bubbleSortMinToMax(test); 57 | for (int temp : test) { 58 | System.out.print(temp + ", "); 59 | } 60 | 61 | System.out.println(); 62 | 63 | test = BubbleSort.bubbleSortMaxToMin(test); 64 | for (int temp : test) { 65 | System.out.print(temp + ", "); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /algorithm/Sort/src/com/code/sort/SelectionSort.java: -------------------------------------------------------------------------------- 1 | package com.code.sort; 2 | 3 | /** 4 | * 选择排序的基本思想是每一趟(假设是第i趟)处理都是从n-i+1个数据中选择一个数据最小(或最大)的作为有序序列中的第i个数据。 5 | * 其中最简单的一种称为直接选择排序。 6 | */ 7 | public class SelectionSort { 8 | 9 | /** 10 | * 直接选择排序法(升序,从小到大) 11 | * @param arr 12 | * @return 13 | */ 14 | public static int[] selectionSortMinToMax(int[] arr) { 15 | int min; 16 | for (int j = 0; j < arr.length - 1; j++) { 17 | min = j; 18 | //标记最小值的位置 19 | for (int i = j; i < arr.length; i++) { 20 | if (arr[i] < arr[min]) { 21 | min = i; 22 | } 23 | } 24 | //交换最小值到arr[j] 25 | int temp = arr[j]; 26 | arr[j] = arr[min]; 27 | arr[min] = temp; 28 | } 29 | return arr; 30 | } 31 | 32 | 33 | /** 34 | * 直接选择排序法(降序,从大到小) 35 | * @param arr 36 | * @return 37 | */ 38 | public static int[] selectionSortMaxToMin(int[] arr) { 39 | int min; 40 | for (int j = 0; j < arr.length - 1; j++) { 41 | min = j; 42 | for (int i = j; i < arr.length; i++) { 43 | if (arr[i] > arr[min]) { 44 | min = i; 45 | } 46 | } 47 | int temp = arr[j]; 48 | arr[j] = arr[min]; 49 | arr[min] = temp; 50 | } 51 | return arr; 52 | } 53 | 54 | 55 | /** 56 | * test 57 | */ 58 | public static void main(String[] args) { 59 | int[] test = new int[]{51, 38, 49, 27, 62, 5, 16}; 60 | test = SelectionSort.selectionSortMinToMax(test); 61 | for (int temp : test) { 62 | System.out.print(temp + ", "); 63 | } 64 | 65 | System.out.println(); 66 | 67 | test = SelectionSort.selectionSortMaxToMin(test); 68 | for (int temp : test) { 69 | System.out.print(temp + ", "); 70 | } 71 | 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /pics/etc/IloveStudy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulk-dev/MyTraining/9c491513e759d7bd07f723fcd2223ba1ba3380c1/pics/etc/IloveStudy.jpg -------------------------------------------------------------------------------- /pics/sql/sql_student_01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulk-dev/MyTraining/9c491513e759d7bd07f723fcd2223ba1ba3380c1/pics/sql/sql_student_01.jpg -------------------------------------------------------------------------------- /question/README.md: -------------------------------------------------------------------------------- 1 | # 概述 2 | 这里放一些对自己而言比较典型的,或者有价值的一些面试题。 3 | 4 | # 试题 5 | 1、下面选项中,哪些是interface中合法方法定义?() 6 | - [x] public void main(String [] args); 7 | - private int getSum(); 8 | - [x] boolean setFlag(Boolean [] test); 9 | - [x] public float get(int x); 10 |
11 | 解析:
12 | `interface中的方法默认为public abstract 的 ,变量默认为public static final`
13 | java程序的入口必须是static类型的,接口中不允许有static类型的方法。A项没有static修饰符,可以作为普通的方法。而且接口中的方法必须是public的。想想借口就是为了让别人实现的,相当于标准,标准不允许别人使用是不合理的,所以接口中的方法必须是public。C项中,接口中的方法默认是public的。D项属于正常的方法。所以答案是:ACD 14 | 15 | --- 16 | 17 | 2、下列Java代码中的变量a、b、c分别在内存的____存储区存放。 18 | 19 | ``` stylus 20 | class A { 21 | private String a = “aa”; 22 | public boolean methodB() { 23 | String b = “bb”; 24 | final String c = “cc”; 25 | } 26 | } 27 | ``` 28 | - 堆区、堆区、堆区 29 | - 堆区、栈区、堆区 30 | - [x] 堆区、栈区、栈区 31 | - 堆区、堆区、栈区 32 | - 静态区、栈区、堆区 33 | - 静态区、栈区、栈区 34 | 35 | 解析:
36 | a是类中的成员变量,存放在堆区;b、c都是方法中的局部变量,存放在栈区。
37 | 参考《Head First Java》p236,对象的生存空间(堆,heap)和方法调用及变量的生存空间(栈,stack),以及基本数据类型变量也放在栈上。实例变量存在于所属的对象中,局部变量和方法参数都被声明在方法中。
38 | 要理解的是,**对象本身只会存在堆上**,即如果方法的局部变量是个对对象的引用,也只有变量本身放在栈上,所引用的对象不会放到栈里。 39 | 40 | --- 41 | 42 | 3、ArrayList list = new ArrayList(20);中的list扩充几次 43 | - [x] 0 44 | - 1 45 | - 2 46 | - 3 47 | 解析:
48 | 1. ArrayList底层是数组,默认构造函数的创建初始容量是10,动态扩容的公式是:新容量=就容量/2 + 旧容量 + 1。比如初始容量为4,每次扩容后:4 -> 7 -> 11 -> 17 -> 26; 49 | 2. 这里调用的是一个可以指定初始容量的构造函数,直接初始化大小为20,所以没有扩容。 50 | 51 | --- 52 | 53 | ``` stylus 54 | byte b1=1,b2=2,b3,b6; 55 | final byte b4=4,b5=6; 56 | b6=b4+b5; 57 | b3=(b1+b2); 58 | System.out.println(b3+b6); 59 | ``` 60 | 4、关于上面代码片段叙述正确的是() 61 | - 输出结果:13 62 | - 语句:b6=b4+b5编译出错 63 | - [x] 语句:b3=b1+b2编译出错 64 | - 运行期抛出异常 65 | 解析:
66 | 被final修饰的变量是常量,这里的b6=b4+b5可以看成是b6=10,在编译时就已经变为b6=10了。
67 | 而b1和b2是byte类型,java中进行计算时候将他们提升为int类型,再进行计算,b1+b2计算后已经是int类型,赋值给b3,b3是byte类型,类型不匹配,编译不会通过,需要进行强制转换。
68 | Java中没有final修饰的的byte,short,char进行计算时都会提升为int类型。
69 | 70 | > ①所有的byte,short,char型的值将被提升为int型; ②如果有一个操作数是long型,计算结果是long型; 71 | > ③如果有一个操作数是float型,计算结果是float型; ④如果有一个操作数是double型,计算结果是double型; 72 | > 而声明为final的变量会被JVM优化,第6行相当于 b6 = 10 73 | 74 | --- 75 | 76 | ``` stylus 77 | 1.public class Enclosingone 78 | 2.{ 79 | 3. public class InsideOne {} 80 | 4. 81 | 5.} 82 | 6.public class inertest 83 | 7.{ 84 | 8. public static void main(string[]args) 85 | 9. { 86 | 10. EnclosingOne eo = new EnclosingOne(); 87 | 11. //insert code here 88 | 12. } 89 | 13. 90 | 14.} 91 | ``` 92 | 5、Which statement at line 11 constructs an instance of the inner class? 93 | - InsideOne ei=eo.new InsideOne(); 94 | - eo.InsideOne ei=eo.new InsideOne(); 95 | - InsideOne ei=EnclosingOne.new InsideOne(); 96 | - [x] EnclosingOne.InsideOne ei=eo.new InsideOne(); 97 | 98 | 解析:
99 | 内部类其实和类的属性没什么区别,只是在声明的时候必须是Outer.Inner a,就像int a 一样,至于静态内部类和非静态内部类new的时候有点区别,Outer.Inner a=new Outer().new Inner()(非静态,先有Outer对象才能有属性) Outer.Inner a=new Outer.Inner()要把Outer.Inner看成一部分,就像类变量一样。 100 | 101 | --- 102 | 103 | 6、以下集合对象中哪几个是线程安全的() 104 | - LinkedList 105 | - ArrayList 106 | - [x] Vector 107 | - [x] Hashtable 108 | 109 | 解析:
110 | 集合中线程安全的类有:vector,stack,hashtable,enumeration,除此之外均是非线程安全的类与接口。 111 | 112 | --- 113 | 114 | ``` stylus 115 | public class NameList 116 | { 117 | private List names = new ArrayList(); 118 | public synchronized void add(String name) 119 | { 120 | names.add(name); 121 | } 122 | public synchronized void printAll() { 123 | for (int i = 0; i < names.size(); i++) 124 | { 125 | System.out.print(names.get(i) + ””); 126 | } 127 | } 128 | 129 | public static void main(String[]args) 130 | { 131 | final NameList sl = new NameList(); 132 | for (int i = 0; i < 2; i++) 133 | { 134 | new Thread() 135 | { 136 | public void run() 137 | { 138 | sl.add(“A”); 139 | sl.add(“B”); 140 | sl.add(“C”); 141 | sl.printAll(); 142 | } 143 | } .start(); 144 | } 145 | } 146 | } 147 | ``` 148 | 7、Which two statements are true if this class is compiled and run?
149 | - An exception may be thrown at runtime. 150 | - The code may run with no output, without exiting. 151 | - The code may run with no output, exiting normally(正常地). 152 | - The code may rum with output “A B A B C C “, then exit. 153 | - [x] The code may rum with output “A B C A B C A B C “, then exit. 154 | - The code may ruin with output “A A A B C A B C C “, then exit. 155 | - [x] The code may ruin with output “A B C A A B C A B C “, then exit. 156 |
157 | 解析:
158 | 有两条进程在同时进行,线程内的是顺序进行,线程之间的顺序不定,可能是交叉执行,也有可能是先执行了一个线程后执行了另一个线程。
159 | 所以第一次输出,最少可能输出3个即直接运行完整个第一个线程,最多可能输出6个就是两个线程交叉运行直到双方线程的addA、addB、addC都执行完成然后执行其中一方的print。
160 | 所以分析一下几个答案: 161 | - A B A B C C (第一次print一定有C,所以第一次输出ABABC,第二次只输出了C,不可能,错) 162 | - A B C A B C A B C (第一次print输出ABC,然后执行第二线程,再输出ABCABC,最终ABCABCABC,正确) 163 | - A A A B C A B C C (AAA不可能出现,错) 164 | - A B C A A B C A B C (第一次输出ABCA,第二次输出ABCABC,最终输出ABCAABCABC,正确) 165 | 第二次输出的内容前部分一定是第一次输出的内容,如G选项中第二次输出A B C A B C,前半部分正是第一次输出的ABCA。 166 | 167 | --- 168 | 169 | 8、以下哪些jvm的垃圾回收方式采用的是复制算法回收 170 | - [x] 新生代串行收集器 171 | - 老年代串行收集器 172 | - 并行收集器 173 | - [x] 新生代并行回收收集器 174 | - 老年代并行回收收集器 175 | - cms收集器 176 |
177 | 解析:
178 | 两个最基本的java回收算法:复制算法和标记清理算法
179 | 复制算法:两个区域A和B,初始对象在A,继续存活的对象被转移到B。此为新生代最常用的算法 180 |
181 | 标记清理:一块区域,标记要回收的对象,然后回收,一定会出现碎片,那么引出
182 | 标记-整理算法:多了碎片整理,整理出更大的内存放更大的对象
183 |
184 | 两个概念:新生代和年老代
185 | 新生代:初始对象,生命周期短的
186 | 年老代:长时间存在的对象
187 | 整个java的垃圾回收是新生代和年老代的协作,这种叫做分代回收。 188 |
189 | - Serial New收集器是针对新生代的收集器,采用的是复制算法 190 | - Parallel New(并行)收集器,新生代采用复制算法,老年代采用标记整理 191 | - Parallel Scavenge(并行)收集器,针对新生代,采用复制收集算法 192 | - Serial Old(串行)收集器,新生代采用复制,老年代采用标记清理 193 | - Parallel Old(并行)收集器,针对老年代,标记整理 194 | - CMS收集器,基于标记清理 195 | - G1收集器:整体上是基于标记清理,局部采用复制 196 | 综上:新生代基本采用复制算法,老年代采用标记整理算法。cms采用标记清理。 197 |
198 | 更多关于垃圾回收的知识点,JVM垃圾回收总结需要深入理解阅读,这里不再展开,可以参考[《JVM垃圾回收总结》][1] 199 | 200 | --- 201 | 202 | 9、说明输出结果。 203 | 204 | ``` stylus 205 | package test; 206 | import java.util.Date; 207 | public class SuperTest extends Date{ 208 | private static final long serialVersionUID = 1L; 209 | private void test(){ 210 | System.out.println(super.getClass().getName()); 211 | } 212 | 213 | public static void main(String[]args){ 214 | new SuperTest().test(); 215 | } 216 | } 217 | ``` 218 | - SuperTest 219 | - SuperTest.class 220 | - [x] test.SuperTest 221 | - test.SuperTest.class 222 |
223 | 解析:
224 | TestSuper和Date的getClass都没有重写,他们都是调用Object的getClass,而Object的getClass作用是返回的是运行时的类的名字。这个运行时的类就是当前类,所以 225 | 226 | ``` stylus 227 | super.getClass().getName() 228 | ``` 229 | 返回的是test.SuperTest,与Date类无关。要返回Date类的名字需要super.getClass().getSuperclass() 230 | 231 | --- 232 | 233 | 10、在JAVA中,下面关于String类和StringBuffer类的描述正确的是那一个? 234 | - [x] StringBuffer类的对象调用toString()方法将转换为String类型 235 | - 两个类都有append()方法 236 | - 可以直接将字符串“test”赋值给声明的String类和StringBuffer类的变量 237 | - 两个类的实例的值都能够被改变 238 | 解析:
239 | 引用类型只有String可以直接复制,其他的都要new出来。String没有append方法,String实例的值不能改变。 240 | 241 | --- 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | [1]: http://blog.csdn.net/dc_726/article/details/7934101# -------------------------------------------------------------------------------- /sql/README.md: -------------------------------------------------------------------------------- 1 | # 概述 2 | 该内容参考于同样在成都的某网友博客,在基于其博文内容上进行自我练习和SQL编写能力的巩固。
3 | 以下: 4 | - [走向面试之数据库基础:一、你必知必会的SQL语句练习-Part 1][1] 5 | - [走向面试之数据库基础:一、你必知必会的SQL语句练习-Part 2][2] 6 | 7 | 8 | [1]: http://www.cnblogs.com/edisonchou/p/3878135.html 9 | [2]: http://www.cnblogs.com/edisonchou/p/3886801.html -------------------------------------------------------------------------------- /sql/练习用的建表数据/forsql.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Navicat MySQL Data Transfer 3 | 4 | Source Server : root+dev 5 | Source Server Version : 50018 6 | Source Host : localhost:3306 7 | Source Database : forsql 8 | 9 | Target Server Type : MYSQL 10 | Target Server Version : 50018 11 | File Encoding : 65001 12 | 13 | Date: 2017-03-11 15:41:00 14 | */ 15 | 16 | SET FOREIGN_KEY_CHECKS=0; 17 | 18 | -- ---------------------------- 19 | -- Table structure for books 20 | -- ---------------------------- 21 | DROP TABLE IF EXISTS `books`; 22 | CREATE TABLE `books` ( 23 | `id` int(11) NOT NULL auto_increment, 24 | `name` varchar(50) default NULL, 25 | `author` varchar(20) default NULL, 26 | `price` decimal(11,0) default NULL, 27 | `quantity` int(11) default '0', 28 | PRIMARY KEY (`id`) 29 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 30 | 31 | -- ---------------------------- 32 | -- Records of books 33 | -- ---------------------------- 34 | INSERT INTO `books` VALUES ('1', '水浒', '施耐庵', '188', '3'); 35 | INSERT INTO `books` VALUES ('2', '计算机网络', '谢希仁', '49', '3'); 36 | INSERT INTO `books` VALUES ('3', '计算方法', '严蔚敏', '58', '3'); 37 | INSERT INTO `books` VALUES ('4', '计算方法习题集', '殷人昆', '188', '3'); 38 | INSERT INTO `books` VALUES ('5', '数据库技术及应用', '王珊', '38', '3'); 39 | INSERT INTO `books` VALUES ('6', '组合数学', '周伟', '28', '3'); 40 | INSERT INTO `books` VALUES ('7', 'Redis初探', '周旭龙', '25', '3'); 41 | 42 | -- ---------------------------- 43 | -- Table structure for borrow 44 | -- ---------------------------- 45 | DROP TABLE IF EXISTS `borrow`; 46 | CREATE TABLE `borrow` ( 47 | `pk` int(11) NOT NULL auto_increment, 48 | `cardId` int(11) default NULL, 49 | `bookId` int(11) default NULL, 50 | `returnDate` timestamp NULL default CURRENT_TIMESTAMP, 51 | PRIMARY KEY (`pk`), 52 | UNIQUE KEY `pk` (`pk`) 53 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 54 | 55 | -- ---------------------------- 56 | -- Records of borrow 57 | -- ---------------------------- 58 | INSERT INTO `borrow` VALUES ('4', '1', '1', '2017-02-16 00:00:00'); 59 | INSERT INTO `borrow` VALUES ('5', '2', '1', '2017-02-16 00:00:00'); 60 | INSERT INTO `borrow` VALUES ('6', '3', '1', '2016-12-14 11:00:44'); 61 | INSERT INTO `borrow` VALUES ('7', '4', '3', '2016-12-14 11:00:48'); 62 | INSERT INTO `borrow` VALUES ('8', '4', '6', '2016-12-14 11:00:53'); 63 | INSERT INTO `borrow` VALUES ('9', '5', '6', '2016-12-14 11:00:57'); 64 | INSERT INTO `borrow` VALUES ('10', '7', '7', '2016-12-14 11:01:01'); 65 | 66 | -- ---------------------------- 67 | -- Table structure for cards 68 | -- ---------------------------- 69 | DROP TABLE IF EXISTS `cards`; 70 | CREATE TABLE `cards` ( 71 | `id` int(11) NOT NULL auto_increment, 72 | `name` varchar(20) default NULL, 73 | `class` varchar(20) default NULL, 74 | PRIMARY KEY (`id`) 75 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 76 | 77 | -- ---------------------------- 78 | -- Records of cards 79 | -- ---------------------------- 80 | INSERT INTO `cards` VALUES ('1', '张三', '计科一班'); 81 | INSERT INTO `cards` VALUES ('2', '李四', '计科一班'); 82 | INSERT INTO `cards` VALUES ('3', '王五', '计科二班'); 83 | INSERT INTO `cards` VALUES ('4', '六四', '计科二班'); 84 | INSERT INTO `cards` VALUES ('5', '七七', '软工一班'); 85 | INSERT INTO `cards` VALUES ('6', '粑粑', '软工二班'); 86 | 87 | -- ---------------------------- 88 | -- Table structure for course 89 | -- ---------------------------- 90 | DROP TABLE IF EXISTS `course`; 91 | CREATE TABLE `course` ( 92 | `courseNo` int(11) default NULL, 93 | `name` varchar(20) default NULL, 94 | `teacherNo` int(11) default NULL 95 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 96 | 97 | -- ---------------------------- 98 | -- Records of course 99 | -- ---------------------------- 100 | INSERT INTO `course` VALUES ('1', '语文', '1'); 101 | INSERT INTO `course` VALUES ('2', '数学', '2'); 102 | INSERT INTO `course` VALUES ('3', '英语', '3'); 103 | INSERT INTO `course` VALUES ('4', '物理', '4'); 104 | 105 | -- ---------------------------- 106 | -- Table structure for fruits 107 | -- ---------------------------- 108 | DROP TABLE IF EXISTS `fruits`; 109 | CREATE TABLE `fruits` ( 110 | `type` varchar(20) default NULL, 111 | `variety` varchar(20) default NULL, 112 | `price` double(15,3) default NULL 113 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 114 | 115 | -- ---------------------------- 116 | -- Records of fruits 117 | -- ---------------------------- 118 | INSERT INTO `fruits` VALUES ('apple', 'gala', '2.790'); 119 | INSERT INTO `fruits` VALUES ('apple', 'fuji', '0.240'); 120 | INSERT INTO `fruits` VALUES ('apple', 'limbertwig', '2.870'); 121 | INSERT INTO `fruits` VALUES ('orange', 'valencia', '3.590'); 122 | INSERT INTO `fruits` VALUES ('orange', 'navel', '9.360'); 123 | INSERT INTO `fruits` VALUES ('pear', 'bradford', '6.050'); 124 | INSERT INTO `fruits` VALUES ('pear', 'bartlett', '2.140'); 125 | INSERT INTO `fruits` VALUES ('cherry', 'bing', '2.550'); 126 | INSERT INTO `fruits` VALUES ('cherry', 'chelan', '6.330'); 127 | 128 | -- ---------------------------- 129 | -- Table structure for score 130 | -- ---------------------------- 131 | DROP TABLE IF EXISTS `score`; 132 | CREATE TABLE `score` ( 133 | `StudentNo` int(11) default NULL, 134 | `CourseNo` int(11) default NULL, 135 | `score` int(11) default NULL 136 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 137 | 138 | -- ---------------------------- 139 | -- Records of score 140 | -- ---------------------------- 141 | INSERT INTO `score` VALUES ('1', '2', '78'); 142 | INSERT INTO `score` VALUES ('1', '3', '67'); 143 | INSERT INTO `score` VALUES ('1', '4', '67'); 144 | INSERT INTO `score` VALUES ('2', '1', '52'); 145 | INSERT INTO `score` VALUES ('2', '2', '81'); 146 | INSERT INTO `score` VALUES ('2', '3', '92'); 147 | INSERT INTO `score` VALUES ('2', '4', '67'); 148 | INSERT INTO `score` VALUES ('3', '1', '52'); 149 | INSERT INTO `score` VALUES ('3', '2', '47'); 150 | INSERT INTO `score` VALUES ('3', '3', '88'); 151 | INSERT INTO `score` VALUES ('3', '4', '67'); 152 | INSERT INTO `score` VALUES ('4', '2', '88'); 153 | INSERT INTO `score` VALUES ('4', '3', '90'); 154 | INSERT INTO `score` VALUES ('4', '4', '67'); 155 | INSERT INTO `score` VALUES ('5', '1', '52'); 156 | INSERT INTO `score` VALUES ('5', '3', '78'); 157 | INSERT INTO `score` VALUES ('5', '4', '67'); 158 | INSERT INTO `score` VALUES ('6', '1', '52'); 159 | INSERT INTO `score` VALUES ('6', '2', '68'); 160 | INSERT INTO `score` VALUES ('6', '4', '67'); 161 | INSERT INTO `score` VALUES ('1', '1', '52'); 162 | INSERT INTO `score` VALUES ('5', '2', '72'); 163 | INSERT INTO `score` VALUES ('7', '2', '72'); 164 | 165 | -- ---------------------------- 166 | -- Table structure for student 167 | -- ---------------------------- 168 | DROP TABLE IF EXISTS `student`; 169 | CREATE TABLE `student` ( 170 | `name` varchar(32) default NULL, 171 | `age` int(11) default NULL, 172 | `sex` varchar(8) default NULL, 173 | `studentNo` int(11) default NULL 174 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 175 | 176 | -- ---------------------------- 177 | -- Records of student 178 | -- ---------------------------- 179 | INSERT INTO `student` VALUES ('钱二', '19', '女', '2'); 180 | INSERT INTO `student` VALUES ('刘一', '18', '男', '1'); 181 | INSERT INTO `student` VALUES ('张三', '17', '男', '3'); 182 | INSERT INTO `student` VALUES ('李四', '18', '女', '4'); 183 | INSERT INTO `student` VALUES ('王五', '17', '男', '5'); 184 | INSERT INTO `student` VALUES ('赵6', '19', '女', '6'); 185 | INSERT INTO `student` VALUES ('钱二', '25', '男', '7'); 186 | 187 | -- ---------------------------- 188 | -- Table structure for teacher 189 | -- ---------------------------- 190 | DROP TABLE IF EXISTS `teacher`; 191 | CREATE TABLE `teacher` ( 192 | `teacherNo` int(11) default NULL, 193 | `name` varchar(20) default NULL 194 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 195 | 196 | -- ---------------------------- 197 | -- Records of teacher 198 | -- ---------------------------- 199 | INSERT INTO `teacher` VALUES ('1', '叶平'); 200 | INSERT INTO `teacher` VALUES ('2', '贺高'); 201 | INSERT INTO `teacher` VALUES ('3', '杨艳'); 202 | INSERT INTO `teacher` VALUES ('4', '叶平'); 203 | -------------------------------------------------------------------------------- /sql/走向面试之数据库基础:你必知必会的SQL语句练习-Part 1/README.md: -------------------------------------------------------------------------------- 1 | # 概述 2 | 本题目的表结构大致如下图所示,具体的建表及测试数据可以参考原博主的博客。
3 | 4 | 我已经连通练习过一次并记录在了为知笔记中,也借此得到了很大的锻炼。这一次进行第二次练习熟悉,也顺便录入到Github中来。
5 | 6 | 另,本篇中的题目,前半部分难度稍大,后半部分难度减小。
7 | 8 | 9 | 10 | 11 | # 练习 12 | 13 | 1)查询“001”课程比“002”课程成绩高的所有学生的学号 14 | 15 | ``` stylus 16 | select 17 | s1.StudentNo 18 | from 19 | score s1, 20 | score s2 21 | where 22 | s1.CourseNo = 001 23 | and 24 | s2.CourseNo = 002 25 | and 26 | s1.StudentNo = s2.StudentNo 27 | and 28 | s1.score > s2.score 29 | ``` 30 |
31 | 32 | 2) 查询平均成绩大于60分的同学的学号和平均成绩 33 | 34 | ``` stylus 35 | select 36 | s1.StudentNo, 37 | AVG(s1.score) 38 | from 39 | score s1 40 | group by s1.StudentNo 41 | having AVG(s1.score) > 60 42 | ``` 43 |
44 | 45 | 3)查询所有同学的学号、姓名、选课数、总成绩 46 | 47 | ``` stylus 48 | select 49 | stu1.studentNo, 50 | stu1.name, 51 | count(s1.CourseNo), 52 | sum(s1.score) 53 | from 54 | score s1, 55 | student stu1 56 | where 57 | s1.StudentNo = stu1.studentNo 58 | group by s1.StudentNo 59 | ``` 60 |
61 | 62 | 4)查询姓“李”的老师的个数 63 | 64 | ``` stylus 65 | select 66 | count(*) 67 | from 68 | teacher t1 69 | where 70 | t1.name like '李%' 71 | ``` 72 |
73 | 74 | 5)查询没学过“叶平”老师课的同学的学号、姓名 75 | 76 | ``` stylus 77 | select 78 | stu1.studentNo, 79 | stu1.name 80 | from 81 | student stu1 82 | where 83 | stu1.studentNo not in 84 | ( 85 | --学过叶平老师课的学生学号 86 | select distinct 87 | s1.StudentNo 88 | from 89 | score s1, 90 | course c1, 91 | teacher t1 92 | where 93 | s1.CourseNo = c1.courseNo 94 | and 95 | c1.teacherNo = t1.teacherNo 96 | and 97 | t1.name = '叶平' 98 | ) 99 | ``` 100 |
101 | 102 | 6)查询学过“001”并且也学过编号“002”课程的同学的学号、姓名 103 | 104 | ``` stylus 105 | select 106 | stu1.studentNo, 107 | stu1.name 108 | from 109 | score s1, 110 | student stu1 111 | where 112 | s1.StudentNo = stu1.studentNo 113 | and 114 | s1.CourseNo = 001 115 | and 116 | s1.StudentNo in 117 | ( 118 | select distinct 119 | s2.StudentNo 120 | from 121 | score s2 122 | where 123 | s2.CourseNo = 002 124 | ) 125 | ``` 126 |
127 | 128 | 7)查询学过“叶平”老师所教的所有课的同学的学号、姓名 129 | 130 | ``` stylus 131 | select 132 | s1.StudentNo, 133 | stu1.name 134 | from 135 | score s1, 136 | student stu1, 137 | course c1, 138 | teacher t1 139 | where 140 | s1.StudentNo = stu1.studentNo 141 | and 142 | s1.CourseNo = c1.courseNo 143 | and 144 | c1.teacherNo = t1.teacherNo 145 | and 146 | t1.name = '叶平' 147 | group by s1.StudentNo 148 | having count(c1.courseNo)= 149 | ( 150 | select 151 | count(c2.courseNo) 152 | from 153 | course c2, 154 | teacher t2 155 | where 156 | c2.teacherNo = t2.teacherNo 157 | and 158 | t2.name = '叶平' 159 | ) 160 | ``` 161 |
162 | 163 | 8)查询课程编号“002”的成绩比课程编号“001”课程低的所有同学的学号、姓名(和第1题是重复的) 164 | 165 | ``` stylus 166 | select 167 | s1.StudentNo, 168 | stu1.name 169 | from 170 | score s1, 171 | score s2, 172 | student stu1 173 | where 174 | s1.StudentNo = stu1.studentNo 175 | and 176 | s1.CourseNo = 001 177 | and 178 | s2.CourseNo = 002 179 | and 180 | s1.StudentNo = s2.StudentNo 181 | and 182 | s1.score > s2.score 183 | ``` 184 |
185 | 186 | 9)查询有课程成绩小于60分的同学的学号、姓名 187 | 188 | ``` stylus 189 | select distinct 190 | s1.StudentNo, 191 | stu1.name 192 | from 193 | score s1, 194 | student stu1 195 | where 196 | s1.StudentNo = stu1.studentNo 197 | and 198 | s1.score < 60 199 | ``` 200 |
201 | 202 | 10)查询没有学全所有课的同学的学号、姓名 203 | 204 | ``` stylus 205 | select 206 | s1.StudentNo, 207 | stu1.name 208 | from 209 | score s1, 210 | student stu1 211 | where 212 | s1.StudentNo = stu1.studentNo 213 | group by s1.StudentNo 214 | having count(s1.CourseNo) < 215 | ( 216 | select 217 | count(*) 218 | from 219 | course c1 220 | ) 221 | ``` 222 |
223 | 224 | 11)查询至少有一门课与学号为“001”的同学所学相同的同学的学号和姓名 225 | 226 | ``` stylus 227 | select distinct 228 | s1.StudentNo, 229 | stu1.name 230 | from 231 | score s1, 232 | student stu1 233 | where 234 | s1.StudentNo = stu1.studentNo 235 | and 236 | s1.CourseNo in 237 | ( 238 | select 239 | s2.CourseNo 240 | from 241 | score s2 242 | where 243 | s2.StudentNo = 001 244 | ) 245 | ``` 246 |
247 | 248 | 12)查询至少学过学号为“001”同学所有一门课的其他同学学号和姓名(和11题几乎一样) 249 | ``` stylus 250 | select distinct 251 | s1.StudentNo, 252 | stu1.name 253 | from 254 | score s1, 255 | student stu1 256 | where 257 | s1.StudentNo = stu1.studentNo 258 | and 259 | s1.StudentNo != 001 260 | and 261 | s1.CourseNo in 262 | ( 263 | select 264 | s2.CourseNo 265 | from 266 | score s2 267 | where 268 | s2.StudentNo = 001 269 | ) 270 | ``` 271 |
272 | 273 | **13)把“SC”表中“叶平”老师教的课的成绩都更改为此课程的平均成绩** 274 | 275 | 这道题有两个点需要注意: 276 | - MySQL中不支持先select同一表中的某值,再update这个表,所以需要采用再select的方式来提取值; 277 | - 个人理解的该题的题意是,假设叶平老师教授了A课和B课,那么课程A改为课程A的平均成绩,课程B改为课程B的平均成绩。实际上我写出的是课程A和B的成绩都改为A和B成绩的平均成绩。~~所以实际上我认为以下的写法是有违题意的,但是按照理解的题意,暂未想到合适的sql语句,故此搁浅,隔日再审。~~ 278 | 279 | ``` stylus 280 | update 281 | score s1 282 | set 283 | s1.score = 284 | ( 285 | select 286 | table1.avgScore 287 | from 288 | ( 289 | select 290 | avg(s2.score) as avgScore 291 | from 292 | score s2, 293 | course c2, 294 | teacher t2 295 | where 296 | s2.CourseNo = c2.courseNo 297 | and 298 | c2.teacherNo = t2.teacherNo 299 | and 300 | t2.name = '叶平' 301 | )table1 302 | ) 303 | 304 | where 305 | s1.CourseNo in 306 | ( 307 | select 308 | c1.courseNo 309 | from 310 | course c1, 311 | teacher t1 312 | where 313 | c1.teacherNo = t1.teacherNo 314 | and 315 | t1.name = '叶平' 316 | ) 317 | ``` 318 | 以上为当初不符题意的sql写法,后来知道原来update可以采取类似多表联合的方式,于是得到了解决,具体代码如下(另,相关文章参考链接:[MySQL:把一个表中的数据按键值更新(update)到另一个表][1]),读书少害人啊! 319 | 320 | ``` stylus 321 | UPDATE 322 | score s, 323 | ( 324 | SELECT 325 | s1.CourseNo as courseNo, 326 | AVG(s1.score) as avgScore 327 | FROM 328 | score s1, 329 | course c1, 330 | teacher t1 331 | WHERE 332 | s1.CourseNo = c1.CourseNo 333 | AND 334 | c1.teacherNo = t1.teacherNo 335 | AND 336 | t1.name = '叶平' 337 | GROUP BY s1.CourseNo 338 | ) as t 339 | SET 340 | s.score = t.avgScore 341 | WHERE 342 | s.CourseNo = t.courseNo 343 | ``` 344 |
345 | 346 | **14)查询和“002”号的同学学习的课程完全相同的其他同学学号和姓名** 347 | 348 | 这里利用了CourseNo作为主键唯一的特性,不同人的各课程相加的值也不同,如果相同,那么所学课程必定相同。 349 | ``` stylus 350 | select 351 | s1.StudentNo, 352 | stu1.name 353 | from 354 | score s1, 355 | student stu1 356 | where 357 | s1.StudentNo = stu1.studentNo 358 | and 359 | s1.StudentNo != 2 360 | group by s1.StudentNo 361 | having sum(s1.CourseNo) = 362 | ( 363 | select 364 | sum(s2.CourseNo) 365 | from 366 | score s2 367 | where 368 | s2.StudentNo = 2 369 | ) 370 | ``` 371 |
372 | 373 | 15)删除学习“叶平”老师课的SC表记录 374 | 375 | ``` stylus 376 | delete from 377 | score s1 378 | where 379 | s1.CourseNo in 380 | ( 381 | select 382 | c1.courseNo 383 | from 384 | course c1, 385 | teacher t1 386 | where 387 | c1.teacherNo = t1.teacherNo 388 | and 389 | t1.name = '叶平' 390 | ) 391 | 392 | ``` 393 |
394 | 395 | **16)向SC表中插入一些记录,这些记录要求符合以下条件:1、没有上过编号“002”课程的同学学号;2、插入“002”号课程的平均成绩** 396 | 397 | (本题采用插入子查询的方式,三个字段中后两个字段为常量) 398 | 399 | ``` stylus 400 | insert into score(StudentNo, courseNo, score) 401 | ( 402 | select 403 | stu1.StudentNo, 404 | "002", 405 | ( 406 | select 407 | avg(s1.score) 408 | from 409 | score s1 410 | where 411 | s1.CourseNo = 2 412 | ) 413 | from 414 | student stu1 415 | where 416 | stu1.studentNo not in 417 | ( 418 | select 419 | s2.StudentNo 420 | from 421 | score s2 422 | where 423 | s2.CourseNo = 2 424 | ) 425 | ) 426 | ``` 427 |
428 | 429 | **17)按平均成绩从低到高显示所有学生的“语文”、“数学”、“英语”三门的课程成绩,按如下形式显示: 学生ID,语文,数学,英语,有效课程数,有效平均分** 430 | 431 | (在自然连接和等值连接中,不匹配的元组信息会丢失,如果在这道题中使用,就会不完整。这里采用了相关子查询的方式。) 432 | 433 | ``` stylus 434 | select 435 | s.StudentNo, 436 | (select s1.score from score s1 where s1.CourseNo=1 and s1.StudentNo = s.StudentNo) as "语文", 437 | (select s2.score from score s2 where s2.CourseNo=2 and s2.StudentNo = s.StudentNo) as "数学", 438 | (select s3.score from score s3 where s3.CourseNo=3 and s3.StudentNo = s.StudentNo) as "英语", 439 | COUNT(s.CourseNo) as "有效课程数", 440 | AVG(s.score) as "有效平均分" 441 | from 442 | score s 443 | group by s.StudentNo 444 | order by AVG(s.score) 445 | ``` 446 | 先将score s按s.StudentNo分类,则StudentNo不重复,分别提出和子查询中参与运算,如[ select s1.score from score s1 where s1.CourseNo=1 and s1.StudentNo = s.StudentNo ]中,提取s中StudentNo如1到子查询中,在子查询中找到s1.StudentNo = s.StudentNo = 1的,然后继续条件and s1.CourseNo = 1,如果没有,填为null。 447 |
448 |
449 | 450 | 18)查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分; 451 | 452 | ``` stylus 453 | select 454 | s1.CourseNo as '课程ID', 455 | max(s1.score) as '最高分', 456 | min(s1.score) as '最低分' 457 | from 458 | score s1 459 | group by s1.CourseNo 460 | ``` 461 |
462 | 463 | **19)按各科平均成绩从低到高和及格率的百分数从高到低顺序;** 464 | 465 | ``` stylus 466 | select 467 | s1.CourseNo, 468 | avg(s1.score) as 'avgScore', 469 | t1.passNum / count(s1.StudentNo) as 'passRate' 470 | from 471 | score s1, 472 | ( 473 | select 474 | s2.CourseNo, 475 | count(s2.StudentNo) as 'passNum' 476 | from 477 | score s2 478 | where 479 | s2.score > 60 480 | group by s2.CourseNo 481 | )t1 482 | where 483 | s1.CourseNo = t1.CourseNo 484 | group by s1.CourseNo 485 | order by avgScore, passRate desc 486 | ``` 487 | (这种解法有误,忽略了某学科全部成绩低于60的情况,信息丢失) 488 | 489 | 所以采取外连接的方式,重写如下: 490 | 491 | ``` stylus 492 | select 493 | t0.CourseNo, 494 | t0.avgScore, 495 | t1.passNum, 496 | t0.amount, 497 | t1.passNum / t0.amount * 100 as 'passRate' 498 | from 499 | ( 500 | select 501 | s1.CourseNo, 502 | avg(s1.score) as 'avgScore', 503 | count(s1.score) as 'amount' 504 | from 505 | score s1 506 | group by s1.CourseNo 507 | )t0 508 | natural left outer join 509 | ( 510 | select 511 | s2.CourseNo, 512 | count(s2.StudentNo) as 'passNum' 513 | from 514 | score s2 515 | where 516 | s2.score > 60 517 | group by s2.CourseNo 518 | )t1 519 | order by t0.avgScore, passRate desc 520 | ``` 521 | 科目1所有人都没及格,你会发现这个查询结果及格数为null,但是我们想要的是,如果没有就为0,怎么办?那么我们在使用ifNull函数: 522 | 523 | ``` stylus 524 | select 525 | t0.CourseNo, 526 | t0.avgScore, 527 | ifnull(t1.passNum, 0), 528 | t0.amount, 529 | ifnull(t1.passNum, 0) / t0.amount * 100 as 'passRate' 530 | from 531 | ( 532 | select 533 | s1.CourseNo, 534 | avg(s1.score) as 'avgScore', 535 | count(s1.score) as 'amount' 536 | from 537 | score s1 538 | group by s1.CourseNo 539 | )t0 540 | natural left outer join 541 | ( 542 | select 543 | s2.CourseNo, 544 | count(s2.StudentNo) as 'passNum' 545 | from 546 | score s2 547 | where 548 | s2.score > 60 549 | group by s2.CourseNo 550 | )t1 551 | order by t0.avgScore, passRate desc 552 | ``` 553 | 这里,提一下MYSQL中ISNULL和IFNULL的区别: 554 | ISNULL(expr):if expr is NULL, returns 1, else returns 0; 555 | IFNULL(expr1, expr2):if expr1 is not NULL, returns expr1, else returns expr2. 556 |
557 |
558 | 559 | 20)查询不同老师所教不同课程平均分从高到低显示 560 | 561 | ``` stylus 562 | select 563 | t1.name, 564 | c1.courseNo, 565 | c1.name, 566 | avg(s1.score) 567 | from 568 | score s1, 569 | course c1, 570 | teacher t1 571 | where 572 | s1.CourseNo = c1.courseNo 573 | and 574 | c1.teacherNo = t1.teacherNo 575 | group by s1.CourseNo 576 | order by avg(s1.score) desc 577 | ``` 578 |
579 | 580 | **21)统计列印各科成绩,各分数段人数: 课程ID,课程名称,(100-85),(85-70),(70-60),( 低于60)** 581 | 582 | 这里用到了MySQL中 case when then else end 用法,命令如其名,详见题目SQL语句。 583 | 584 | ``` stylus 585 | select 586 | s1.CourseNo, 587 | c1.name, 588 | sum(case when s1.score between 85 and 100 then 1 else 0 end) as "85-100", 589 | sum(case when s1.score between 70 and 85 then 1 else 0 end) as "70-85", 590 | sum(case when s1.score between 60 and 70 then 1 else 0 end) as "60-70", 591 | sum(case when s1.score < 60 then 1 else 0 end) as "<60" 592 | from 593 | score s1, 594 | course c1 595 | where 596 | s1.CourseNo = c1.courseNo 597 | group by s1.CourseNo 598 | ``` 599 |
600 | 601 | **22)查询各科成绩前三名的记录:(不考虑成绩并列情况)** 602 | 603 | 这里会巧妙利用到相关子查询。 604 | 605 | ``` stylus 606 | select 607 | * 608 | from 609 | score s1 610 | where 611 | s1.score in 612 | ( 613 | select 614 | s2.score 615 | from 616 | score s2 617 | where 618 | s2.CourseNo = s1.CourseNo 619 | order by s2.score desc 620 | limit 0, 3 621 | ) 622 | ``` 623 | 如果每次提出的该行中的分数,在该分数对应学科的前三名分数当中,那么符合条件,提取出来。 624 | 但是,在MySQL4.1中子查询是不能使用LIMIT的,手册中也明确指明 This version of MySQL doesn’t yet support ‘LIMIT & IN/ALL/ANY/SOME subquery’。 625 | 所以这个方法暂时待定,换另一个方法: 626 | 627 | ``` stylus 628 | select 629 | * 630 | from 631 | score s 632 | where 633 | ( 634 | select 635 | count(*) 636 | from 637 | score s1 638 | where 639 | s1.CourseNo = s.CourseNo 640 | and 641 | s1.score > s.score 642 | ) < 3 643 | order by s.CourseNo 644 | ``` 645 | 这个方法的思路是,需要提取的行,该行对应的分数对应的学科中,比它高的分数必须小于3个 646 | (即假如自己是第3,那么在该学科所有分数中,比自己高的只有第一和第二共2个) 647 | 但是,这个方法对于并列的成绩,会全部输出。 648 |
649 |
650 | 651 | 23)查询每门课程被选修的学生数 652 | 653 | ``` stylus 654 | select 655 | s1.CourseNo, 656 | count(s1.StudentNo) 657 | from 658 | score s1 659 | group by s1.CourseNo 660 | 661 | ``` 662 |
663 | 664 | 24)查询出只选修了一门课程的全部学生的学号和姓名 665 | 666 | ``` stylus 667 | select 668 | s1.StudentNo, 669 | stu1.name 670 | from 671 | score s1, 672 | student stu1 673 | where 674 | s1.StudentNo = stu1.studentNo 675 | group by s1.StudentNo 676 | having count(s1.CourseNo) = 1 677 | ``` 678 |
679 | 680 | 25)查询男生、女生的人数 681 | 682 | ``` stylus 683 | select 684 | stu1.sex, 685 | count(stu1.studentNo) 686 | from 687 | student stu1 688 | group by stu1.sex 689 | 690 | ``` 691 |
692 | 693 | **26)查询同名同姓学生名单,并统计同名人数** 694 | 695 | 这道题告诉我,凡是不要想得太复杂... 696 | 697 | ``` stylus 698 | select 699 | stu1.name, 700 | count(stu1.name) 701 | from 702 | student stu1 703 | group by stu1.name 704 | ``` 705 |
706 | 707 | **27)查询1991年出生的学生名单** 708 | 709 | 不同数据库的时间函数不一样,这里使用的是mysql;
710 | CURDATE() 或CURRENT_DATE() 获取当前日期,按格式"YYYY-MM-DD"返回;
711 | YEAR(date) 返回date对应的年份,范围是1970-2069 712 | 713 | ``` stylus 714 | select 715 | stu1.name, 716 | stu1.age 717 | from 718 | student stu1 719 | where 720 | YEAR(CURRENT_DATE())-stu1.age = 1991 721 | ``` 722 |
723 | 724 | 28)查询每门课程的平均成绩,结果按平均成绩升序排列 725 | 726 | ``` stylus 727 | select 728 | s1.CourseNo, 729 | avg(s1.score) 730 | from 731 | score s1 732 | group by s1.CourseNo 733 | order by avg(s1.score) 734 | ``` 735 |
736 | 737 | 29)查询平均成绩大于85的所有学生的学号、姓名和平均成绩 738 | 739 | ``` stylus 740 | select 741 | stu1.studentNo, 742 | stu1.name, 743 | avg(s1.score) 744 | from 745 | score s1, 746 | student stu1 747 | where 748 | s1.StudentNo = stu1.studentNo 749 | group by s1.StudentNo 750 | having avg(s1.score)>85 751 | ``` 752 |
753 | 754 | 30)查询课程名称为“数学”,且分数低于60的学生姓名和分数 755 | 756 | ``` stylus 757 | select 758 | stu1.name, 759 | s1.score 760 | from 761 | score s1, 762 | course c1, 763 | student stu1 764 | where 765 | s1.StudentNo = stu1.studentNo 766 | and 767 | s1.CourseNo = c1.courseNo 768 | and 769 | c1.name = "数学" 770 | and 771 | s1.score < 60 772 | ``` 773 |
774 | 775 | 31)查询所有学生的选课情况 776 | 777 | ``` stylus 778 | select 779 | stu1.name, 780 | c1.name 781 | from 782 | score s1, 783 | student stu1, 784 | course c1 785 | where 786 | s1.StudentNo = stu1.studentNo 787 | and 788 | s1.CourseNo = c1.courseNo 789 | order by stu1.studentNo 790 | ``` 791 |
792 | 793 | 32)查询任何一门课程成绩在70分以上的姓名、课程名称和分数 794 | 795 | ``` stylus 796 | select 797 | stu1.name, 798 | c1.name, 799 | s1.score 800 | from 801 | score s1, 802 | course c1, 803 | student stu1 804 | where 805 | s1.CourseNo = c1.courseNo 806 | and 807 | s1.StudentNo = stu1.studentNo 808 | and 809 | s1.score > 70 810 | ``` 811 |
812 | 813 | 33)查询不及格的课程,并按课程号从大到小排列 814 | 815 | ``` stylus 816 | select distinct 817 | s1.CourseNo 818 | from 819 | score s1 820 | where 821 | s1.score < 60 822 | order by s1.CourseNo desc 823 | ``` 824 |
825 | 826 | 34)查询课程编号为003且课程成绩在80分以上的学生的学号和姓名 827 | 828 | ``` stylus 829 | select 830 | s1.StudentNo, 831 | stu1.name, 832 | s1.score 833 | from 834 | score s1, 835 | student stu1 836 | where 837 | s1.StudentNo = stu1.studentNo 838 | and 839 | s1.CourseNo = 3 840 | and 841 | s1.score > 80 842 | ``` 843 |
844 | 845 | **35)求选了课程的学生人数** 846 | 847 | ``` stylus 848 | select 849 | count(*) 850 | from 851 | ( 852 | select 853 | * 854 | from 855 | score s1 856 | group by s1.StudentNo 857 | ) table1 858 | ``` 859 | 860 | 不够简洁,优化如下: 861 | 862 | ``` stylus 863 | select 864 | count(distinct s1.StudentNo) 865 | from 866 | score s1 867 | ``` 868 |
869 | 870 | **36)查询选修“杨艳”老师所授课程的学生中,成绩最高的学生姓名及其成绩** 871 | 872 | 使用MySQL的limit函数: 873 | 874 | ``` stylus 875 | select 876 | stu1.name, 877 | s1.score 878 | from 879 | score s1, 880 | course c1, 881 | teacher t1, 882 | student stu1 883 | where 884 | s1.CourseNo = c1.courseNo 885 | and 886 | s1.StudentNo = stu1.studentNo 887 | and 888 | c1.teacherNo = t1.teacherNo 889 | and 890 | t1.name = '杨艳' 891 | order by s1.score desc 892 | limit 0, 1 893 | ``` 894 |
895 | 896 | 37)查询各个课程及相应的选修人数 897 | 898 | ``` stylus 899 | select 900 | c1.courseNo, 901 | c1.name, 902 | count(*) 903 | from 904 | score s1, 905 | course c1 906 | where 907 | s1.CourseNo = c1.courseNo 908 | group by s1.CourseNo 909 | ``` 910 |
911 | 912 | **38)查询不同课程但成绩相同的学生的学号、课程号、学生成绩** 913 | 914 | ``` stylus 915 | select distinct 916 | s1.StudentNo, 917 | s1.CourseNo, 918 | s1.score 919 | from 920 | score s1, 921 | score s2 922 | where 923 | s1.score = s2.score 924 | and 925 | s1.CourseNo <> s2.CourseNo 926 | order by s1.score 927 | ``` 928 |
929 | 930 | **39)查询每门课程成绩最好的前两名** 931 | 932 | 这里同第22题:查询各科成绩前三名的记录 933 | 934 | ``` stylus 935 | select 936 | stu1.name, 937 | s.CourseNo, 938 | s.score 939 | from 940 | score s, 941 | student stu1 942 | where 943 | ( 944 | select 945 | count(*) 946 | from 947 | score s1 948 | where 949 | s.CourseNo = s1.CourseNo 950 | and 951 | s.score < s1.score 952 | ) < 2 953 | and 954 | s.StudentNo = stu1.studentNo 955 | order by s.CourseNo 956 | ``` 957 |
958 | 959 | 40)统计每门课程的学生选修人数(超过5人的课程才统计)要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列 960 | 961 | ``` stylus 962 | select 963 | s1.CourseNo, 964 | count(s1.StudentNo) 965 | from 966 | score s1 967 | group by s1.CourseNo 968 | having count(s1.StudentNo)>5 969 | order by count(s1.StudentNo) desc, s1.CourseNo 970 | ``` 971 |
972 | 973 | 41)检索至少选修两门课程的学生学号 974 | 975 | ``` stylus 976 | select 977 | s1.StudentNo 978 | from 979 | score s1 980 | group by s1.StudentNo 981 | having count(s1.CourseNo) >= 2 982 | ``` 983 |
984 | 985 | **42)查询全部学生都选修的课程的课程号和课程名** 986 | 987 | 思路:全部学生都选修了的课程,即:score表按课程分组,课程中的学生数量和总学生数量相同的元组,即为全部学生选修的课程 988 | 989 | ``` stylus 990 | select 991 | s1.CourseNo, 992 | c1.name 993 | from 994 | score s1, 995 | course c1 996 | where 997 | s1.CourseNo = c1.courseNo 998 | group by s1.CourseNo 999 | having count(s1.StudentNo)= 1000 | ( 1001 | select 1002 | count(*) 1003 | from 1004 | student stu1 1005 | ) 1006 | ``` 1007 |
1008 | 1009 | 43)查询没学过“叶平”老师讲授的任一门课程的学生姓名 1010 | 1011 | ``` stylus 1012 | select 1013 | stu1.name 1014 | from 1015 | student stu1 1016 | where 1017 | stu1.StudentNo not in 1018 | ( 1019 | select distinct 1020 | s1.StudentNo 1021 | from 1022 | score s1, 1023 | course c1, 1024 | teacher t1 1025 | where 1026 | s1.CourseNo = c1.courseNo 1027 | and 1028 | c1.teacherNo = t1.teacherNo 1029 | and 1030 | t1.name = '叶平' 1031 | ) 1032 | ``` 1033 |
1034 | 1035 | 44)查询两门以上不及格课程的同学的学号及其平均成绩 1036 | 1037 | ``` stylus 1038 | select 1039 | t1.StudentNo, 1040 | t1.avgScore 1041 | from 1042 | ( 1043 | select 1044 | s2.StudentNo, 1045 | avg(s2.score) as avgScore 1046 | from 1047 | score s2 1048 | group by s2.StudentNo 1049 | ) t1, 1050 | ( 1051 | select 1052 | s1.StudentNo 1053 | from 1054 | score s1 1055 | where 1056 | s1.score < 60 1057 | group by s1.StudentNo 1058 | having count(s1.CourseNo)>=2 1059 | ) t2 1060 | where 1061 | t1.StudentNo = t2.StudentNo 1062 | ``` 1063 |
1064 | 1065 | 45)检索“004”课程分数小于60,按分数降序排列的同学学号 1066 | 1067 | ``` stylus 1068 | select 1069 | s1.StudentNo, 1070 | s1.score 1071 | from 1072 | score s1 1073 | where 1074 | s1.CourseNo = 4 1075 | and 1076 | s1.score < 60 1077 | order by s1.score desc 1078 | ``` 1079 |
1080 | 1081 | 46)删除“002”同学的“001”课程的成绩 1082 | 1083 | ``` stylus 1084 | enter code heredelete from 1085 | score s1 1086 | where 1087 | s1.StudentNo = 2 1088 | and 1089 | s1.CourseNo = 1 1090 | ``` 1091 |
1092 |
1093 | 1094 | END 1095 | 1096 | 1097 | [1]: http://www.aichengxu.com/mysql/21657.htm -------------------------------------------------------------------------------- /sql/走向面试之数据库基础:你必知必会的SQL语句练习-Part 2/README.md: -------------------------------------------------------------------------------- 1 | # 概述 2 | 具体的建表数据,参考原博地址:
3 | [走向面试之数据库基础:一、你必知必会的SQL语句练习-Part 2][1] 4 | 5 | # 开练! 6 | 1)找出借书至少2本的读者,输出借书卡号及所借图书册数 7 | 8 | ``` stylus 9 | select 10 | b.cardId, 11 | count(*) 12 | from 13 | borrow b 14 | group by b.cardId 15 | having count(*)>=2 16 | ``` 17 |
18 | 19 | 2)查询借阅了"水浒"一书的读者,输出姓名及班级 20 | 21 | ``` stylus 22 | select 23 | c.name, 24 | c.class 25 | from 26 | borrow b, 27 | books bk, 28 | cards c 29 | where 30 | b.bookId = bk.id 31 | and 32 | bk.name = '水浒' 33 | and 34 | b.cardId = c.id 35 | ``` 36 |
37 | 38 | 3)查询目前为止未还图书,输出借阅者(卡号)、书号及还书日期 39 | 40 | ``` stylus 41 | select 42 | b.cardId, 43 | b.bookId, 44 | b.returnDate 45 | from 46 | borrow b 47 | where 48 | b.returnDate > current_date 49 | ``` 50 |
51 | 52 | 4)查询书名包括"网络"关键词的图书,输出书号、书名、作者 53 | 54 | ``` stylus 55 | select 56 | b.id, 57 | b.name, 58 | b.author 59 | from 60 | books b 61 | where 62 | b.name like '%网络%' 63 | ``` 64 |
65 | 66 | 5)查询现有图书中价格最高的图书,输出书名及作者 67 | 68 | ``` stylus 69 | select 70 | bk.name, 71 | bk.author 72 | from 73 | books bk 74 | where 75 | bk.price = (select max(b.price) from books b) 76 | ``` 77 |
78 | 79 | 6)查询当前借了"计算方法"但没有借"计算方法习题集"的读者,输出其借书卡号,并按卡号降序排序输出 80 | 81 | ``` stylus 82 | select 83 | b1.cardId 84 | from 85 | borrow b1, 86 | books bk1 87 | where 88 | b1.bookid = bk1.id 89 | and 90 | bk1.name = '计算方法' 91 | and 92 | b1.cardId not in 93 | ( 94 | select 95 | b2.cardId 96 | from 97 | borrow b2, 98 | books bk2 99 | where 100 | b2.bookid = bk2.id 101 | and 102 | bk2.name = '计算方法习题集' 103 | ) 104 | order by b1.cardId desc 105 | ``` 106 |
107 | 108 | **7)将"计科一班"班同学所借图书的还期都延长一周** 109 |
110 | 用到MySQL的时间函数 111 | ``` stylus 112 | update 113 | borrow b1, 114 | cards c1 115 | set 116 | b1.returnDate = DATE_ADD(b1.returnDate, interval 7 day) 117 | where 118 | b1.cardId = c1.id 119 | and 120 | c1.class = '计科一班' 121 | ``` 122 |
123 | 124 | 8)从BOOKS表中删除当前无人借阅的图书记录 125 | 126 | ``` stylus 127 | delete from books bk 128 | where bk.id not in 129 | ( 130 | select distinct b.bookId from borrow b 131 | ) 132 | ``` 133 |
134 | 135 | **9)如果经常按书名查询图书信息,请建立合适的索引** 136 |
137 | 很少用,虽然很简单也标注下重点 138 | 139 | ``` stylus 140 | create index index_bookName on books(name) 141 | ``` 142 |
143 | 144 | **10)建立一个视图,显示"计科一班"班学生的借书信息(只要求显示姓名和书名)** 145 |
146 | 视图的建立 147 | 148 | ``` stylus 149 | create view borrowInfo_C1 as 150 | select 151 | c1.name as "姓名", 152 | bk1.name as "书名" 153 | from 154 | borrow b1, 155 | cards c1, 156 | books bk1 157 | where 158 | b1.cardId = c1.id 159 | and 160 | b1.bookId = bk1.id 161 | and 162 | c1.class = "计科一班" 163 | ``` 164 |
165 | 166 | **11)查询当前同时借有"计算方法"和"组合数学"两本书的读者,输出其借书卡号,并按卡号升序排序输出** 167 | 168 | ``` stylus 169 | select 170 | b1.cardId 171 | from 172 | borrow b1, 173 | books bk1 174 | where 175 | b1.bookId = bk1.id 176 | and 177 | bk1.name = '计算方法' 178 | and 179 | b1.cardId in 180 | ( 181 | select 182 | b2.cardId 183 | from 184 | borrow b2, 185 | books bk2 186 | where 187 | b2.bookId = bk2.id 188 | and 189 | bk2.name = '组合数学' 190 | ) 191 | order by b1.cardId 192 | ``` 193 |
194 | 其实可以更简单: 195 | 196 | ``` stylus 197 | select 198 | b1.cardId 199 | from 200 | borrow b1, 201 | books bk1 202 | where 203 | b1.bookId = bk1.id 204 | and 205 | bk1.name in ('计算方法', '组合数学') 206 | group by b1.cardId 207 | having count(b1.cardId) = 2 208 | order by b1.cardId 209 | ``` 210 |
211 |
212 |
213 | **THE END** 214 | 215 | 216 | 217 | 218 | 219 | 220 | [1]: http://www.cnblogs.com/edisonchou/p/3886801.html --------------------------------------------------------------------------------