php面试整理

wuchangjian2021-11-15 01:09:45编程学习

php面试整理

*什么是操作系统?知道那些

概念(来源于百度):

操作系统(operating system,简称OS)是管理计算机硬件与软件资源的计算机程序。操作系统需要处理如管理与配置内存、决定系统资源供需的优先次序、控制输入设备与输出设备、操作网络与管理文件系统等基本事务。操作系统也提供一个让用户与系统交互的操作界面。

*什么是面向对象

面向对象说到底就是一种思想,任何事物都可以看作是一个对象。在有些面试题目中也称之为OOP(Object Oriented Programming)。

面向对象主要的思想是:封装继承多态抽象

  • 封装就是模块化,把不同的功能,封装在不同的模块里。
  • 继承就是给对象提供了从基类获取字段和方法得能力
  • 多态,相当于对于同一个接口类型,由多种不同的实现方式,所衍生出来的。
  • 抽象,相当于把具体的实例中,把本质抽象出来。把行为和具体的实现进行分离开来,对于程序的保密起到一定的作用

面向对象内容

  • − 定义了一件事物的抽象特点。类的定义包含了数据的形式以及对数据的操作。
  • 对象 − 是类的实例。
  • 成员变量 − 定义在类内部的变量。该变量的值对外是不可见的,但是可以通过成员函数访问,在类被实例化为对象后,该变量即可成为对象的属性。
  • 成员函数 − 定义在类的内部,可用于访问对象的数据。
  • 继承 − 继承性是子类自动共享父类数据结构和方法的机制,这是类之间的一种关系。在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并加入若干新的内容。
  • 父类 − 一个类被其他类继承,可将该类称为父类,或基类,或超类。
  • 子类 − 一个类继承其他类称为子类,也可称为派生类。
  • 多态 − 多态性是指相同的函数或方法可作用于多种类型的对象上并获得不同的结果。不同的对象,收到同一消息可以产生不同的结果,这种现象称为多态性。
  • 重载 − 简单说,就是函数或者方法有同样的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数或者方法。
  • 抽象性 − 抽象性是指将具有一致的数据结构(属性)和行为(操作)的对象抽象成类。一个类就是这样一种抽象,它反映了与应用有关的重要性质,而忽略其他一些无关内容。任何类的划分都是主观的,但必须与具体的应用有关。
  • 封装 − 封装是指将现实世界中存在的某个客体的属性与行为绑定在一起,并放置在一个逻辑单元内。
  • 构造函数 − 主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。
  • 析构函数 − 析构函数(destructor) 与构造函数相反,当对象结束其生命周期时(例如对象所在的函数已调用完毕),系统自动执行析构函数。析构函数往往用来做"清理善后" 的工作(例如在建立对象时用new开辟了一片内存空间,应在退出前在析构函数中用delete释放)。

对象的主要三个特性

  • 对象的行为:可以对 对象施加那些操作,开灯,关灯就是行为。
  • 对象的形态:当施加那些方法是对象如何响应,颜色,尺寸,外型。
  • 对象的表示:对象的表示就相当于身份证,具体区分在相同的行为与状态下有什么不同。

preg_match — 进行正则表达式匹配。

语法:

int preg_match ( string $pattern , string $subject [, array $matches [, int $flags ]] )

在 subject 字符串中搜索与 pattern 给出的正则表达式相匹配的内容。如果提供了 matches ,则其会被搜索的结果所填充。 m a t c h e s [ 0 ] 将 包 含 与 整 个 模 式 匹 配 的 文 本 , matches[0] 将包含与整个模式匹配的文本, matches[0]matches[1] 将包含与第一个捕获的括号中的子模式所匹配的文本,以此类推。

Cookie 是什么?如何取回 Cookie 的值?

cookie 常用于识别用户。cookie 是一种服务器留在用户计算机上的小文件。每当同一台计算机通过浏览器请求页面时,这台计算机将会发送 cookie。通过 PHP,您能够创建并取回 cookie 的值。

语法

setcookie(name, value, expire, path, domain);
//规定了此 cookie 在一小时后过期:
setcookie("user", "runoob", time()+3600);

取回

PHP 的 $_COOKIE 变量用于取回 cookie 的值。

// 输出 cookie 值
echo $_COOKIE["user"];
// 查看所有 cookie
print_r($_COOKIE);

Session 的工作机制

为每个访客创建一个唯一的 id (UID),并基于这个 UID 来存储变量。UID 存储在 cookie 中,或者通过 URL 进行传导。

  • 在您把用户信息存储到 PHP session 中之前,首先必须启动会话。**注释:**session_start() 函数必须位于 标签之前:

  • 存储和取回 session 变量的正确方法是使用 PHP $_SESSION 变量:

    <?php
    session_start();
    // 存储 session 数据
    $_SESSION['views']=1;
    ?>
     
    <html>
    <head>
    <meta charset="utf-8">
    <title>菜鸟教程(runoob.com)</title>
    </head>
    <body>
     
    <?php
    // 检索 session 数据
    echo "浏览量:". $_SESSION['views'];
    ?>
     
    </body>
    </html>
    
  • 如果您希望删除某些 session 数据,可以使用 unset() 或 session_destroy() 函数。unset() 函数用于释放指定的 session 变量:

    <?php
    session_start();
    if(isset($_SESSION['views']))
    {
        unset($_SESSION['views']);
    }
    ?>
        ||
    <?php
    session_destroy();
    ?>    
    

php关键词

image-20211113234502455

*****变量作用域,什么是引用变量?在php中用什么符号定义引用变量?

PHP 变量作用域

变量的作用域是脚本中变量可被引用/使用的部分。

PHP 有四种不同的变量作用域:

序号作用域描述
1local局部作用域
2global全局作用域
3static静态作用域
4parameter函数参数作用域
  • local:(本地的)—— 局部变量的作用域在 PHP 函数内部声明的变量是局部变量,仅能在函数内部访问。

  • global:用于函数内访问全局变量。在函数内调用函数外定义的全局变量,我们需要在函数中的变量前加上 global 关键字

    <?php
    $a = 10;
    $b = 5;
    function test1(){global $a,$b;$z = $a - $b;echo '1-: '.$z.'---';}
    test1();
    ?>
    
  • static:当一个函数完成时,它的所有变量通常都会被删除。然而,有时候您希望某个局部变量不要被删除。

    要做到这一点,请在您第一次声明变量时使用 static 关键字

    <?php
    function test(){$a = 0;echo $a.'---   ';$a++;}
    function test1(){static $a = 0;echo $a.'---';$a++;}
    test();test();test();
    test1();test1();test1();
    ?>
    
  • parameter:(参数)——参数作用域参数是通过调用代码将值传递给函数的局部变量。

    ​ 关于局部变量和全局变量的优先级,因为在PHP中函数都有自己单独的作用域,所以在局部变量的优先级要大于全局变量(在你不声明这个变量之前),声明之后此变量就变成了局部变量如果修改值那么全局变量的值也会改变。

    <?php
    $a = 10;
    $b = 5;
    function test(){global $a,$b;$a = 15;$z = $a - $b;echo '0-: '.$z.'---';}
    function test1(){global $a,$b;$z = $a - $b;echo '1-: '.$z.'---';}
    function test2(){global $a,$b;$a = 15;$z = $a - $b;echo '2-: '.$z;}
    test();//如果此方法注释运行结果为5 10;否则10 10 10
    test1();
    test2();
    ?>
    

引用变量

概念:

在PHP中,引用意味着用不同的名字访问同一个变量内容。

定义方式:

使用 & 符号

延伸:PHP引用变量的原理

1赋值:

将一个变量的值赋值给另一个变量,其中一个变量的值进行改变,会重新进行拷贝,此时会再开辟一个新的内存空间。

// 1. 定义一个变量
$a = range(0, 1000); // 在内存中开辟一片空间,存储变量a
var_dump(memory_get_usage());

