将自己遇到的有含量且常见的面试题分类统计

  

-----------------------linux相关------------------------ 

 在这里总结自己面试这么多次遇到的linux相关的面试题:

1.linux启动过程是咋样的?

大致分为五步:

(1)内核引导:

  读入/boot下的内核文件

(2)运行init

  读取/etc下面的配置文件(init进程)

 (3)系统初始化:

  读取/etc/rc.d/rcX.d/目录下面的文件  (开机启动的一些服务)

[root@iz2ze46xi6pjjj69ailg9lz bin]# cd /etc/rc.d/
[root@iz2ze46xi6pjjj69ailg9lz rc.d]# ls
init.d  rc0.d  rc1.d  rc2.d  rc3.d  rc4.d  rc5.d  rc6.d  rc.local

  /etc/rc[0-6].d是/etc/rc.d/rc[0-6].d的软连接:    /etc/init.d是/etc/rc.d/init.d的一个软连接

(4)建立终端:

  建立6个终端   tty1-tty6

(5)用户登录

三种登录方式:

  ssh   命令行  图形化界面

2.linux的文件权限以及如何改变文件权限?

(1)文件权限解释:

首先看一组linux文件权限:

[root@iz2ze46xi6pjjj69ailg9lz ~]# ll
total 307576
-rw-r--r--  1 root  root     356682 Mar 14 23:40 ~
-rw-r--r--  1 root  root    8961394 Feb  1 15:59 exam1.31.sql
-rw-r--r--  1 root  root   14744393 Jan 27 13:50 exam.sql
-rw-r--r--  1 root  root  213608341 Jan 27 22:19 Exam.war
drwxrwxr-x 11 17608 17608      4096 Aug 22  2017 mbedtls-2.6.0
-rw-r--r--  1 root  root    1958070 Mar 14 23:53 mbedtls-2.6.0-gpl.tgz
-rw-r--r--  1 root  root   75281701 Mar 26 22:02 mongodb-linux-x86_64-3.2.9.tgz
drwxr-xr-x  3 root  root       4096 Mar 14 23:46 ss
-rw-r--r--  1 root  root         40 Sep  1  2017 test
drwxr-xr-x  3 root  root       4096 Jan 26 20:51 tomcat项目
drwxr-xr-x  2 root  root       4096 Oct 28 10:51 ww
drwxr-xr-x  3 root  root       4096 Dec 16 16:48 自己的练习

在Linux中第一个字符代表这个文件是目录、文件或链接文件等等。

  • 当为[ d ]则是目录
  • 当为[ - ]则是文件;
  • 若是[ l ]则表示为链接文档(link file);
  • 若是[ b ]则表示为装置文件里面的可供储存的接口设备(可随机存取装置);
  • 若是[ c ]则表示为装置文件里面的串行端口设备,例如键盘、鼠标(一次性读取装置)。

  接下来的字符中,以三个为一组,且均为『rwx』 的三个参数的组合。其中,[ r ]代表可读(read)、[ w ]代表可写(write)、[ x ]代表可执行(execute)。 要注意的是,这三个权限的位置不会改变,如果没有权限,就会出现减号[ - ]而已。

  r=读取属性  //值=4
  w=写入属性  //值=2
  x=执行属性  //值=1

 (2)改变文件的运行权限:     chmod  命令:

权限范围的表示法如下:

u User,即文件或目录的拥有者;
g Group,即文件或目录的所属群组;
o Other,除了文件或目录拥有者或所属群组之外,其他用户皆属于这个范围;
a All,即全部的用户,包含拥有者,所属群组以及其他用户;
r 读取权限,数字代号为“4”;
w 写入权限,数字代号为“2”;
x 执行或切换权限,数字代号为“1”;
- 不具任何权限,数字代号为“0”;
s 特殊功能说明:变更文件或目录的权限。

chmod(选项)(参数)

选项

-c或——changes:效果类似“-v”参数,但仅回报更改的部分;
-f或--quiet或——silent:不显示错误信息;
-R或——recursive:递归处理,将指令目录下的所有文件及子目录一并处理;
-v或——verbose:显示指令执行过程;
--reference=<参考文件或目录>:把指定文件或目录的所属群组全部设成和参考文件或目录的所属群组相同;
<权限范围>+<权限设置>:开启权限范围的文件或目录的该选项权限设置;
<权限范围>-<权限设置>:关闭权限范围的文件或目录的该选项权限设置;
<权限范围>=<权限设置>:指定权限范围的文件或目录的该选项权限设置;

