Nginx ---- 高性能得WEB服务端(三)

一、重写功能   rewrite

Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求,此功能依靠 PCRE(perl compatible regular expression),因此编译之前要安装PCRE库,rewrite是nginx服务器的重要功能之一,重写功能(rewrite)用于实现URL的重写,URL的重写是非常有用的功能,比如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的链接,就可以设置为访问,另外还可以在一定程度上提高网站的安全性。更换域名后需要保持旧的域名能跳转到新的域名上、某网页发生改变需要跳转到新的页面、网站防盗链等等需求

1、ngx_http_rewrite_module模块指令

1.if指令

if (条件匹配) {   action
}

使用正则表达式对变量进行匹配,匹配成功时if指令认为条件为true,否则认为false,变量与表达式之间使用以下符号链接:

​
=  #比较变量和字符串是否相等,相等时if指令认为该条件为true,反之为false
!=  #比较变量和字符串是否不相等,不相等时if指令认为条件为true,反之为false
~  #区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~ #区分大小写字符,判断是否匹配,不满足匹配条件为真,满足匹配条件为假~* #不区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~* #不区分大小字符,判断是否匹配,满足匹配条件为假,不满足匹配条件为真-f 和 !-f #判断请求的文件是否存在和是否不存在
-d 和 !-d #判断请求的目录是否存在和是否不存在
-x 和 !-x #判断文件是否可执行和是否不可执行
-e 和 !-e #判断请求的文件或目录是否存在和是否不存在(包括文件,目录,软链接)
举例:
location /main {index index.html;default_type text/html;
#定义文件类型if ( $scheme = http ){
#如果用户访问的协议是http,$scheme变量表示用户来访问使用的协议。       echo "if-----> $scheme";
#则输出if --->协议 }if ( $scheme = https ){
#如果用户访问的协议是https,$scheme变量表示用户来访问使用的协议。 echo "if ----> $scheme";
#则输出if --->协议 }

2.return指令

return用于完成对请求的处理,并直接向客户端返回响应状态码,比如:可以指定重定向URL(对于特殊重定向状态码,301/302等) 或者是指定提示文本内容(对于特殊状态码403/500等),处于此指令后的所有配置都将不被执行,return可以在server、if 和 location块进行配置

www.kgc.com/test/
404
return code; #返回给客户端指定的HTTP状态码
return code [text]; #返回给客户端的状态码及响应报文的实体内容,可以调用变量,其中text如果有空格,需要用单或双引号
return code url; #返回给客户端的URL地址 
3字打头重定向
301  永久重定向  将缓存记录在浏览器中
302  临时重定向  没有缓存  每次都要重定向 

3.set指令

指定key并给其定义一个变量,变量可以调用Nginx内置变量赋值给key,另外set定义格式为set $key value,value可以是text, variables和两者的组合。

server{listen 80;root /data/;server_name www.kgc.com;location /test {set $name kgc;echo $name;set $my_port $server_port;echo $my_port;}
}

4.break指令

用于中断当前相同作用域(location)中的其他Nginx配置,与该指令处于同一作用域的Nginx配置中,位于它前面的配置生效,位于后面的 ngx_http_rewrite_module 模块中指令就不再执行,Nginx服务器在根据配置处理请求的过程中遇到该指令的时候,回到上一层作用域继续向下读取配置,该指令可以在server块和location if块中使用

注意: 如果break指令在location块中后续指令还会继续执行,只是不执行 ngx_http_rewrite_module 模块的指令,其它指令还会执行

访问bj就跳转到beijing 

#############7-1 子配置###################[root@localhost ~]#vim /apps/nginx/conf.d/pc.conf 
server{listen 80;root /data;server_name www.kgc.com;location /bj {rewrite ^/bj/(.*) /beijing/$1 permanent;}
}[root@localhost ~]#nginx -t[root@localhost ~]#nginx -s reload[root@localhost ~]#cd /data/[root@localhost data]#mkdir /data/beijing[root@localhost data]#echo beijinghuanyingni > /data/beijing/index.html############7-2 访问#####################[root@localhost ~]#curl 192.168.10.101/bj/ -L
beijinghuanyingni[root@localhost ~]#curl 192.168.10.101/beijing -L
beijinghuanyingni

 

验证 

2、rewrite  指令

通过正则表达式的匹配来改变URI,可以同时存在一个或多个指令,按照顺序依次对URI进行匹配,rewrite主要是针对用户请求的URL或者是URI做具体处理

官方文档:https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite

1.rewrite跳转实现

Nginx:通过ngx_http_rewrite_module 模块支持URL重写、支持if条件判断,但不支持else
跳转:从一个 location跳转到另一个location,循环最多可以执行10次,超过后nginx将返回500错误
PCRE支持:perl兼容正则表达式的语法规则匹配
重写模块 set 指令:创建新的变量并设其值

2.rewrite 执行顺序

  1. 执行 server 块里面的 rewrite 指令。
  2. 执行 location 匹配。
  3. 执行选定的 location 中的 rewrite 指令

3.rewrite  语法格式

rewrite flag 使用介绍

利用nginx的rewrite的指令,可以实现url的重新跳转,rewrtie有四种不同的flag,分别是redirect(临时重定向302)、permanent(永久重定向301)、break和last。其中前两种是跳转型的flag,后两种是代理型。

  • 跳转型指由客户端浏览器重新对新地址进行请求
  • 代理型是在WEB服务器内部实现跳转

flag 说明

  • redirect;302
    • #临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URL给客户端,由客户端重新发起请求;使用相对路径,或者http://或https://开头,状态码:302
  • permanent;301       www.bj.com     www.beijing.com
    • #重写完成后以永久重定向方式直接返回重写后生成的新URL给客户端,由客户端重新发起请求,状态码:301
  • break;       www.bj.com
    • #重写完成后,停止对当前URL在当前location中后续的其它重写操作,而后直接跳转至重写规则配置块之后的其它配置;结束循环,建议在location中使用 ,适用于一个URL一次重写 
  • last;
    • #重写完成后,停止对当前URI在当前location中后续的其它重写操作,而后对新的URL启动新一轮重写检查,不建议在location中使用,会造成死循环,少用
      适用于一个URL多次重写,要注意避免出现超过十次以及URL重写后返回错误的给用户301

正则表达式格式(regex)

. #匹配除换行符以外的任意字符
\w #匹配字母或数字或下划线或汉字
\s #匹配任意的空白符
\d #匹配数字    [0-9]   
\b #匹配单词的开始或结束
^ #匹配字符串的开始
$ #匹配字符串的结束
* #匹配重复零次或更多次
+ #匹配重复一次或更多次
? #匹配重复零次或一次
{n} #匹配重复n次
{n,} #匹配重复n次或更多次
{n,m} #匹配重复n到m次
*? #匹配重复任意次,但尽可能少重复
+? #匹配重复1次或更多次,但尽可能少重复
?? #匹配重复0次或1次,但尽可能少重复
{n,m}? #匹配重复n到m次,但尽可能少重复
{n,}? #匹配重复n次以上,但尽可能少重复
\W  #匹配任意不是字母,数字,下划线,汉字的字符
\S #匹配任意不是空白符的字符
\D #匹配任意非数字的字符
\B #匹配不是单词开头或结束的位置
[^x] #匹配除了x以外的任意字符
[^kgc] #匹配除了kgc 这几个字母以外的任意字符

1、访问bj就跳转到beijing

#############7-1 子配置###################[root@localhost ~]#vim /apps/nginx/conf.d/pc.conf 
server{listen 80;root /data;server_name www.kgc.com;location /bj {rewrite ^/bj/(.*) /beijing/$1 permanent;}
}[root@localhost ~]#nginx -t[root@localhost ~]#nginx -s reload[root@localhost ~]#cd /data/[root@localhost data]#mkdir /data/beijing[root@localhost data]#echo beijinghuanyingni > /data/beijing/index.html############7-2 访问#####################[root@localhost ~]#curl 192.168.10.101/bj/ -L
beijinghuanyingni[root@localhost ~]#curl 192.168.10.101/beijing -L
beijinghuanyingni

2、访问http就等于访问https

浏览器访问

3、last 和 break区别 

  • break适用于一个URL一次重写 

  • last会造成死循环,少用,适用于一个URL多次重写

[root@localhost ~]#vim  /apps/nginx/conf.d/pc.conf 
server{listen 80;root /data;server_name www.kgc.com;listen 443 ssl;ssl_certificate /data/ssl/www.kgc.com.crt;ssl_certificate_key /data/ssl/www.kgc.com.key;ssl_session_cache shared:sslcache:20m;ssl_session_timeout 10m;location /bj {rewrite ^/bj/(.*) /beijing/$1 permanent;}location / {if ( $scheme = http ) {rewrite /(.*) https://$host/$1 permanent;}}location /break {rewrite .* /test break;}location /last {rewrite .* /test last;}location /test {return 403;}
}[root@localhost ~]#nginx -t[root@localhost ~]#nginx -s reload

浏览器检测

3、防盗链

防盗链基于客户端携带的referer实现,referer是记录打开一个页面之前记录是从哪个页面跳转过来的标记信息,如果别人只链接了自己网站图片或某个单独的资源,而不是打开了网站的整个页面,这就是盗链,referer就是之前的那个网站域名,正常的referer信息有以下几种:

none:#请求报文首部没有referer首部,比如用户直接在浏览器输入域名访问web网站,就没有referer信息。
blocked:#请求报文有referer首部,但无有效值,比如为空。
server_names:#referer首部中包含本主机名及即nginx 监听的server_name。
arbitrary_string:#自定义指定字符串,但可使用*作通配符。示例: *.kgc.org www.kgc.*
regular expression:#被指定的正则表达式模式匹配到的字符串,要使用~开头,例如:~.*\.kgc\.com

nginx安全之防盗链设置,避免资源盗用以及节省带宽

配置文件

去另一台访问

如果在电脑真机上做防盗链:

关于电脑真机中如何设置ip与域名的映射关系 

文件修改的时候进入属性——安全——编辑(指定当前用户)有写入的权限,及时修改 及时撤回!!!

改完真机域名后将原配置该回去,防止在原配置中出现乱码

然后去浏览器访问7-1  192.168.10.101/a.jpg

 然后去浏览器输入 7-2  192.168.10.102

可以查看到从101盗过来的图片

去10.101上面配置防盗链

[root@localhost ~]#vim /apps/nginx/conf.d/pc.conf 
server{listen 80;root /data;server_name www.kgc.com;listen 443 ssl;ssl_certificate /data/ssl/www.kgc.com.crt;ssl_certificate_key /data/ssl/www.kgc.com.key;ssl_session_cache shared:sslcache:20m;ssl_session_timeout 10m;location ~* \.(jpg|gif|swf|jpeg|bmp)$ {valid_referers none blocked *.lucky.com lucky.com;if ( $invalid_referer ) {return 403;}}
}[root@localhost ~]#nginx -t[root@localhost ~]#nginx -s reload

或是加个图片看看访问出错误图片

4、其它相关高级功能

二、反向代理

反向代理:reverse proxy,指的是代理外网用户的请求到内部的指定的服务器,并将数据返回给用户的一种方式,这是用的比较多的一种方式。

Nginx 除了可以在企业提供高性能的web服务之外,另外还可以将 nginx 本身不具备的请求通过某种预定义的协议转发至其它服务器处理,不同的协议就是Nginx服务器与其他服务器进行通信的一种规范,主要在不同的场景使用以下模块实现不同的功能:

ngx_http_proxy_module: #将客户端的请求以http协议转发至指定服务器进行处理
ngx_http_upstream_module #用于定义为proxy_pass,fastcgi_pass,uwsgi_pass等指令引用的后端服务器分组
ngx_stream_proxy_module:#将客户端的请求以tcp协议转发至指定服务器处理
ngx_http_fastcgi_module:#将客户端对php的请求以fastcgi协议转发至指定服务器助理
ngx_http_uwsgi_module: #将客户端对Python的请求以uwsgi协议转发至指定服务器处理

正向代理:代理的是客户端 去访问 服务器
反向代理: 代理的是服务端

1、实现反向代理

官方文档: https://nginx.org/en/docs/http/ngx_http_proxy_module.html

同构代理、异构代理

1.http协议反向代理

2.反向代理皮质参数

#官方文档:https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass 
proxy_pass; 
#用来设置将客户端请求转发给的后端服务器的主机,可以是主机名(将转发至后端服务做为主机头首部)、IP
地址:端口的方式
#也可以代理到预先设置的主机群组,需要模块ngx_http_upstream_module支持#示例:
10.0.0.8/weblocation /web {index index.html;proxy_pass http://10.0.0.18:8080; #8080后面无uri,即无 / 符号,需要将location后面url 附加到proxy_pass指定的url后面,此行为类似于root
#proxy_pass指定的uri不带斜线将访问的/web,等于访问后端服务器
http://10.0.0.18:8080/web/index.html,即后端服务器配置的站点根目录要有web目录才可以被访问# http://nginx/web/index.html ==> http://10.0.0.18:8080/web/index.htmlproxy_pass http://10.0.0.18:8080/;   #8080后面有uri,即有 / 符号,相当于置换,即访问/web时实际返回proxy_pass后面uri内容.此行为类似于alias #proxy_pass指定的uri带斜线,等于访问后端服务器的http://10.0.0.18:8080/index.html 内容返回给客户端}  # http://nginx/web/index.html ==> http://10.0.0.18:8080#重启Nginx测试访问效果:
#curl -L http://www.kgc.org/web#如果location定义其uri时使用了正则表达式模式(包括~,~*,但不包括^~),则proxy_pass之后必须不能使用uri; 即不能有/ ,用户请求时传递的uri将直接附加至后端服务器之后
server {...server_name HOSTNAME;location ~|~* /uri/ {proxy_pass http://host:port; #proxy_pass后面的url 不能加/}...}http://HOSTNAME/uri/ --> http://host/uri/proxy_hide_header field;
#用于nginx作为反向代理的时候,在返回给客户端http响应时,隐藏后端服务器相应头部的信息,可以设置
在http,server或location块
#示例: 隐藏后端服务器ETag首部字段location /web {index index.html;proxy_pass http://10.0.0.18:8080/; proxy_hide_header ETag;}proxy_pass_header field;
#默认nginx在响应报文中不传递后端服务器的首部字段Date, Server, X-Pad, X-Accel等参数,如果
要传递的话则要使用 proxy_pass_header field声明将后端服务器返回的值传递给客户端
#field 首部字段大小不敏感
#示例:透传后端服务器的Server和Date首部给客户端,同时不再响应报中显示前端服务器的Server字段
proxy_pass_header Server;
proxy_pass_header Date;proxy_pass_request_body on | off; 
#是否向后端服务器发送HTTP实体部分,可以设置在http,server或location块,默认即为开启proxy_pass_request_headers on | off; 
#是否将客户端的请求头部转发给后端服务器,可以设置在http,server或location块,默认即为开启

3.反向代理单台web服务器

1、访问本机(192.168.10.101)的根就等于去访问192.168.10.102    把7-1做代理服务器
[root@localhost data]#vim /apps/nginx/conf.d//pc.conf 
[root@localhost data]#cat /apps/nginx/conf.d/pc.conf 
server{listen 80;root /data;server_name www.kgc.com;listen 443 ssl;ssl_certificate /data/ssl/www.kgc.com.crt;ssl_certificate_key /data/ssl/www.kgc.com.key;ssl_session_cache shared:sslcache:20m;ssl_session_timeout 10m;location / {proxy_pass http://192.168.10.102;	}
}
[root@localhost data]#nginx -t[root@localhost data]#nginx -s reload

客户端配置httpd服务

也可以去浏览器访问一下192.168.10.101

2、可以把端口也加入

去客户端7-2修改端口号

去7-1修改配置文件,  添加端口号 

浏览器检测

proxy_pass; 
#用来设置将客户端请求转发给的后端服务器的主机,可以是主机名(将转发至后端服务做为主机头首部)、IP
地址:端口的方式
#也可以代理到预先设置的主机群组,需要模块ngx_http_upstream_module支持

3、在真实服务器上 做防火墙规则     iptables -A INPUT  -s 192.168.91.100 -j DROP
在真实服务器上 做防火墙规则
iptables -A INPUT  -s 192.168.10.101 -j DROP
客户端再次访问  会出现504网关超时(有可能只是处理时间久,服务器不一定挂了),时间较长1分钟,没有定义代理超时时间iptables -A INPUT  -s 192.168.10.101 -j REJECT
客户端再次访问  会出现502,一般出现502 代表后端真实服务器挂了
[root@zzzcentos2 html]#iptables -A INPUT -s 192.168.246.7 -j DROP
[root@zzzcentos2 html]#iptables -vnL

去浏览器访问

4、iptables -R INPUT 1  -s 192.168.246.7 -j REJECT

在7-2真实服务器上做防火墙规则

去浏览器访问

状态码:502网关不可达,真实服务器坏了

              504网关超时,代理服务器与真实服务器之间有问题

5、配置文件加 /  与不加 / 实验

7-1服务器配置

7-2真实服务器进行配置

加 /    表示替换

7-1进行配置

7-2检测

总结:

加        /  表示替换

不加    /  表示追加

 /api 匹配可能选择型太多,不允许替换,只能追加,一般不加/

4.指定location实现反向原理、动静分离

7-1代理服务器配置

7-2服务器配置

7-3服务器配置

检测:

7-1进行检测

浏览器检测

源代码与服务器代码一样,静态资源

源代码与服务器代码不一样,动态资源

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2813561.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

基于springboot+vue的学科平台系统(前后端分离)

博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战,欢迎高校老师\讲师\同行交流合作 ​主要内容:毕业设计(Javaweb项目|小程序|Pyt…

Redis高可用三主三从集群部署(三种方式部署/18个节点的大集群)

文章目录 🔊博主介绍🥤本文内容使用宝塔面板搭建集群规划配置验证 使用docker搭建使用脚本搭建规划防火墙端口配置脚本redis.conf配置文件执行过程 📢文章总结📥博主目标 🔊博主介绍 🌟我是廖志伟&#xff…

【递归】【回溯】Leetcode 112. 路径总和 113. 路径总和 II

【递归】【回溯】Leetcode 112. 路径总和 113. 路径总和 II 112. 路径总和解法:递归 有递归就有回溯 记得return正确的返回上去 113. 路径总和 II解法 递归 如果需要搜索整棵二叉树,那么递归函数就不要返回值 如果要搜索其中一条符合条件的路径&#xff…

AI入门笔记(二)

紧接着上一篇幅,点火条件的图形表示如下。 利用单位阶跃函数可表示点火的式子:yu(w1x1w2x2w3x3-θ) 因为u表示的是单位阶跃函数,那么一般化点火的式子可以表示为:ya(w1x1w2x2w3x3-θ),此处的a表示激活函数&#xff0…

笔记:GO1.19 带来的优化(重新编译juicefs)

## 背景 go编写的应用程序(juicefs)在k8s(docker)中运行,时不时出现 OOM Killed。 ## 分析 发现某些应用使用juicefs会导致内存使用飙升; k8s的pod给的内存资源:request 2G,limit…

ui设计:利用即使设计设计出漂亮样式

目录 一、基本操作 二、具体介绍 6-1 填充图片 6-2 填充色 6-3 图标 右边栏基础设置 右边栏导出​编辑 一、基本操作 二、具体介绍 6-1 填充图片 选择其一图片填充 6-2 填充色 6-3 图标 右边栏基础设置 右边栏导出

面试redis篇-12Redis集群方案-分片集群

原理 主从和哨兵可以解决高可用、高并发读的问题。但是依然有两个问题没有解决: 海量数据存储问题高并发写的问题 使用分片集群可以解决上述问题,分片集群特征: 集群中有多个master,每个master保存不同数据每个master都可以有…

腾讯云4核8g的服务器能承受多少并发?

腾讯云4核8G服务器支持多少人在线访问?支持25人同时访问。实际上程序效率不同支持人数在线人数不同,公网带宽也是影响4核8G服务器并发数的一大因素,假设公网带宽太小,流量直接卡在入口,4核8G配置的CPU内存也会造成计算…

ADS-B Ground Receiver Radarcape

目录 Radarcape ADS-B MLAT Receiver Web Browser User Interface Radarcape Technical Data Radarcape Software Features Radarcape Basics Radarcape ADS-B MLAT Receiver Radarcape is a professional ADS-B receiver made for 24/7 operation. High performance rec…

AI赚钱套路总结和教程

最近李一舟和Sora 很火,作为第一批使用Sora赚钱的男人,一个清华学美术的跟人讲AI,信的人太多了,钱太好赚了。3年时间,李一舟仅通过卖课就赚了1.75亿元,其中《每个人的人工智能课》收入2786万元,…

【Flink】Flink 中的时间和窗口之窗口(Window)

1. 窗口的概念 Flink是一种流式计算引擎,主要是来处理无界数据流,数据流的数据是一直都有的,等待流结束输入数据获取所有的流数据在做聚合计算是不可能的。为了更方便高效的处理无界流,一种方式就是把无限的流数据切割成有限的数…

XINDOO的2023年总结

这篇文章是我的第十年年终总结,本来想很正式的写,由于元旦偷懒,春节又特种式狂奔四个城市给自己和妹妹订婚,横跨几千公里,几乎一半的假期都在路上。我23年的年终总结难产至今,最后赶在2月结束前开始动笔。 …

vscode与vue/react环境配置

一、下载并安装VScode 安装VScode 官网下载 二、配置node.js环境 安装node.js 官网下载 会自动配置环境变量和安装npm包(npm的作用就是对Node.js依赖的包进行管理),此时可以执行 node -v 和 npm -v 分别查看node和npm的版本号: 配置系统变量 因为在执…

Nginx -3

接着上文写 七. 重写功能 Nginx 服务器利用 ngx_http_rewrite_module 模块解析和处理 rewrite 请求,此功能依靠 PCRE (perl compatible regular expression),因此编译之前要安装PCRE库,rewrite 是 nginx 服务器的重要功能之一,用…

Flask基础学习4

19-【实战】问答平台项目结构搭建_剪_哔哩哔哩_bilibili 参考如上大佬的视频教程&#xff0c;本博客仅当学习笔记&#xff0c;侵权请联系删除 问答发布的web前端页面实现 register.html {% extends base.html %}{% block head %}<link rel"stylesheet" href&q…

LeetCode--代码详解 230. 二叉搜索树中第K小的元素

230. 二叉搜索树中第K小的元素 题目 给定一个二叉搜索树的根节点 root &#xff0c;和一个整数 k &#xff0c;请你设计一个算法查找其中第 k 个最小元素&#xff08;从 1 开始计数&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,1,4,null,2], k 1 输出&#…

MFC web文件 CHttpFile的使用初探

MFC CHttpFile的使用 两种方式&#xff0c;第一种OpenURL&#xff0c;第二种SendRequest&#xff0c;以前捣鼓过&#xff0c;今天再次整结果发现各种踩坑&#xff0c;好记性不如烂笔头&#xff0c;记录下来。 OpenURL 这种方式简单粗暴&#xff0c;用着舒服。 try {//OpenU…

[C++][linux]Linux上内存共享内存用法

一&#xff0c;什么是共享内存 共享内存&#xff08;Shared Memory&#xff09;&#xff0c;指两个或多个进程共享一个给定的存储区。进程可以将同一段共享内存连接到它们自己的地址空间中&#xff0c;所有进程都可以访问共享内存中的地址&#xff0c;就好像它们是由用C语言函…

QT项目打包

十、项目打包 设置图标 以下是个项目设置图标的 操作步骤 设计或下载一个图标图片&#xff08;推荐分辨率6464及其以上&#xff0c;256256及其以下&#xff09;。转换为.ico格式&#xff0c;转换可以使用下面的网站。 Convertio — 文件转换器 PNG转ICO, 在线转换器 - 转换视频…

四年的外包生涯,让我的技术明显退步

在湖南的一个安静角落&#xff0c;我&#xff0c;一个普通的大专生&#xff0c;开始了我的软件测试之旅。四年的外包生涯&#xff0c;让我在舒适区里逐渐失去了锐气&#xff0c;技术停滞不前&#xff0c;仿佛被时间遗忘。然而&#xff0c;生活的转机总是在不经意间降临。 与女…