// 2. 定义变量 b,将 a变量的值赋值给 b
$b = $a; // 将变量b 指向 变量a开辟的空间中
var_dump(memory_get_usage());

// 3. 对 a进行修改
$a = range(0, 1000);
var_dump(memory_get_usage());

原理:

使用了 COW(Copy On Write)机制 : 对 $a$b 其中一个进行改变,内存空间才会发生改变。

  • 在内存中开辟一片空间存储变量a;
  • 将变量b 指向 变量a的内存空间中;
  • 对变量a进行修改(对a进行写操作),此时会再开辟一片内存空间存储a 和 a和a和b(原来的a 和 a和a和b被改变)
2引用:

两个变量无论何时都共用一个内存空间(对其中一个的值进行更改的时候,不会开辟新的内存空间)

// 1. 定义一个变量
$a = range(0, 1000);
var_dump(memory_get_usage());
// 2. 定义变量b, 将a变量的值赋值给b
$b = &$a;
var_dump(memory_get_usage());
// 3. 对a进行修改
$a = range(0, 1000);
var_dump(memory_get_usage());

原理:

  • 定义一个变量a(开辟一个内存空间存储变量a);
  • 定义变量b , 将 b,将b,将a的地址给了b , 此 时 b,此时b,此时b与$a指向同一个内存空间,且永远指向该内存空间(不会再重新拷贝,改掉的只是该内存空间的值);
  • 对a进行修改(不会再开辟内存空间),此时a 和 a和a和b的值,都是修改后的值;
3unset只会取消引用,不会销毁内存空间
$a = 1; // 开辟一个内存空间存储变量a,并赋值为1
$b = &$a; // 将$a的引用赋值给$b,此时$a和$b指向同一个内存空间(永久指向)
unset($b); // 此时取消的是$a和$b的引用,不会取消内存空间
echo $a.'<br>'; // 1
4对象本身就是引用传递,在修改时,不会重新开辟内存空间
class Person
{
    public $name = 'zhangsan';
}

$p1 = new Person; // 开辟一个内存空间存储$p1
$p2 = $p1; // 将$p1和$p2存入同一个内存空间(内存空间会变大)
$p2->name = 'lisi'; // $p1,$p2都为lisi,因为指向的是同一个内存空间
真题
写出如下程序的输出结果:
$data = ['a', 'b', 'c'];

foreach ($data as $key => $val) { 
    $val = &$data[$key]; 
}
  1. 程序运行时,每一次循环结束后变量 $data的值时什么?请解释
  2. 程序执行完成后,变量 $data的值时什么?请解释

答案:

// 第一次循环
$data = ['a', 'b', 'c'];
// 第二次循环
$data = ['b', 'b', 'c'];
// 第三次循环
$data = ['b', 'c', 'c'];
// 程序执行完成后,变量 $data的值
$data = ['b', 'b', 'c'];

解析:

1foreach ($data as $key => $val)
	会将$data第一个元素的键名赋值给$key,将$data的第一个元素的值赋值给$val($k=0; $v=a;)
2) $val = &$data[$key]; 
	$v = &$data[0];(即$v拿了$data[0]的地址)
	$v = &$data[0] = a(此时$data[0]$v都指向 a内存空间)
	
以上步骤即为:
1)第一次循环:
	$k = 0;
	$v = a;
	$v = &$data[0];
	($v = &$data[0] = a,$v$data[0] 都指向 a内存空间) // 结果:$data = ['a','b','c'];
2)第二次循环:
	$k = 1;
	$v = b;
	$data[0] = b;
	$v = &$data[1];
	($v = &$data[1] = b, $v$data[1] 都指向 b内存空间) // 结果:$data = ['b','b','c'];
3)第三次循环:	
	$k = 2;
	$v = c;
	$data[1] = $c;
	$v = &$data[2];
	($v = &$data[2] = c, $v$data[1] 都指向 c内存空间) // 结果:$data = ['b','c','c'];

代码测试:

$data = ['a', 'b', 'c'];

foreach ($data as $k => $v) {
    $v = &$data[$k];
    var_dump($data);
}
var_dump($data);

image-20211111182519200

PHP 超级全局变量

  1. $_GET –> get 传送方式
  2. $_POST –> post 传送方式
  3. $_REQUEST –> 可以接收到 get 和 post 两种方式的值
  4. $GLOBALS –> 引用全局作用域中可用的全部变量
  5. $_FILES –> 上传文件使用
  6. $_SERVER –> 系统环境变量
  7. $_SESSION –> 用于会话控制
  8. $_COOKIE –> 用于会话控制
  9. $_ENV –> 服务器端环境变量

*php数据类型

String(字符串), Integer(整型), Float(浮点型), Boolean(布尔型), Array(数组), Object(对象), NULL(空值)。

PHP 类型比较

  • 松散比较:使用两个等号 == 比较,只比较值,不比较类型。
  • 严格比较:用三个等号 === 比较,除了比较值,也比较类型。

PHP 常量

使用 define() 函数:

bool define ( string $name , mixed $value [, bool $case_insensitive = false ] )
  • **name:**必选参数,常量名称,即标志符。
  • **value:**必选参数,常量的值。
  • case_insensitive :[]可选参数,如果设置为 TRUE,该常量则大小写不敏感。默认是大小写敏感的。

PHP 8个魔术常量

定义如:namespace Api\Controller;

strlen() 函数和strpos() 函数

  • strlen() 函数返回字符串的长度(字节数)。
  • strpos() 函数用于在字符串内查找一个字符或一段指定的文本。如果在字符串中找到匹配,该函数会返回第一个匹配的字符位置。如果未找到匹配,则返回 FALSE。

*echo 和 print 区别,PHP的几种打印输出

echo 和 print 区别:

  • echo - 可以输出一个或多个字符串 无返回值
  • print - 只允许输出一个字符串,返回值总为 1

PHP的几种打印输出:

  • echo - 可以输出一个或多个字符串 无返回值
  • print - 只允许输出一个字符串,返回值总为 1
  • print_r - 显示数组类型
  • var_dump - 显示数组类型,显示判断条件的是与非,比print_r()显示的更详细

PHP EOF(heredoc)

概念:

PHP EOF(heredoc)是一种在命令行shell(如sh、csh、ksh、bash、PowerShell和zsh)和程序语言(像Perl、PHP、Python和Ruby)里定义一个字符串的方法。

  • <<<EOF 开始标记开始,以 EOF 结束标记结束,结束标记必须顶头写,不能有缩进和空格,且在结束标记末尾要有分号

  • 开始标记和结束标记相同,比如常用大写的 EOT、EOD、EOF 来表示,但是不只限于那几个(也可以用:JSON、HTML等),只要保证开始标记和结束标记不在正文中出现即可。

  • 位于开始标记和结束标记之间的变量可以被正常解析,但是函数则不可以。在 heredoc 中,变量不需要用连接符 ., 来拼接,如下:

    <?php
    $name="runoob";
    $a= <<<EOF
            "abc"$name
            "123"
    EOF;
    // 结束需要独立一行且前后不能空格
    echo $a;
    ?>
    

数组是什么?php数组,数组排序函数

概念:

数组是一个能在单个变量中存储多个值的特殊变量。

php数组
//数值数组 自动分配 ID 键(ID 键总是从 0 开始):
$cars=array("Volvo","BMW","Toyota");
//关联数组是使用您分配给数组的指定的键的数组。
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");
//多维数组是包含一个或多个数组的数组。
$sites = array("google"=>array("Google","baidu"),"taobao"=>array("淘宝","京东"));
数组排序函数
  • sort() - 对数组进行升序排列
  • rsort() - 对数组进行降序排列
  • asort() - 根据关联数组的值,对数组进行升序排列
  • ksort() - 根据关联数组的键,对数组进行升序排列
  • arsort() - 根据关联数组的值,对数组进行降序排列
  • krsort() - 根据关联数组的键,对数组进行降序排列

如何避免 $_SERVER[“PHP_SELF”] 被利用?