参数

权限模式:指定文件的权限模式;
文件:要改变权限的文件。

例子:

chmod u+x,g+w f01  //为文件f01设置自己可以执行,组员可以写入的权限
chmod u=rwx,g=rw,o=r f01
chmod 764 f01
chmod a+x f01  //对文件f01的u,g,o都设置可执行属性

文件的属主和属组属性设置

chown user:market f01  //把文件f01给uesr,添加到market组
ll -d f1  查看目录f1的属性

 3.如何设置一个服务开机启动?

  开机服务自启动就是将一可执行文件放到/etc/init.d/目录下,并在/etc/rc.d/rc[0-6].d或者/etc/rc[0-5].d目录下创建软连接。

     /etc/rc[0~6].d其实是/etc/rc.d/rc[0~6].d的软连接,主要是为了保持和Unix的兼容性才做此策

  • 创建可执行脚本文件
  • 赋予文件运行权限
chmod +x XXX.sh

  • 创建软连接

可以手动创建软连接或者chkconfig创建连接。

(1)手动在rc[0-6].d创建软连接:

  在rc0.d-rc6.d目录下分别创建文件连接。  

  第一个字符是S,系统在启动的时候,运行脚 本test2,就会添加一个start参数,告诉脚本,现在是启动模式。同时在rc0.d和rc6.d目录下,创建名字为K90test2的 文件连接,第一个字符为K,系统在关闭系统的时候,会运行test2,添加一个stop,告诉脚本,现在是关闭模式。

ln -s /etc/rc.d/init.d/test2 /etc/rc.d/rc2.d/S99test2
ln -s /etc/rc.d/init.d/test2 /etc/rc.d/rc3.d/S99test2
ln -s /etc/rc.d/init.d/test2 /etc/rc.d/rc5.d/S99test2
ln -s /etc/rc.d/init.d/test2 /etc/rc.d/rc0.d/K01test2
ln -s /etc/rc.d/init.d/test2 /etc/rc.d/rc6.d/K01test2

 (2)chkconfig创建软连接:

chkconfig --add test2

脚本的前三行如下:(脚本前面三行格式固定)

#!/bin/sh
#chkconfig: 2345 80 90
#description:test2

第一行,告诉系统使用的shell,所有的shell脚本都是这样。
第 二行,chkconfig后面有三个参数2345,80和90告诉chkconfig程序,需要在rc2.d~rc5.d目录下,创建名字为 S80test2的文件连接,连接到/etc/rc.d/init.d目录下的的test2脚本。

验证服务:

 chkconfig --list

参考:http://www.cnblogs.com/qlqwjy/p/7746184.html

 4.linux的运行级别是咋样的?

5.linux下面想要查询一个日志文件的最后20行

head,tail分别显示文件开头和结尾内容

例如查看文件前20行:

  head -n 20 xxx.txt 

查看文件最后20行

  tail -n 20 xxx.txt

 查看文件中间一段,你可以使用sed命令,如: 

sed -n '8,9p' catalina.2018-03-15.log

这样你就可以只查看文件的第8行到第9行。

如果需要实时查看日志:

tail -f catalina.out 

 

6.linux的shell类型

sh(全称 Bourne Shell): 是UNIX最初使用的 shell,而且在每种 UNIX 上都可以使用。
Bourne Shell 在 shell 编程方面相当优秀,但在处理与用户的交互方面做得不如其他几种 shell。
bash(全称 Bourne Again Shell): LinuxOS 默认的,它是 Bourne Shell 的扩展。
与 Bourne Shell 完全兼容,并且在 Bourne Shell 的基础上增加了很多特性。可以提供命令补全,命令编辑和命令历史等功能。它还包含了很多 C Shell 和 Korn Shell 中的优点,有灵活和强大的编辑接口,同时又很友好的用户界面。
csh(全称 C Shell): 是一种比 Bourne Shell更适合的变种 Shell,它的语法与 C 语言很相似。
Tcsh: 是 Linux 提供的 C Shell 的一个扩展版本。
Tcsh 包括命令行编辑,可编程单词补全,拼写校正,历史命令替换,作业控制和类似 C 语言的语法,他不仅和 Bash Shell 提示符兼容,而且还提供比 Bash Shell 更多的提示符参数。
ksh (全称 Korn Shell): 集合了 C Shell 和 Bourne Shell 的优点并且和 Bourne Shell 完全兼容。
pdksh: 是 Linux 系统提供的 ksh 的扩展。