$_SERVER["PHP_SELF"] 可以通过 htmlspecialchars() 函数来避免被利用。

<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
//htmlspecialchars() 把一些预定义的字符转换为 HTML 实体。现在如果用户想利用 PHP_SELF 变量, 结果将输出如下所示:
<form method="post" action="test_form.php/&quot;&gt;&lt;script&gt;alert('hacked')&lt;/script&gt;">

*****写出jQuery中,,可以处理ajax的几种方法。

Ajax概念

Ajax(Asynchronous JavaScript and XML ):是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。核心就是JavaScript对象XmlHttpRequest

原生ajax请求:
<script type="text/javascript">
	//使用JavaScript语言发起Ajax请求,访问服务器AjaxServlet中JavaScriptAjax
    function ajaxRequest(){
    	//1,创建XMLHttpRequest
    	var xmlhttprequest = new XMLHttpRequest();
    	/*2,调用open方法设置请求参数open(method,url,asyn);
    	method:请求方式;
    	url:请求地址;
    	asyn:true表示异步,请求发送后,不管服务器是否响应,客户端程序继续执行。false客户端程序将阻塞来等待服务端响应,影响体验。
    	*/
    	xmlhttprequest.open("GET","url",true);
    	//4,在send前绑定onreadystatechange事件,处理请求完成后的操作。
    	xmlhttprequest.onreadystatechange = function(){
         	if(xmlhttprequest.readyState == 4 &&
               xmlhttprequest.status == 200){
                var jsonObj = JSON.parse(xmlhttprequest.responseText);
                //把响应数据展示
                document.getElementById("#id").innerHtml = jsonObj.data;
            }   
        }
    	//3,调用send方法发送请求
    	xmlhttprequest.send();
	}
    
    
</script>
jQuery中的Ajax请求

表单序列化 serialize()

serialize()可以把表单中所有表单项的内容都获取到,并以 name=value&name=value 的形式进行拼接。