7.Linux开放端口

/sbin/iptables -I INPUT -p tcp --dport 6379 -j ACCEPT

最后可以加个  service iptables save  永久保存

---------------------Java基础相关--------------------

0.Java所有的new操作都是在堆中创建对象,Java的下标除了JDBC获取结果集和PrepareStatement设置参数的时候从1开始,基本上所有的下标都是从0开始。

1.static关键字的用法:(从五方面解释)

  • 用来修饰成员变量,将其变为类的成员,从而实现所有对象对于该成员的共享;
  • 用来修饰成员方法,将其变为类方法,可以直接使用“类名.方法名”的方式调用,常用于工具类;
  • 静态块用法,将多个类成员放在一起初始化,使得程序更加规整,其中理解对象的初始化过程非常关键)

可以用于处理只执行一次的代码,例如:hibernate种SessionFactory的创建,mybatis的SqlSessionFactory的创建

  • 静态导包用法,将类的方法直接导入到当前类中,从而直接使用“方法名”即可调用类方法,更加方便。

import static java.lang.System.out;

out.println(HibernateUtils.openSession());

  • 静态内部类   用法

2.Java中final,finally,finalize的区别

 (1)final可以修饰类、方法、变量

  • 修饰类表示类不可以被继承
  • 修饰方法表示此方法不可以被重写(覆盖)但是可以被重载
  • 修饰变量表示变量不可变(引用不可变--也就是不可以重新指向另一个对象,但是引用内容可以变),而且static final 经常用作常量处理。

  (2)finally的使用:---通常用于try..catch..之后关闭一些IO流等操作

  1. try语句没有被执行,如在try语句之前就返回了,这样finally语句就不会执行;因此说明了finally语句被执行的必要而非充分条件是:相应的try语句一定被执行到。

  2. 如果在try代码块中执行System.exit(0)语句;那么将终止Java虚拟机JVM,因此,finally语句也不会被执行到。

  3. finally块的语句在try或catch中的return语句执行之后返回之前执行且finally里的修改语句可能影响也可能不影响try或catch中return已经确定的返回值,如果返回值类型为传址类型(String与8种包装类型除外),则影响;传值类型与String与8种基本数据类型的包装类型,则不影响。若finally里也有return语句则覆盖try或catch中的return语句直接返回(当然也会覆盖 throw )。

package cn.qlq.test;public class FinallyTest {public static void main(String[] args) {System.out.println(test1());System.out.println(test2());}public static String test1() {String s = "s1";try {int i = 1 / 0;s = "s2";return s;} catch (Exception e) {s = "s3";return s;} finally {s = "s4";}}public static Person test2() {Person p = new Person();p.setName("old");try {int i = 1 / 0;return p;} catch (Exception e) {p.setName("exception");return p;} finally {p.setName("finally");}}
}

结果:

s3
Person [age=0, name=finally]

 finally块的语句在try或catch中的return语句执行之后返回之前执行且finally里的修改语句可能影响也可能不影响try或catch中return已经确定的返回值,如果返回值类型为传址类型,则影响;传值类型(8种基本类型)与8种基本数据类型的包装类型与String(不可变类)不影响。若finally里也有return语句则覆盖try或catch中的return语句直接返回。

面试宝典解释的原因如下:

  程序在执行到return时首先会把返回值存到一个指定的位置(JVM中的slot),其次与执行finally块,最后再返回。如果finally中有return语句会以finally的return为主,相当于普通程序中的return结束函数。如果没有return语句,则会在finally执行完之后弹出slot存储的结果值并且返回,如果是引用类型则finally修改会影响结果,如果是基本数据类型或者不可变类不会影响返回结果。

  (3)finalize()析构方法的使用

  finalize()在JVM回收对象的时候会调用该对象的此方法,用于垃圾回收的时候处理一些事情