$("#id").click(function(){
    $.getJSON("url",
             "action=jQuerySerialize&"+$("#id").serialize(),
             function(data){
        		$("#msg").html(data.datas);//展示响应数据
    });
};
1、$.ajax方法
  • url 表示请求的地址

  • type 表示请求的类型 GET 或 POST 请求

  • data 表示发送给服务器的数据格式有两种: 1:name=value&name=value 2:{key:value}

  • success 请求成功,响应的回调函数

  • dataType 响应的数据类型 常用的数据类型有: text 表示纯文本 xml 表示 xml 数据 json 表示 json 对象

$("#id").click(function(){
    $.ajax({
        url:"",
        data:{action:"jQueryAjax"},
        type:"GET",
        success:function(data){
            $("#msg").html(data.datas);//展示响应数据
        },
        dataType:"json"
    })
});
2、$.get$.post方法
  • url 请求的url地址

  • data 发送的数据

  • callback 成功的回调函数

  • type 返回的数据类型

    因为get或post已经写明了请求的类型,所以不用传入type参数了

//ajax--get

$("#id").click(function(){
    $.get("url",
          "action=jQueryGet",
          function(data){
        	$("#msg").html(data.datas);//展示响应数据
    	  },
          "json");
});
//ajax--post
$("#id").click(function(){
    $.post("url",
           {
        	action:"jQueryGet",
        	data:"data"
           },
          function(data){
        	$("#msg").html(data.datas);//展示响应数据
          },
          "json");
});
3、getJSON方法
  • url 请求的 url 地址

  • data 发送给服务器的数据

  • callback 成功的回调函数

    与之前同理,写明了请求的类型并且写明返回的数据类型,因此可以少传两个参数。

$("#id").click(function(){
    $.getJSON("url",
             {
        		action:"jQueryGet",
        		data:"data"
             },
             function(data){
        		$("#msg").html(data.datas);//展示响应数据
    });
};
4、load方法
$("#id").load(url,data,callback);//从服务器加载数据,并把返回的数据放入被选元素中。
Ajax跨域问题

跨域:当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域

当前页面url被请求页面url是否跨域原因
http://www.test.com/http://www.test.com/index.html同源(协议、域名、端口号相同)
http://www.test.com/https://www.test.com/index.html跨域协议不同(http/https)
http://www.test.com/http://www.baidu.com/跨域主域名不同(test/baidu)
http://www.test.com/http://blog.test.com/跨域子域名不同(www/blog)
http://www.test.com:8080/http://www.test.com:7001/跨域端口号不同(8080/7001)
跨域问题解决
1、响应头添加Header允许访问

在服务端填上响应头:

response.addHeader(‘Access-Control-Allow-Origin:*);//允许所有来源访问 
response.addHeader(‘Access-Control-Allow-Method:POST,GET);//允许访问的方式

image-20211111210825515

2、jsonp 只支持get请求不支持post请求

原理:

ajax本身是不可以跨域的,通过产生一个script标签来实现跨域。因为script标签的src属性是没有跨域的限制的。其实设置了dataType: 'jsonp'后,$.ajax方法就和ajax XmlHttpRequest没什么关系了,取而代之的则是JSONP协议。JSONP是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问。

在同源策略下,在某个服务器下的页面是无法获取到该服务器以外的数据的,即一般的ajax是不能进行跨域请求的。但 img、iframe 、script等标签是个例外,这些标签可以通过src属性请求到其他服务器上的数据。利用<script>标签的开放策略,我们可以实现跨域请求数据,当然这需要服务器端的配合。 Jqueryajax的核心是通过 XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加<script>标签来调用服务器提供的 js脚本。

ajax的跨域写法:

  • ①dataType改为jsonp
  • ②jsonp : “jsonpCallback”————发送到后端实际为http://a.a.com/a/FromServlet?userName=644064&jsonpCallback=jQueryxxx
  • ③后端获取get请求中的jsonpCallback
  • ④构造回调结构
//原生js
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />  
<script type="text/javascript">  
    function jsonpCallback(result) {  
        //alert(result);  
        for(var i in result) {  
            alert(i+":"+result[i]);//循环输出a:1,b:2,etc.  
        }  
    }  
    var JSONP=document.createElement("script");  
    JSONP.type="text/javascript";  
    JSONP.src="http://crossdomain.com/services.php?callback=jsonpCallback";  
    document.getElementsByTagName("head")[0].appendChild(JSONP);  
</script> 
//jQuery+Ajax
$.ajax({
			type : "GET",
			async : false,
			url : "http://a.a.com/a/FromServlet?userName=644064",
			dataType : "jsonp",//数据类型为jsonp  
			jsonp : "jsonpCallback",//服务端用于接收callback调用的function名的参数
			success : function(data) {
				alert(data["userName"]);
			},
			error : function() {
				alert('fail');
			}
});
//后端servlet
        String jsonpCallback = request.getParameter("jsonpCallback");
		//构造回调函数格式jsonpCallback(数据)
		resp.getWriter().println(jsonpCallback+"("+jsonObject.toJSONString()+")");
//服务端PHP代码 (services.php):
function api_jsonp_encode($json)
    {
        if (!empty($_GET['callbak'])) {
            return $_GET['callbak'] . '(' . $json . ')'; // jsonp
        }
        return $json; // json
    }
3、httpClient内部转发

原理:

若想在B站点中通过Ajax访问A站点获取结果,固然有ajax跨域问题,但在B站点中访问B站点获取结果,不存在跨域问题,这种方式实际上是在B站点中ajax请求访问B站点的HttpClient,再通过HttpClient转发请求获取A站点的数据结果。但这种方式产生了两次请求,效率低,但内部请求,抓包工具无法分析,安全。

$.ajax({
			type : "GET",
			async : false,
			url : "http://b.b.com:8080/B/FromAjaxservlet?userName=644064",
			dataType : "json",
			success : function(data) {
				alert(data["userName"]);
			},
			error : function() {
				alert('fail');
			}
});
//服务端
@WebServlet("/FromAjaxservlet")
public class FromAjaxservlet extends HttpServlet{
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		try {
			//创建默认连接
			CloseableHttpClient httpClient = HttpClients.createDefault();
			//创建HttpGet对象,处理get请求,转发到A站点
			HttpGet httpGet = new HttpGet("http://a.a.com:8080/A/FromServlet?userName="+req.getParameter("userName")); 
                        //执行
			CloseableHttpResponse response = httpClient.execute(httpGet);
			int code = response.getStatusLine().getStatusCode();
			//获取状态
			System.out.println("http请求结果为:"+code);
			if(code == 200){
                                //获取A站点返回的结果
				String result = EntityUtils.toString(response.getEntity());
				System.out.println(result);
                                //把结果返回给B站点
				resp.getWriter().print(result);
			}
			response.close();
			httpClient.close();
		} catch (Exception e) {
		}
	}
}
4、使用接口网关——nginx、springcloud zuul (互联网公司常规解决方案)
  • www.a.a.com不能直接请求www.b.b.com的内容,可以通过nginx,根据同域名,但项目名不同进行区分。什么意思呢?这么说可能有点抽象。假设我们公司域名叫www.nginxtest.com

  • 当我们需要访问www.a.a.com通过www.nginxtest.com/A访问,并通过nginx转发到www.a.a.com

  • 当我们需要访问www.b.b.com通过www.nginxtest.com/B访问,并通过nginx转发到www.a.a.com

  • 我们访问公司的域名时,是"同源"的,只是项目名不同,此时项目名的作用只是为了区分,方便转发。如果你还不理解的话,先看看我是怎么进行配置的:

server {
        listen       80;
        server_name  www.nginxtest.com;
        location /A {
		    proxy_pass  http://a.a.com:81;
			index  index.html index.htm;
        }
		location /B {
		    proxy_pass  http://b.b.com:81;
			index  index.html index.htm;
        }
    }

我们访问以www.nginxtest.com开头且端口为80的网址,nginx将会进行拦截匹配,若项目名为A,则分发到a.a.com:81。实际上就是通过"同源"的域名,不同的项目名进行区分,通过nginx拦截匹配,转发到对应的网址。整个过程,两次请求,第一次请求nginx服务器,第二次nginx服务器通过拦截匹配分发到对应的网址。

写出尽可能多的Linux命令

Linux常用命令

系统安全
sudo // 超级用户
su // 用于切换当前用户身份到其他身份,变更时需输入所要变更的用户账号与密码。
chmod // 用来变更文件或目录的权限
setfacl // 设置文件访问控制列表
进程管理
w // 用于显示已经登陆系统的用户列表,并显示用户正在执行的指令。
top // 可以实时动态地查看系统的整体运行情况,是一个综合了多方信息监测系统性能和运行信息的实用工具。
ps // 用于报告当前系统的进程状态。
kill // 用来删除执行中的程序或工作。
pkill // 可以按照进程名杀死进程。
pstree // 以树状图的方式展现进程之间的派生关系,显示效果比较直观。
killall // 使用进程的名称来杀死进程,使用此指令可以杀死一组同名进程。
用户管理
id        // 可以显示真实有效的用户ID(UID)和组ID(GID)。
usermod   // 用于修改用户的基本信息。
useradd   // 用于 Linux中创建的新的系统用户。
groupadd  // 用于创建一个新的工作组,新工作组的信息将被添加到系统文件中。
userdel   // 用户删除给定的用户,以及与用户相关的文件。若不加选型,则进删除用户账号,而不删除相关文件。

文件系统
mount // 用户加载文件系统到指定的加载点。
umount // 用于卸载已经加载的文件。
fsck // 用于检查并且试图修复文件系统中的错误。
df // 用于显示磁盘分区上的可使用的磁盘空间。
du // 对文件和目录磁盘使用的空间的查看。
系统关机和重启
shutdown // 关机
reboot // 重启
网络应用
curl // 是一个利用URL规则在命令行下工作的文件传输工具。
telnet // 用于登录远程主机,对远程主机进行管理。
mail // 命令行的电子邮件发送和接收工具。
elinks // 能实现一个纯文本界面的WWW浏览器,操作方式与"lynx"类似。
网络测试
ping // 用于测试主机之间网络的连通性。
netstat // 用来打印Linux中网络系统的状态信息,可让你得知整个Linux系统的网络情况。
host // 常用的分析域名查询工具,可以用来测试域名系统工作是否正常。
网络配置
hostname // 用于显示和设置系统的主机名称。
ifconfig // 被用于配置和显示Linux内核中网络接口的网络参数。
常用工具
ssh // 时openssh套件中的客户端连接工具,可以给予ssh加密协议实现安全的远程登录服务器。
screen // 是一款由GNU计划开发的用于命令行终端切换的自由软件。
clear // 用于清除当前屏幕终端上的任何信息。
who // 显示当前登录系统的用户信息。
date // 显示或设置系统时间与日期。
软件包管理
yum // 提供了查找、安装、删除某一个、一组甚至全部软件包的命令,而且命令简洁而又好记。
rpm // rpm软件包的管理工具。
apt-get // Debian Linux发行版中的APT软件包管理工具。所有基于Debian的发行都使用这个包管理系统。deb包可以把一个应用的文件包在一起,大体如同 Windows上的安装文件。
文件查找和比较
locate // 用来查找文件或目录。
find // 用来在指定目录下查找文件。
文件内容查看
head // 用于显示文件的开头的内容。在默认情况下,head命令显示文件的头10行内容。
tail // 用于输入文件中的尾部内容。tail命名默认在屏幕上显示指定文件的末尾10行。
more // 用来浏览文件档案的内容(只能向前浏览)。
less // 用来浏览文字档案的内容,允许用户向前或向后浏览文件。使用该命令时,用PageUp键向上翻页,用PageDown键向下翻页。要退出less程序,应按Q键。
文件处理
unlink // 用于系统调用函数 unlink 去删除指定的文件。
rename // 用字符串替换的方式批量改变文件名。
cat // 连接文件并打印到标准输出设备上,cat经常用来显示文件的内容。
touch // 有两个功能:一是用于把已存在文件的时间标签更新为系统当前的时间(默认方式),它们的数据将原封不动地保留下来;二是用来创建新的空文件。
ln // 用来为文件创建连接,连接类型分为硬连接和符号连接两种,默认的连接类型是硬连接。如果要创建符号连接必须使用"-s"选项(注意:符号链接文件不是一个独立的文件,它的许多属性依赖于源文件,所以给符号链接文件设置存取权限时没有意义的)
目录操作
cd // 用来切换工作目录至 dirname。
mv // 用来对文件或目录重新命名,或者将文件从一个目录移到另一个目录中。
rm // 可以删除一个目录中的一个或多个文件或目录,也可以将某个目录及其下属的所有文件及其子目录均删除掉。
pwd // 以绝对路径的方式显示用户当前工作目录。
tree // 以树状图列出目录的内容。
cp // 用来将一个或过个源文件或者目录复制到指定的目的文件或目录。
ls // 用来显示目录列表,在 Linux中是使用率较高的命令。ls命令的输出信息可以进行彩色加亮显示,以区分不同类型的文件。
文件权限属性
setfacl // 用来变更文件或目录的权限。
chmod // 设置文件访问控制列表。
chgrp // 用来改变文件或目录所属的用户组。
chown // 改变某个文件或目录的所有者和所属的组,该命令可以向某个用户授权,使该用户变成指定文件的所有者。或者改变所属的组。(用户可以是用户或者是用户ID,用户组可以是组名或组ID。文件可以是由空格分开的文件列表,在文件名中可以包含通配符)【只有文件主和超级用户才可以使用该命令】
文件传输
ftp // 用来设置文件系统相关功能。
scp // 用于在Linux下远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的。可能会稍微影响一下速度。当你服务器硬盘变为只读 read only system 时,用 scp 可以帮你把文件移出来。另外,scp还非常节省资源,不会提高多少系统负荷,在这一点上,rsync就远远不及它了。虽然 rsyncscp 会快一点,但当小文件众多的情况下,rsync 会导致硬盘 I/O 非常高,而 scp 基本不影响系统正常使用。

Linux系统定时任务

crontab 命令
contab -e       // 创建定时任务
* * * * * 命令  // 分、时、日、月、周(每过多长时间去执行,根据我们所设置的分、时、日、月、周)
at 命令
# at 2:00 tomorrow  // 在明天的两点去执行
at>/home/Jason/do_job // 执行结果是这种格式的
at>Ctrl + D // 退出
#总体意思,明天两点执行 do_job,最终退出

延伸

vi/vim 编辑器
模式
  • 一般模式、编辑模式和命令行模式
切换 编辑模式:i、I、a、A、o、O、r、R
切换 命令行模式::、/、?
【:w】:保存文件
【:w!】:若文件为只读,强制保存文件
【:q】:退出 vi
【:q!】:不保存,强制退出 vi
【:wq】:保存并退出
【:wq!】:强制保存,并退出
【:set nu】:显示行号
【:set nonu】:取消显示行号
  • Esc :退出 编辑模式,回到 一般模式

  • 移动光标
【Ctrl + F】 :到下一页
【Ctrl + B】 :到上一页
【[0] 或者功能键 [Home]】:光标移动到当前行的最前面
【[$] 或者功能键 [End]】:光标移动到当前行的末尾
【G】:光标移动到文件的最后一行(第一个字符处)
【gg】:光标移动到文件的第一行,相当于 “1G”
【N + [Enter]】:光标向下移动 n 行
  • 查找和替换
/word:在文件中查找内容为 word 的字符串(向下查找)
?word:在文件中查找内容为 word 的字符串(向上查找)
:n1, n2s/word1/word2/g:n1,n2 为数字,在第 n1 行到第 n2 行之间查找 > word1,并将其替换成 word2
:1,$s/word1/word2/g:从第一行(第n行同理)到最后一行查找 word1 注册,并替换成 word2
:1,$s/word1/word2/gc:功能同上,只不过每次替换时都会让用户确认
  • 删除、复制和粘贴
【x】:向后删除一个字符,相当于**【Delete】**
【X】:向前删除一个字符,相当于**【Backspace】**
【dd】:删除光标所在的一整行
【ndd】:删除光标所在的向下 n 行
【yy】: 复制光标所在的那一行
【nyy】:复制光标所在的向下 n 行
【p】:为将已将复制的数据在光标下一行粘贴
【P】:为将已将复制的数据在光标上一行粘贴
【Ctrl + r】:多次撤销
  • 视图模式(vim)
【v】:将光标经过的地方反白选择
【V】:将光标经过的行反白选择
【Ctrl + v】:块选择,可用长方形的方式选择文本
【y】:将反白的地方复制到剪贴板
【d】:将反白的内容删除
  • 配置
【:set nu】:显示行号
【:set nonu】:取消显示行号
shell 基础
  • 脚本执行方式
1)赋予权限,直接执行,例:chmod + x test.sh; ./test.sh
2)调用解释其使得脚本执行,例:bash、csh、ash、bsh、ksh等等
3)使用source命令,例:source test.sh
  • 编写基础