3.  switch支持的数据类型:

  记住一条,可以转为int型的都可以作为switch case的数据类型,switch表达式后面的数据类型只能是byte(1),short(2),char(2),int(4)四种整形类型(这些基本类型的包装类型是不支持的),枚举类型和java.lang.String类型(从java 7才允许),不能是boolean类型。

4.java基本数据类型的长度以及数据类型转换以及初值

Java一共提供了8种原始的数据类型(byte、short、int、long、float、double、char、boolean),这些数据类型不是对象,而是Java中不同于类的特殊类型,这些基本类型的数据变量在声明之后就会立即在栈上被分配空间。除了这些基本类型外,其他类型都是引用类型,这类变量在声明时不会被分配内存空间,只是存储了一个内存地址。

注意:

1) 在Java中,默认声明的小数是double类型的,而整数默认是int类型。

2) 在Java中,null不是一个合法的Object实例,所以编译器并没有为其分配内存,它仅仅用于表明该引用目前没有指向任何对象。null是将引用变量的值全部置0。

注意:如果是临时变量(方法内部变量)不会赋初值,只有成员属性才会赋初值。

另外注意,引用类型占用四个字节。

5.java多态----覆盖(重写概念)

覆盖就是父类的变量指向子类的对象,调用变量的方法实际上是调用子类的覆盖了父类的方法,这也是多态的体现(面试官说重写是多态,重载是不是还在研究中。。。。。。。)。

        Parent p1 = new Child1();Parent p2 = new Child2();p1.method1();//调用Child1类重写了父类的method1方法p2.method1();//调用Child2类重写了父类的method1方法

多态的三个必要条件:

  • 继承
  • 重写
  • 父类引用指向子类对象

多态的实现方式:

  重写、接口、抽象方法和抽象类

 6.  java异常

Error和Exception(运行时异常和检查异常)  参考https://www.cnblogs.com/qlqwjy/p/7816290.html

补充:一个线程运行时发生异常会怎样?

  如果异常没有被捕获该线程将会停止执行。 (这个在线程池中也会体现,线程池中当达到最大线程数某个线程执行中异常未被捕获而结束时,会重新创建一个线程)

7.  Java的Integer常量池和String常量池

  String s1 = new String("1"); 是在堆中创建一个String对象,并将s1指向该对象;String s2 = new String("1"); 又在堆中创建一个String对象,并将s2指向该对象;

  String s3 = "1";   在常量池创建一个对象1,并将s3指向该对象;String s4 = "1"  的时候常量池已经有1,所以不会再创建对象,也就是s3与s4指向同一个对象。

  Integer i1 = new Integer(1)的时候是在Java堆中创建一个Integer对象,i1指向堆中的对象,i1与常量池没关系。

  Integer i3=1;的时候是从常量池中查找值为1的常量,i3指向该常量,Integer常量池的大小是-128到127

8.深复制与浅复制区别

浅复制:被赋值的对象与原对象都含有相同的值,而所有对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅赋值所考虑的对象,而不复制它所引用的对象。

深赋值:被复制的对象的所有变量都有与原对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被赋值的新对象,而不再是原来的那些被引用的对象。换言之,深复制把复制的对象所引用的对象都复制了一遍。

9.值传递与引用传递

  1)值传递:方法调用时,实际参数把它的值传递给对应的形式参数,形式参数只是用实际参数的值初始化自己的存储单元内容,是两个不同的存储单元,所以方法执行中形式参数值的改变不影响实际参数的值。

  2)引用传递(指针传递):也称为传地址。方法调用时,实际参数是对象(或数组),这时实际参数与形式参数指向同一个地址,在方法执行中,对形式参数的操作实际上就是对实际参数的操作,所以方法执行中形式参数的改变将会影响实际参数。(包装类型是引用传值,但是由于String和8种包装类型的不可变性,所以操作形参相当于重新创建对象并赋给形参,不影响实参),数组也是引用传递。

  在Java中,原始数据类型在传递参数时都是按值传递,而包装类型在传递参数是是按引用传递,但包装类型在进行计算的时候会自动拆箱,。

  对象在函数调用传参的时候是引用传递(基本数据类型值传递),"="赋值也是引用传递(基本数据类型值传递)