1)开头用 #! 指定脚本解释器,例如:#!/bin/sh
2)编写具体功能

MySQL

关于SQL语句的注意事项:

  • 1、SQL语句中的 [ ] 中的内容为可选,可以写也可以不写。

  • 2、每个SQL语句句末的分号可以写也可以不写。

  • 3、SQL语句对大小写不敏感,大写小写都行。-- 为注释符号。

  • 4、除了汉字,所有的SQL语句必须是英文状态下输入的才行,不然会报错。

  • 5、数据库名、表名或字段名上的``符号(我叫它斜引号),这个符号不是单引号,而是tab键上面的那个键的符号,这个符号可写可不写。如果你的数据库名、表名或字段名是一个特殊字符或者关键字时,就需要带上这个符号。

数据库操作

创建数据库

CREATE DATABASE [IF NOT EXISTS] 数据库名;

删除数据库

DROP DATABASE [IF EXISTS] 数据库名;

使用数据库

USE 数据库名;

查看数据库

SHOW DATABASE;#查看所有的数据库。
SHOW CREATE DATABASE 数据库名;#查看某个已创建的数据库。

修改数据库

ALTER DATABASE 数据库名 DEFAULT CHARACTER SET 编码方式 COLLATE 编码方式_bin;

数据库列的类型

数值类型

类型名描述
tinyint十分小的数据,只占1个字节
smallint较小的数据,占2个字节
mediumint中等大小的数据,占3个字节
int标准的整数,占4个字节(常用)
bigint较大的数据,占8个字节
float浮点数,占4个字节
double浮点数,占8个字节
decimal字符串形式的浮点数,占8个字节

字符串类型

类型名描述
char固定的字符串大小,范围0~255
varchar可变字符串,范围0~65535(常用)
tinytext微型文本,范围2^8-1
text文本串,范围2^16-1

时间与日期类型

类型名描述
date日期,格式为YY-MM-DD
time时间,格式为HH:mm:ss
datetime日期与时间,格式为YY-MM-DD HH:mm:ss (常用)
timestamp时间戳,从1970年1月1日到现在的毫秒数
year年份

数据库的字段属性

字段属性

  • Unsigned: Unsigned属性,指无符号的整数,如果声明了该属性,则该字段对应的列的数据不能为负数。

  • zerofill: zerofill属性,指0填充,即不足的位数用0来填充。

  • 自增: 自动在上一条记录的基础上加1(默认),一般用来设置唯一的主键。可以自定义自增的起始值和步长。

  • 非空: 如果设置为not null,则必须填写值,否则会报错;如果设置为null,可以不填写值,则默认值为null。

  • 默认: 设置为默认的值,如果不指定该列的值,则会有默认值。

*****索引

概念:对数据库表中的一列或多列的值进行排序后的一种结构。实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。

优点:提高表中数据的查询速度。

缺点: 同时会降低更新表的速度,建立索引会占用磁盘空间的索引文件。

  • UNIQUE:唯一索引
  • FULLTEXT:全文索引
  • SPATIAL:空间索引
  • INDEX|KEY:表示字段的索引
-- 创建表时创建
CREATE TABLE [IF NOT EXISTS] 表名 (字段名 数据类型 [索引类型] INDEX [别名] (字段名)|KEY [别名] (字段名) );
-- 已存在的表上创建索引
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX 索引名 ON 表名 (字段名 [长度] [ASC|DESC]);
-- 用ALTER TABLE已存在的表上创建索引
ALTER TABLE 表名 ADD [UNIQUE|FULLTEXT|SPATIAL] INDEX 索引名 (字段名 [长度] [ASC|DESC]);
-- 删除索引
DROP INDEX 索引名 ON 表名;
-- 用ALTER TABLE删除索引
ALTER TABLE 表名 DROP INDEX 索引名;
-- 显示索引信息
SHOW INDEX FROM 表名\G

联合索引

复合索引

SQL数据库表的操作

表的创建