10.可变类与不可变类

  不可变类:所谓的不可变类是指这个类的实例一旦创建完成后,就不能改变其成员变量值。如JDK内部自带的很多不可变类:Interger、Long和String(8种基本数据类型的包装类和String都是不可变类)等。不可变类的意思是一旦这个对象创建之后其引用不会改变,每次重新赋值会新增一个对象。不可变类是实例创建后就不可以改变成员遍历的值。这种特性使得不可变类提供了线程安全的特性但同时也带来了对象创建的开销,每更改一个属性都是重新创建一 个新的对象。例如String s = "s1",s = "s2"实际上是创建了两个对象,第二次将其值指向新的"s2".。

  可变类:相对于不可变类,可变类创建实例后可以改变其成员变量值,开发中创建的大部分类都属于可变类

11.创建对象的五种方式

  

12.  一个有返回值的方法必须有return语句吗?

  如果把return和throw放在一起,直接会提示错误,"Unreachable statement"(无法被执行)。 retrun和throw都是使程序跳出当前的方法。所以有throw 的时候会退出当前程序也就不需要return。

---------------------多线程相关-------------------------

参考:http://www.cnblogs.com/xrq730/p/5060921.html

1.Thread和Runnable的区别和联系

2.多次start一个线程会怎么样:  可以看出如果线程状态不是新建就会抛出非法状态异常。也就是多次start会抛出非法状态异常。

    public synchronized void start() {if (threadStatus != 0)throw new IllegalThreadStateException();
group.add(this);boolean started = false;try {start0();started = true;} finally {try {if (!started) {group.threadStartFailed(this);}} catch (Throwable ignore) {/* do nothing. If start0 threw a Throwable thenit will be passed up the call stack */}}}

3.线程有哪些状态

    public enum State {NEW,
RUNNABLE,
BLOCKED,
WAITING,
TIMED_WAITING,
TERMINATED;}

1、新建状态NEW

  new了线程但是没有开始执行,比如: Thread t1 = new Thread();t1就是一个新建状态的线程。

2、可运行状态RUNNABLE

  new出来线程,调用start()方法即处于RUNNABLE状态了。处于RUNNABLE状态的线程可能正在Java虚拟机中运行,也可能正在等待处理器的资源,因为一个线程必须获得CPU的资源后,才可以运行其run()方法中的内容,否则排队等待

3、阻塞BLOCKED

  如果某一线程正在等待监视器锁,以便进入一个同步的块/方法,那么这个线程的状态就是阻塞BLOCKED

4、等待WAITING

  某一线程因为调用不带超时的Object的wait()方法、不带超时的Thread的join()方法、LockSupport的park()方法,就会处于等待WAITING状态

5、超时等待TIMED_WAITING

  某一线程因为调用带有指定正等待时间的Object的wait()方法、Thread的join()方法、Thread的sleep()方法、LockSupport的parkNanos()方法、LockSupport的parkUntil()方法,就会处于超时等待TIMED_WAITING状态

6、终止状态TERMINATED

  线程调用终止或者run()方法执行结束后,线程即处于终止状态。处于终止状态的线程不具备继续运行的能力。

---------------------Web前端相关-------------------------

1.JS闭包概念

---------------------JavaWeb相关-------------------------

---------------------数据结构相关--------------------------

---------------------数据库相关--------------------------

---------------------Java框架相关-------------------------

转载于:https://www.cnblogs.com/qlqwjy/p/8658875.html