CREATE TABLE [IF NOT EXISTS] `表名` (
		`字段名` 列类型 [属性] [索引] [注释],
		`字段名` 列类型 [属性] [索引] [注释],
		...
		`字段名` 列类型 [属性] [索引] [注释]
)[表的类型] [字符集设置] [注释];
CREATE TABLE IF NOT EXISTS `student` (
		`id` INT(10) NOT NULL auto_increment COMMENT '学号',
		`name` VARCHAR(20) NOT NULL DEFAULT '匿名' COMMENT '姓名',
		`age` INT(3) NOT NULL COMMENT '年龄',
		PRIMARY KEY (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8

-- `id`: 字段名(列名),要用斜引号``,在tab键上方
-- INT(10): 列类型与长度
-- NOT NULL: 非空
-- auto_increment: 自增
-- COMMENT: 注释,后面是字符串,要用单引号或双引号
-- PRIMARY KEY: 设置字段`id`为主键,即学号为主键
-- 注意:每个字段之间需要用逗号隔开

表的修改与删除

-- 修改表名
ALTER TABLE 旧表名 RENAME AS 新表名
-- 增加表的字段
ALTER TABLE 表名 ADD 字段名 列类型
-- 修改表的字段约束
ALTER TABLE 表名 MODIFY 字段名 列类型 [类属性]
-- 修改表的字段名(重命名)
ALTER TABLE 表名 CHANGE 旧字段名 新字段名 [列类型] [列属性]
-- 删除表的字段
ALTER TABLE 表名 DROP 字段名
-- 删除表
DROP TABLE [IF EXISTS] 表名

DML语言数据管理

DML语言,即数据库操作语言,包括数据的插入、修改与删除操作,即insert、update、delete。

插入数据

-- 插入多条数据
INSERT INTO 表名([字段名1],[字段名2],[字段名3],...) VALUES(值1,值2,值3,...)
-- 插入单条数据
INSERT INTO 表名 VALUES(值1,值2,值3,...)

修改数据

-- 修改多条数据
UPDATE 表名 SET 字段名1=值1,字段名2=值2,... WHERE 条件语句
-- 修改单条数据
UPDATE 表名 SET 字段名=值 WHERE 条件语句

删除数据

--删除表的所有数据
DELETE FROM 表名
--删除指定的数据
DELETE FROM 表名 WHERE 条件语句

SQL语句的操作符

操作符及其含义

操作符含义
=等于
<> 或 !=不等于
>大于
<小于
>=大等于
<=小等于
BETWEEN … AND …在某个范围内
AND用于连接多个条件,相当于 &&
OR用于连接多个条件,相当于 ll

*****DQL查询数据

Select语句

-- 查询全部记录
SELECT * FROM 表名
-- 查询指定字段
SELECT 字段名1,字段名2,字段名3,... FROM 表名
-- 查询指定字段,并设置别名,别名不需要加引号
SELECT 字段名1 AS 别名1,字段名2 AS 别名2,字段名3 AS 别名3 FROM 表名
-- 去重查询,去掉重复的记录
SELECT DISTINCT 字段名 FROM 表名
SELECT DISTINCT 字段名1,字段名2,字段名3,... FROM 表名

条件查询

SELECT ... FROM 表名 WHERE 条件语句
-- AND关键字
SELECT *|字段名1,... FROM 表名 WHERE 条件表达式1 AND 条件表达式2 [...AND 条件表达式n]
-- OR关键字
SELECT *|字段名1,... FROM 表名 WHERE 条件表达式1 OR 条件表达式2 [...OR 条件表达式n]
-- IN关键字 查询学号为202101,202102,202103的学生
SELECT * FROM `student` WHERE  id IN (202101,202102,202103)
-- BETWEEN AND关键字指定范围
SELECT *|字段名1,... FROM 表名 WHERE 字段名 [NOT] BETWEEN 值1 AND 值2;
-- 查询年龄不为空的学生的姓名
SELECT `name` FROM `student` WHERE  age IS NOT NULL;

模糊查询

-- 查询姓张的学生,如张三、张小明,名字后面有任意个字
SELECT * FROM `student` WHERE `name` LIKE '张%'
-- 查询姓张的学生,如张三,名字后面只有一个字
SELECT * FROM `student` WHERE `name` LIKE '张_'
-- 查询姓张的学生,如张大爷,名字后面有两个字
SELECT * FROM `student` WHERE `name` LIKE '张__'
-- 查询名字中间有‘三’的学生,如张三丰,名字后面有两个字
SELECT * FROM `student` WHERE `name` LIKE '%三%'

高级查询

聚合函数
函数名作用
COUNT()返回某列的行数
SUM()返回某列的和
AVG()返回某列的平均值
MAX()返回某列的最大值
MIN()返回某列的最小值
SELECT COUNT(字段名) FROM 表名;
SELECT AVG(字段名) FROM 表名;
SELECT SUM(字段名) FROM 表名;
SELECT MAX(字段名) FROM 表名;
SELECT MIN(字段名) FROM 表名;
排序和分组和分页
-- 排序
SELECT 字段名1,字段名2,字段名3,... FROM 表名 ORDER BY 字段名1 [ASC|DESC] 字段名2 [ASC|DESC]...
-- 分组
SELECT 字段名1,字段名2,字段名3,... FROM 表名 GROUP BY 字段名1,字段名2,...[HAVING 条件表达式];
-- 分页
SELECT 字段名1,字段名2,字段名3,... FROM 表名 LIMIT [OFFSET,] 记录数;

*****JoinOn联表查询

-- 内连接:
-- 查询相同的记录,至少有一个匹配就会返回
SELECT 别名1.字段名1 别名2.字段名2 FROM 左表表名 别名 INNER JOIN 右表表名 别名 ON 别名1.字段名 = 别名2.字段名
-- 外连接:
-- 左查询
-- 即使右表中没有匹配,也会从左表中返回所有的值
SELECT 别名1.字段名1 别名2.字段名2 FROM 左表表名 别名 LEFT JOIN 右表表名 别名 ON 别名1.字段名 = 别名2.字段名

-- 右查询
-- 即使左表中没有匹配,也会从右表中返回所有的值
SELECT 别名1.字段名1 别名2.字段名2 FROM 左表表名 别名 RIGHT JOIN 右表表名 别名 ON 别名1.字段名 = 别名2.字段名

子查询

SELECT name,age 
FROM `student` s 
INNER JOIN `result` r 
ON s.id = r.id
INNER JOIN `subject` sub
ON r.subNo = sub.subNo
WHERE subName = 'MySQL从入门到删库跑路'

MySQL事务

  • MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你既需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!

  • 在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。

  • 事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行。

  • 事务用来管理 insert,update,delete 语句。一般来说,事务是必须满足4个条件(ACID)::原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。

原子性

一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

一致性

在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。

隔离性

数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。

持久性

事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

*****写出三种以上MySQL数据库存储引擎名称。

选择一个合适的存储引擎是一个比较复杂的问题。每种存储引擎都有自己的优缺点,不能笼统地说谁比谁好。

存储引擎的对比
特性InnoDBMyISAMMEMORY
事务安全支持
存储限制64TB
空间使用
内存使用
插入数据的速度
对外键的支持支持

InnoDB存储引擎

InnoDB概念:事务型数据库的首选引擎支持事务安全表(ACID),其它存储引擎都是非事务安全表,支持行锁定和外键,MySQL5.5以后默认使用InnoDB存储引擎。

InnoDB特点:支持事务处理,支持外键,支持崩溃修复能力和并发控制。如果需要对事务的完整性要求比较高(比如银行),要求实现并发控制**(比如售票),那选择InnoDB有很大的优势。如果需要频繁的更新、删除操作的数据库**,也可以选择InnoDB,因为支持事务的提交(commit)和回滚(rollback)。

InnoDB的聚簇索引:就是表本身,它由表的数据与B+Tree索引组成。其中内部节点中包括索引列和指向下一节点的指针,而叶子节点包括表所有列上的数据,比如主键列,MVCC列,回滚列其它列等等。所以我们在查询数据时直接就能够查找到我们想要的数据。

InnoDB的二级索引(非聚簇索引):内部结点中包含索引列与指向下个节点的指针,而叶子节点则包括索引列和主键值。这也就造成了如果我们想要通过二级索引去查询一条数据的啥时候需要两轮的查询,第一轮是通过B+Tree查找到主键值,第二轮就是拿着主键值再经过一次B+Tree的查找找到真实的值。

MyISAM存储引擎

MyISAM概念:基于ISAM存储引擎,并对其进行扩展。它是在Web、数据仓储和其他应用环境下最常使用的存储引擎之一。MyISAM拥有较高的插入、查询速度,但不支持事务,不支持外键。

MyISAM特点:插入数据快,空间和内存使用比较低。如果表主要是用于插入新记录和读出记录,那么选择MyISAM能实现处理高效率。如果应用的完整性、并发性要求比较低,也可以使用。

MyISAM的索引聚簇索引和非聚簇索引:原理相同,就是内部结点都包含有索引列和指向下一个节点的指针,在叶子节点中包含的是行号,指向实际的物理地址。

MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址

MEMORY存储引擎

MEMORY存储引擎概念:表中的数据存储到内存中,为查询和引用其他表数据提供快速访问。

MEMORY特点:**所有的数据都在内存中,数据的处理速度快,但是安全性不高。如果需要很快的读写速度,对数据的安全性要求较低,可以选择MEMOEY。**它对表的大小有要求,不能建立太大的表。所以,这类数据库只使用在相对较小的数据库表。

*****PHP连接数据库的方式

PDO【推荐使用】

  • 可扩展性更好、支持预处理、面向对象
  • 推荐使用PDO,因为扩展性非常好,将来换其他库也是没有问题的,而且它里面的方法都是比较完善的。

MySQLi

  • 只支持MySQL操作(不支持其他库)、支持预处理、面向对象和过程,效率较高(效率比PDO稍微高点)

MySQL库

  • 只支持MySQL数据库、没有预处理的支持、面向过程

编写一个在线留言本,实现用户的在线留言功能。

创建数据库,数据表:

CREATE DATABASE test;
CREATE TABLE `testmsg` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `msg` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `creatdate_at` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

留言提交页msg.php

//留言提交页
<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<!-- 新 Bootstrap4 核心 CSS 文件 -->
	<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css">
	<!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
	<script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>
	<!-- bootstrap.bundle.min.js 用于弹窗、提示、下拉菜单,包含了 popper.min.js -->
	<script src="https://cdn.staticfile.org/popper.js/1.15.0/umd/popper.min.js"></script>
	<!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
	<script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
	<title></title>
</head>
<body>
	<div class="container">
		<div class="row clearfix">
			<div class="col-md-12 column">
				<div class="card bg-light text-dark">
					<div class="card-header" style="text-align: center;">
						<h3>欢迎来到网抑留言板</h3>
					</div>
				    <div class="card-body">
						<form action="insert.php" method="post">
							<div class="form-group">
								<label for="usr">用户名:</label>
								<input type="text" class="form-control" id="usr" name="user" value="user">
							</div>
						    <div class="form-group">
						      <label for="comment">留言:</label>
						      <textarea class="form-control" rows="5" id="comment" name="comment"></textarea>
						    </div>
							<div class="form-group">
							    <div class="col-sm-offset-1 col-sm-10">
							        <button type="submit" class="btn btn-success btn-lg">提交</button>
							    </div>
							</div>
						  </form>
					</div>
					<div class="card-footer">
						<a href="http://localhost:8888/test/test.php" class="btn btn-info" role="button">查看留言</a>
					</div>
				</div>
				
			</div>
		</div>
	</div>
</body>
</html>

留言存入数据库insert.php

//留言存入数据库
<?php
	$servername = "localhost";
	$username = "root";
	$password = "wyl59420wyl999";
	$dbname = "phptest";
	//var_dump($_POST);
	$user = $_POST['user'];
	//echo $user;
	$comment = $_POST['comment'];
	$date = date("Y-m-d h:i:s");
	//echo $date;
		try {
			 $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
			 echo "连接成功<br>"; 
			 $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
			 if($comment!=""){
				 $insert = "INSERT INTO `testmsg` (`user`, `msg`, `creatdate_at`) VALUES ('{$user}', '{$comment}', '{$date}');";
				 $conn->exec($insert);
				 echo "评论成功<br>";
				 echo '<br><a href="http://localhost:8888/test/test.php" role="button">查看留言</a>';
				 //关闭连接
				 $conn = null;
			 } 
			}
			catch(PDOException $e)
			{
			 echo $e->getMessage();
			} 
?>

留言展示页test.php

//留言展示页
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<meta http-equiv="X-UA-Compatible" content="IE=edge">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<!-- 新 Bootstrap4 核心 CSS 文件 -->
		<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css">
		<!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
		<script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>
		<!-- bootstrap.bundle.min.js 用于弹窗、提示、下拉菜单,包含了 popper.min.js -->
		<script src="https://cdn.staticfile.org/popper.js/1.15.0/umd/popper.min.js"></script>
		<!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
		<script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
		<title>Document</title>
	</head>
	<body>
		<div class="container">
			<div class="row clearfix">
				<div class="col-md-12 column">
					<div class="col-md-12 column bg-secondary">
						<br />
						<div class="card bg-info text-white">
							<div class="card-header" style="text-align: center;">
								<h3>留言板</h3>
							</div> 
						</div>
						<div class="row clearfix">
							<?php 
								$servername = "localhost";
								$username = "root";
								$password = "wyl59420wyl999";
								$dbname = "phptest";
								//$user = $_POST['user'];
								try {
								    $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
								    //echo "连接成功"; 
									$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
									$stmt = $conn->prepare("SELECT `user`, `msg`, `creatdate_at` FROM `testmsg`;"); 
									$stmt->execute();
									$rows=$stmt->fetchAll(PDO::FETCH_ASSOC);
									echo '<div class="col-md-12 column"><ul class="list-group">';
									//var_dump($rows);
									foreach($rows as $row){
										echo '<li class="list-group-item list-group-item-info" style="position:relative;">';
										echo "{$row['user']}:";
										echo '<span style="position:absolute; left:150px">';
										echo "{$row['msg']}</span>";
										echo '<span style="position:absolute; right:20px">';
										echo "{$row['creatdate_at']}";
										echo "</span></li>";	   
									}
									echo "</ul></div>";
									//释放查询结果
									$stmt = null;
									//关闭连接
									$conn = null;
								}
								catch(PDOException $e)
								{
								    echo $e->getMessage();
								}
							?>
						</div>
						<br />
					</div>
				</div>
			</div>
		</div>
	</body>
</html>

image-20211115000955075

image-20211115001030525

image-20211115001108866

*****谈谈你对MVC的认识,介绍几种目前比较流行的MVC框架。

MVC分别指model,view,controler。

Model - 数据模型层:通常情况下对数据进行加工,进行一些其他的处理,与数据相关的一些操作都在 Model层 操作。
View - 视图层:跟用户进行交互的一些界面上的东西。
Controller - 控制层:用来处理业务逻辑的。

核心思想是:视图和用户交互,通过事件导致控制器改变,控制器改变导致模型改变或者控制器同时改变两者,模型改变导致视图改变或者视图改变潜在的从模型里面获得参数来改变自己。

它的优势在于:开发人员可以只关注整个结构中的其中某一层,可以很容易的用新的实现来替换原有层次的实现,可以降低层与层之间的依赖,有利于标准化,利于各层逻辑的复用。

php流行的MVC框架

yii,codelgniter,cakephp

*****写出常见的排序算法。

排序算法下载

(9条消息) 十大排序算法_不知名Coder - javatv.net-CSDN博客

img

冒泡排序

选择排序

插入排序

希尔排序

归并排序

快速排序

堆排序

计数排序

桶排序

基数排序

*****php如何解决网站大流量与高并发的问题。

参考博客

1)流量优化

防盗链处理

把一些恶意的请求拒之问外。如:现在有A,B两个站,A站 想用 B站 的资源,直接在页面嵌入了一些图片,JS,CSS,本身来说,A站并不关心B站会消耗多少流量,但是对于B站来说,如果我们调用了B站的一些图片,JS或者CSS,都会对它做一个HTTP请求,就会消耗流量和带宽,所以本身对B站来说,会有不好的影响。从另一个角度来说,也侵犯了B站的版权问题,因此在这儿,要做 防盗链处理,这是流量的优化。

2)前端优化