面试笔记【自己总结】相关推荐

  1. 应有尽有!这可能是最全的 AI 面试笔记了

    点击上方"视学算法",选择"星标"公众号 重磅干货,第一时间送达 今天给大家推荐一个非常全面的 AI 面试笔记集锦,包含 2018.2019 年的校招.春招.秋 ...

  2. springaop事务逻辑原理_太狠了!阿里大牛手写的Spring核心面试笔记:IOC+AOP+MVC+事务...

    Spring作为现在最流行的java 开发技术,其内部源码设计非常优秀.如果你不会Spring,那么很可能面试官会让你回家等通知. Spring是什么? 有一个工地,几百号人在用铁锹铲子挖坑. 如果开 ...

  3. 炼丹面试官的面试笔记

    作者:无名,某小公司算法专家 排版:一元,四品炼丹师 公众号:炼丹笔记 关于Attention和Transformer的灵魂拷问 背景 现在几乎很多搞深度学习的朋友都把attention和Transf ...

  4. Java高级开发工程师面试笔记

    最近在复习面试相关的知识点,然后做笔记,后期(大概在2018.02.01)会分享给大家,尽自己最大的努力做到最好,还希望到时候大家能给予建议和补充 ----------------2018.03.05 ...

  5. labuladong的算法小抄pdf_真漂亮!这份GitHub上爆火的算法面试笔记,助你圆满大厂梦...

    前言 Github作为程序员们的后花园,一直以来都是程序员最喜欢逛逛.学习的地方,小编也不例外,最近看到一份对标BAT等一线大厂的算法面试笔记,已经标星68+K了,很是惊讶,看了一下,觉得知识点整理得 ...

  6. jsjq面试笔记(下)

    js&jq面试笔记,该部分为下部分. 字符串相关 1.定义一个方法,用于将string中的每个字符之间加一个空格,并输出 如:'hello' -> 'h e l l o'function ...

  7. 怎么判断自己启动的线程是否执行完成 java_Java面试笔记(上)

    面试整体流程(HR 或技术面) 1.请简单的自我介绍 我叫***,工作*年了,先后做过**项目.**项目. 2.请你简单的介绍一下**项目 该系统主要有哪些部分组成,简单介绍项目的整体架构,具体参与某 ...

  8. 网易被裁后,68天吃透这份阿里学长甩我的Android面试笔记,竟让我收到字节跳动和小米offer

    自我情况介绍一下: 楼主双非本科,17年毕业,学历背景一般,之前一直在网易工作,生活状态还算是稳定,国庆节后突然被裁彻底打破了我的生活节奏,将近一个月都处在懵逼状态(哪个环节出问题了,导致被裁),在咨 ...

  9. GitHub上AI岗位面试笔记(机器学习算法/深度学习/ NLP/计算机视觉)

    目录 机器学习 深度学习 自然语言处理与数学 算法题和笔试题 推荐阅读 工具 最近在GitHub上淘到一个很棒的AI算法面试笔记,特地分享给小伙伴们~ GitHub地址:https://github. ...

  10. 剖析Framework面试-笔记(二)

    剖析Framework面试-笔记 其他应用组件相关 Service的启动原理 Service的绑定原理 使用 原理 动态广播的注册与收发原理 动态广播的注册原理 广播的发送原理 广播的接受原理 静态广 ...

最新文章

  1. LTE - PUCCH Format2
  2. tomcat主目录(ROOT.xml)和虚拟目录
  3. python打不开怎么办-python为什么打不开
  4. android闹钟唤醒不准的原因_俄罗斯睡眠专家:闹钟铃声选错了,可能扰乱你的内分泌...
  5. 高颜值网易云音乐第三方播放器 YesPlayMusic Mac中文版 支持m1
  6. 自动化系统计算机网络期末考试题,模拟试卷_计算机网络试题B-自动化-孙璐
  7. C++ 泛型编程的基础--模板初识及应用
  8. C++ 序列式容器之vector
  9. grpc框架_grpc的入门使用
  10. DataGradView操作之,列头右键菜单隐藏和显示字段功能
  11. Debug Android with Android phone.
  12. jinyuan oracle,简述Oracle IOT(Index Organized Table)(下)
  13. ROS-Kinetic安装turtlebot-3并仿真
  14. 抖音服务器升级维护时间,抖音服务器升级要多久2021
  15. PHP商城网站绑定中国银联在线支付接口
  16. 校内计算机无法报名高考,没有奖项可以报名自主招生吗?报考条件建议65问
  17. Laravel 生成Controller
  18. 五线谱上的Linux旋律
  19. Android视频背景,动态背景,Android用视频做背景的轻松实现
  20. 那些年,我们走过的Github坑

热门文章

  1. 精妙SQL语句集合(收集)
  2. SELinux系列(十七)—awk命令使用详解
  3. c语言 乘号 指针 避免,C语言指针篇(一)指针与指针变量
  4. 高考语文再现奇葩作文题!大数据分析高考作文,看看哪年最坑爹?
  5. 超越Excel、python的数据可视化报表,月薪3W的人都在用
  6. mysql遇见 column count of mysql.proc is wrong expected 20 found16
  7. volatile,static,const,extern等关键字
  8. c语言http协议头字符串,c语言http请求解析表单内容
  9. c#截取后几位_C#几种截取字符串的方法小结
  10. iis搭建php出现301,IIS服务器PHP下三种实现301重定向的方法