① 减少HTTP请求

假设打开一个界面,可以把一些CSS,JS文件,图片进行合并,这样做虽然会使文件变大,但是减少了请求的次数。

② 添加异步请求

如:不是一些很重要的数据,用户首次请求界面的时候,先不进行展示,需要的时候再进行展示,我们可以在旁边放一些事件,通过一些JS、jQuery等第三方库做一些AJAX的相关的异步请求,这样对于HTTP请求在性能上回有一个大幅度的提升,不要一次性把数据都加载过来,这样会对服务器造成很大的压力。

③ 启用浏览器缓存和文件压缩

如:启用浏览器 去缓存HTML文件给其设定过期时间,设定缓存文件相关的指纹等等。还可以将静态资源文件(如:JS、image等一些前端资源)设置过期时间缓存,为其指定过期时间,把它缓存到浏览器中,这样下一次再去访问的时候,不需要去请求服务端,可以直接通过浏览器把缓存读取出来。对于 文件压缩,可以通过一些压缩方式,如:把图片压缩的小一些,展示的时候图片就会下载的更快些,响应速度会加深,并且减少了流量的消耗,减少了带宽的消耗。同时也可以启用 Nginx 的 GCPR服务,将文件整体来说压的小一些。

④ CDN 加速

可以把一些前端的文件,前端的资源全部都放到CDN当中,用户过来访问的时候,可以就近来进行访问,从而提高访问速度,并且从一定意义上来说,也解决了带宽不够用的问题,可以把数据缓存到CDN的节点中,在用户去访问的时候,都会就近的选择CDN的节点进行访问,从一定意义上来说,就不会访问我们真实的服务器。

⑤ 建立独立图片服务器

因为本身来说,图片服务器是比较吃I/O的,为了解决对 I/O的损耗,可以把它与我们的 Web 服务器完全分离开,这样 Web 服务器本身的I/O 不会被我们的图片损耗,然后还可以针对性的对我们的图片服务器做一些优化,如:提高硬盘的转速;把CPU的计算能力降低下来;把图片服务器做一个集群。

3)服务端优化

① 页面静态化

把现有的服务端的逻辑(如:PHP),把PHP的一些逻辑,PHP的一些数据,PHP最终生成的要显示给用户的一些HTML内容缓存起来,直接缓存成HTML代码速度会更快,并且对我们的CPU负载,对我们的服务器的压力都会减小很多。

② 并发处理

如:页面做了一些静态化,但是静态化会有一个过期时间,不可能永远显示页面,如果是这样创建一些动态的内容就没有意义了,但是对于实质性要求比较高的来说,我们可能在做一些静态化的时候,不是特别的合理。这时需要穿透静态化,即绕过静态化,来直接访问真实的数据。访问真实数据的时候,可能就需要做一些程序上的并发处理,如 多线程多进程的异步处理、队列处理 等等,都可以异步完成数据的处理,从而提升请求的响应的速度,同时也提升了并发数。

③ 队列处理

4)数据库优化

① 数据库缓存

    memcache 缓存
    redis 缓存等

② 分库分表、分区操作

    垂直拆分、水平拆分;
    分区

③ 读写分离

    把一些服务器,一些数据完全分开;
    一些服务器做数据库的读操作(查询),一些服务器做写操作(增、删、该)

④ 负载均衡

5)Web 服务器优化

负载均衡

    可以使用 Nginx 的反向代理来实现负载均衡;
    使用七层,使用四层(LVS)软件来实现负载均衡。

3001.4450)

1)流量优化

防盗链处理

把一些恶意的请求拒之问外。如:现在有A,B两个站,A站 想用 B站 的资源,直接在页面嵌入了一些图片,JS,CSS,本身来说,A站并不关心B站会消耗多少流量,但是对于B站来说,如果我们调用了B站的一些图片,JS或者CSS,都会对它做一个HTTP请求,就会消耗流量和带宽,所以本身对B站来说,会有不好的影响。从另一个角度来说,也侵犯了B站的版权问题,因此在这儿,要做 防盗链处理,这是流量的优化。

2)前端优化

① 减少HTTP请求

假设打开一个界面,可以把一些CSS,JS文件,图片进行合并,这样做虽然会使文件变大,但是减少了请求的次数。

② 添加异步请求

如:不是一些很重要的数据,用户首次请求界面的时候,先不进行展示,需要的时候再进行展示,我们可以在旁边放一些事件,通过一些JS、jQuery等第三方库做一些AJAX的相关的异步请求,这样对于HTTP请求在性能上回有一个大幅度的提升,不要一次性把数据都加载过来,这样会对服务器造成很大的压力。

③ 启用浏览器缓存和文件压缩

如:启用浏览器 去缓存HTML文件给其设定过期时间,设定缓存文件相关的指纹等等。还可以将静态资源文件(如:JS、image等一些前端资源)设置过期时间缓存,为其指定过期时间,把它缓存到浏览器中,这样下一次再去访问的时候,不需要去请求服务端,可以直接通过浏览器把缓存读取出来。对于 文件压缩,可以通过一些压缩方式,如:把图片压缩的小一些,展示的时候图片就会下载的更快些,响应速度会加深,并且减少了流量的消耗,减少了带宽的消耗。同时也可以启用 Nginx 的 GCPR服务,将文件整体来说压的小一些。

④ CDN 加速

可以把一些前端的文件,前端的资源全部都放到CDN当中,用户过来访问的时候,可以就近来进行访问,从而提高访问速度,并且从一定意义上来说,也解决了带宽不够用的问题,可以把数据缓存到CDN的节点中,在用户去访问的时候,都会就近的选择CDN的节点进行访问,从一定意义上来说,就不会访问我们真实的服务器。

⑤ 建立独立图片服务器

因为本身来说,图片服务器是比较吃I/O的,为了解决对 I/O的损耗,可以把它与我们的 Web 服务器完全分离开,这样 Web 服务器本身的I/O 不会被我们的图片损耗,然后还可以针对性的对我们的图片服务器做一些优化,如:提高硬盘的转速;把CPU的计算能力降低下来;把图片服务器做一个集群。

3)服务端优化

① 页面静态化

把现有的服务端的逻辑(如:PHP),把PHP的一些逻辑,PHP的一些数据,PHP最终生成的要显示给用户的一些HTML内容缓存起来,直接缓存成HTML代码速度会更快,并且对我们的CPU负载,对我们的服务器的压力都会减小很多。

② 并发处理

如:页面做了一些静态化,但是静态化会有一个过期时间,不可能永远显示页面,如果是这样创建一些动态的内容就没有意义了,但是对于实质性要求比较高的来说,我们可能在做一些静态化的时候,不是特别的合理。这时需要穿透静态化,即绕过静态化,来直接访问真实的数据。访问真实数据的时候,可能就需要做一些程序上的并发处理,如 多线程多进程的异步处理、队列处理 等等,都可以异步完成数据的处理,从而提升请求的响应的速度,同时也提升了并发数。

③ 队列处理

4)数据库优化

① 数据库缓存

    memcache 缓存
    redis 缓存等

② 分库分表、分区操作

    垂直拆分、水平拆分;
    分区

③ 读写分离

    把一些服务器,一些数据完全分开;
    一些服务器做数据库的读操作(查询),一些服务器做写操作(增、删、该)

④ 负载均衡

5)Web 服务器优化

负载均衡

    可以使用 Nginx 的反向代理来实现负载均衡;
    使用七层,使用四层(LVS)软件来实现负载均衡。

相关文章

自己写的Ansbile自动化部署脚本

自己写的Ansbile自动化部署脚本

环境介绍: 2台虚拟机(master 2G 2核, node 1G 1核)...

Java后端常问面试题

适用于刚毕业的应届生,很多都是我面试时面试官问的问题。这些只是基础也就是说...

JavaAPI_01

Java API 1.跟新华字典一样的,封装了Java中所有系统的类以及...

Java基础的暂时收尾以及Web的开始

     本周随着第二次考核的收尾,java基础暂时告一段落。第二次考核中...

Linux之用户身份切换与特殊的Shell

Linux之用户身份切换与特殊的Shell

温故:         在上面一篇文章《Linux之ACL权限设置》中给...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。