【算法】深度优先搜索DFS 入门:基本知识+经典例题

2023-11-18

DFS最重要的是理清搜索顺序!
ps:这是我入门dfs时写的博客,后来dfs渐渐熟练了,也补充了一些题目上去(带原题和代码)。个人感觉整篇博文从上到下确实由易到难,代码也由开始的冗长变得渐渐精简。

自学DFS看的视频:
小甲鱼:讲原理
青岛大学-王卓:讲的较为全面的基本知识p122-124
自学之后的题目总结:【DFS】题目总结

推荐AcWing y总的讲解!

基本知识

深度优先搜索(DFS, Depth First Search)是一个针对图和树的遍历算法。早在19世纪就被用于解决迷宫问题。

它的思想是从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解,那就返回到上一个节点,然后从另一条路开始走到底,这种尽量往深处走的概念即是深度优先的概念。(参考“可参考资料2”)

对图的理解可见:
图的详解

大概步骤:

深度优先搜索用一个数组存放产生的所有状态。
(1) 把初始状态放入数组中,设为当前状态;
(2) 扩展当前的状态,产生一个新的状态放入数组中,同时把新产生的状态设为当前状态;
(3) 判断当前状态是否和前面的重复,如果重复则回到上一个状态,产生它的另一状态;
(4) 判断当前状态是否为目标状态,如果是目标,则找到一个解答,结束算法。
(5) 如果数组为空,说明无解。
对于pascal语言来讲,它支持递归,在递归时可以自动实现回溯(利用局部变量)所以使用递归编写深度优先搜索程序相对简单,当然也有非递归实现的算法。(摘自百度百科)

经典例题

1、水池问题

很基础的水池问题

题目描述
输入
第一行输入一个整数N,表示共有N组测试数据
每一组数据都是先输入该地图的行数m(0<m<100)与列数n(0<n<100),
然后,输入接下来的m行每行输入n个数,表示此处有水还是没水(1表示此处是水池,0表示此处是地面)

输出
输出该地图中水池的个数。

每个水池的旁边(上下左右四个位置)如果还是水池的话的话,它们可以看做是同一个水池。
样例输入
2
3 4
1 0 0 0
0 0 1 1
1 1 1 0
5 5
1 1 1 1 0
0 0 1 0 1
0 0 0 0 0
1 1 1 0 0
0 0 1 1 1
样例输出
2
3

一个总结:
这是一道基础dfs题,适合我这样的初学者;
大致思路是:
定义一个void dfs()函数,功能是如果二维数组某点为1,则判断其上下左右是否为为1,若为1,使之为0,并递归调用dfs对其周围进行搜索判断;
其中,若传入一个已知为1的点,对它周围搜索,肯定会搜索会本点并使之为0,则无需单独对该点单独操作;
且,if中的数组的参数与调用时传入的参数相同,如此方便记忆。

void函数如:

void dfs(int a,int b)                                   //深度优先搜索函数,一旦调用,一个点周围连续的地方都记为0; 
{
	if(arr[a-1][b]==1){arr[a-1][b]==0;dfs(a-1,b);        //上 
	}
	
	if(arr[a+1][b]==1){arr[a+1][b]==0;dfs(a+1,b);        //下 
	}
	
	if(arr[a][b-1]==1){arr[a][b-1]==0;dfs(a,b-1);        //左 
	}
	
	if(arr[a][b+1]==1){arr[a][b-1]==0;dfs(a,b+1);         //右 
	} 
}

主函数:
int main(void)要传入void(目前不知道原因,记就是了)
此题的常规操作:
输入多组数据用while(t--)

逐个传入二维数组常规操作:

for(int i=1;i<=n;i++)            //逐个输入二维数组的常规操作 
		{
			for(int j=0;j<=m;j++)
			{
				cin>>arr[i][j];
			}
		}

遍历二维数组也要两层循环,其中从1开始,因为我们计数从1开始,简化操作;
i、j均小于等于;

for(int i=1;i<=n;i++)
{
	for(int j=1;j<=m;j++)
	{......}

}

其他操作:
1、万能头;
2、可以宏定义一个N表示水池的边界,其中105是从1到100再上下左右+1 为105(自行体会);

#include<bits/stdc++.h>        //万能头
#define N 105 

还可以再看看链接里的讲解;

整体代码:

#include<bits/stdc++.h>        //万能头
#define N 105 
using namespace std;

int arr[N][N];

void dfs(int a,int b)                                   //深度优先搜索函数,一旦调用,一个点周围连续的地方都记为0; 
{
	if(arr[a-1][b]==1){arr[a-1][b]==0;dfs(a-1,b);        //上 
	}
	
	if(arr[a+1][b]==1){arr[a+1][b]==0;dfs(a+1,b);        //下 
	}
	
	if(arr[a][b-1]==1){arr[a][b-1]==0;dfs(a,b-1);        //左 
	}
	
	if(arr[a][b+1]==1){arr[a][b-1]==0;dfs(a,b+1);         //右 
	} 
}

int main(void)                       //int main(void) 常规套路要记下来 
{
	int t;
	int n,m;
	cin>>t;
	while(t--)
	{
		int cnt=0;
		cin>>n>>m;
		for(int i=1;i<=n;i++)            //逐个输入二维数组的常规操作 
		{
			for(int j=0;j<=m;j++)
			{
				cin>>arr[i][j];
			}
		}
		
		for(int i=1;i<=n;i++)           //对二维数组进行遍历 
		{
			for(int j=1;j<=m;j++)
			{
				if(arr[i][j]==1)
				{
					cnt++;              //核心步骤 
					dfs(i,j);
				}
			}
		}
		
		cout<<cnt<<endl;
	}
	
	return 0;
}

2、六角星问题

模型一:
六角星问题

题目:

如图【1.png】所示六角形中,填入1~12的数字。使得每条直线上的数字之和都相同。
图中,已经替你填好了3个数字,请你计算星号位置所代表的数字是多少?

在这里插入图片描述
本题小总结:

1、讲图中每一个节点抽象成一个数字,一共13个节点,用数组来存放其放的数字;
2、用v数组(visited)来表示一个数字是否被用过,如:
v[1]=1,即数字1已经被用过;
v[4]=0,即数字4未被用过。
如:

#include<bits/stdc++.h>
using namespace std;

int a[13]={0},v[13]={0};     //a是表示图的数组,v是表示某个数字是否使用过visited
void dfs(int x);
void jude(void);            //声明一下;

int main(void)
{
	int i;
	a[1]=1;
	a[2]=8;
	a[12]=3;                    //给图标号
	
	v[1]=1;
	v[8]=1;
	v[3]=1;                      //给使用过的数字mark一下; 
	
	dfs(1);
	return 0;
 } 

3、若x是1,2,12这三个已经有了的,直接进行下一步dfs;
如果x是13,则进行判断;
前面有这两个if判断后,走到这一步的都是非1,2,12,13的,接下来是核心操作:
若数字未被用过,就直接把该数字放进去,然后一直向下递归(dfs(x+1)),到13后判断,如果不符合题意,就退回到dfs(x+1)的下一步,v[i]=0,即之前用过的那个数字行不通,不用那个数字,从那个数字之后往下尝试递归。
如下:

void dfs(int x)
 {
	int i,b[6];             //b代表六条边
	if(x==1||x==2||x==12)         //如果x是1,2,12这三个一开始已经有的,就直接递归到下一个; 
	{
		dfs(x+1);
		return ;
	}
	
	if(x==13)                     //如果x是13,最后一个,就进行判断; 
	{
		jude();
	}
	
	for(i=1;i<13;i++)           //核心操作:从数字1到12,如果有没有用过(v[数字]=0),就让它被用,放入下一个空格,然后反复调用 
	{
		if(v[i]==0)
		{
			v[i]=1;
			a[x]=i;
			dfs(x+1);
			v[i]=0;
		}
	}
 }

4、这一步是定义判断函数,判断每条表之和是否相等。相当通俗易懂,直接放代码:

void jude(void)
 {
 	int i,b[6];
 	b[0]=a[1]+a[3]+a[6]+a[8]; 
	b[1]=a[1]+a[4]+a[7]+a[11];
	b[2]=a[2]+a[3]+a[4]+a[5];
	b[3]=a[2]+a[6]+a[9]+a[12];
	b[4]=a[5]+a[7]+a[10]+a[12];
	b[5]=a[8]+a[9]+a[10]+a[11];

	for(i=1;i<6;i++)
	{
		if(b[i]!=b[i-1])
		{
			return;
		}
	}
	cout<<a[6];
 }

总体思想就是递归和回溯,加上数组的运用。
整体代码:

#include<bits/stdc++.h>
using namespace std;

int a[13]={0},v[13]={0};     //a是表示图的数组,v是表示某个数字是否使用过visited
void dfs(int x);
void jude(void);            //声明一下;

int main(void)
{
	int i;
	a[1]=1;
	a[2]=8;
	a[12]=3;                    //给图标号
	
	v[1]=1;
	v[8]=1;
	v[3]=1;                      //给使用过的数字mark一下; 
	
	dfs(1);
	return 0;
 } 
 
 void dfs(int x)
 {
	int i,b[6];             //b代表六条边
	if(x==1||x==2||x==12)         //如果x是1,2,12这三个一开始已经有的,就直接递归到下一个; 
	{
		dfs(x+1);
		return ;
	}
	
	if(x==13)                     //如果x是13,最后一个,就进行判断; 
	{
		jude();
	}
	
	for(i=1;i<13;i++)           //核心操作:从数字1到12,如果有没有用过(v[数字]=0),就让它被用,放入下一个空格,然后反复调用 
	{
		if(v[i]==0)
		{
			v[i]=1;
			a[x]=i;
			dfs(x+1);
			v[i]=0;
		}
	}
 }
 
 void jude(void)
 {
 	int i,b[6];
 	b[0]=a[1]+a[3]+a[6]+a[8]; 
	b[1]=a[1]+a[4]+a[7]+a[11];
	b[2]=a[2]+a[3]+a[4]+a[5];
	b[3]=a[2]+a[6]+a[9]+a[12];
	b[4]=a[5]+a[7]+a[10]+a[12];
	b[5]=a[8]+a[9]+a[10]+a[11];

	for(i=1;i<6;i++)
	{
		if(b[i]!=b[i-1])
		{
			return;
		}
	}
	cout<<a[6];
 }

3、N皇后问题

模型二

在N*N格的国际象棋上摆放N个皇后,使其不能互相攻击,
即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。

如果出现x+y==某个常数,那么它们就在一条对角线上了。
+n是因为数组下标不能为负,加的一个参数而已。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=10;
int n;
char g[N][N];
int lie[N],zdj[N],fdj[N];
void dfs(int u)//u是行 每行只能有一个 
{
	if(u==n)//结束
	{
		for(int i=0;i<n;i++) cout<<g[i]<<endl;
		cout<<endl;
		return;
	} 
	
	for(int i=0;i<n;i++)
	{
		if(!lie[i]&&!zdj[u+i]&&!fdj[n-u+i])
		{
			g[u][i]='Q';
			lie[i]=1;
			zdj[u+i]=1;fdj[n-u+i]=1;
			dfs(u+1);//下一行
			g[u][i]='.';//恢复现场 
			lie[i]=0;
			zdj[u+i]=0;fdj[n-u+i]=0;
		}
	}
}
int main()
{
	cin>>n;
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			g[i][j]='.';
		}
	}
	dfs(0);
	return 0; 
}

解法在这里:
一个模板。

4、带分数

100 可以表示为带分数的形式:100 = 3 + 69258 / 714 , 还可以表示为:100 = 82 + 3546 / 197
注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。
类似这样的带分数,100 有 11 种表示法。
题目要求:
从标准输入读入一个正整数N (N<1000*1000)
程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。
注意:不要求输出每个表示,只统计有多少表示法!

小总结:
1、主函数:输入、调用dfs函数,输出;
2、dfs函数,不断递归和某个数字是否使用等操作;
3、jude判断函数,调用sum函数组合出许多种数字组合并判断是否能符合题意;
4、sum函数,将传入的数字一个个组成如题所示的数字,如24567这种;

dfs函数里的注释:
若某个数字没有用过,则将它使用,并进入下一层递归,然后自然地就到了jude,若可以则count1++;
行或不行都回溯回来,重新用不同的数字,即v[i]=0,然后循环到下一个数字;

本题有两个坑点:
1、分母不能做除数,要进行判断;
2、可能报“reference to ’ *** ’ is ambiguous”的错,因为用的是万能头,我定义的变量名跟里面的属性或者方法重名了,将***里的变量名改一下即可。

整体代码:

#include<bits/stdc++.h>
using namespace std;

long long count1=0,p;
int a[10],v[10]={0};

void dfs(int n);                 //一堆声明; 
void jude(void);
int sum(int x,int y);

int main(void)
{
	cin>>p;
	dfs(1);
	cout<<count1;
	
	return 0;
}

void dfs(int n)
{
	int i;
	
	if(n>9)                  //当递归到9以上即数字都用完了,可以进行判断 
	{
		jude();
	}
	
	for(i=1;i<10;i++)           //反复递归 
	{
		if(!v[i])
		{
			v[i]=1;           //若某个数字没有用过,则将它使用,并进入下一层递归,然后自然地就到了jude,若可以则count1++; 
			a[n]=i;             //行或不行都回溯回来,重新用不同的数字,即v[i]=0,然后循环到下一个数字; 
			dfs(n+1);
			v[i]=0;
		}
	}
}

void jude(void)
{
	int x,y,z;
	
	for(int i=0;i<8;i++)
	{
		for(int j=i+1;j<9;j++)         //这个循环是步骤最多的地方;把每一种可能的数字组合都试了一遍; 
		{                                //且,数字可以不连续,因为某个数字若已经用过就跳过去了; 
			x=sum(1,i);
			y=sum(i+1,j);
			z=sum(j+1,9);
			
			if((p-x)*z==y)              //即题目中的分式等式 
			{
				count1++;
			}
		}
	}
}

int sum(int x,int y)
{
	int s=0;
	
	if(y==0)             //分母不能做除数 
	{
		return 0;
	}
	
	for(x;x<y;x++)
	{
		s=s*10+a[x];
	}
	
	return s;
 } 

关于经典例题的总结

摘自参见资料5

2-4题都有相同的一段代码:

这个函数做的就是把每一种情况列举一次,再用jude函数筛选。
这种模型适合的题目是:给你一个图让你填不重复的数。

void dfs(int n)
{
    int i;
    if(n>x)
    jude();
    for(i=1;i<=x;i++) 
        if(v[i])
        {
            v[i] = 0;
            a[n] = i;
            dfs(n+1); 
            v[i] = 1;
          } 
}  

其他题(链接)

AcWing 129. 火车进栈 dfs+栈

AcWing 129. 火车进栈 dfs+栈

飞行员兄弟 DFS+枚举

飞行员兄弟 DFS+枚举

Lake Counting(经典dfs)

Lake Counting

#include<iostream>
using namespace std;
typedef long long ll;
//======================
const int N=100+10;
char a[N][N];
int vis[N][N];
int ans=0;
int dx[8]={-1,0,1,-1,1,-1,0,1};
int dy[8]={-1,-1,-1,0,0,1,1,1};
int n,m;
void dfs(int x,int y)//坐标
{
	if(vis[x][y]) return;
	vis[x][y]=1;
	for(int i=0;i<8;i++)
	{
		int xx=x+dx[i];
		int yy=y+dy[i];
		
		if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&!vis[xx][yy]&&a[xx][yy]=='W')
		{					
			dfs(xx,yy);
		}
	}
} 
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		scanf("%s",a[i]+1);
	}

	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			if(!vis[i][j]&&a[i][j]=='W')
			{
				ans++;
			//	cout<<i<<" "<<j<<endl;
				dfs(i,j);
			}
		}
	
	cout<<ans;
	return 0; 
}

可参考资料

1、图的详解
2、较为全面的大佬博客
3、算法源码,用C++、C和Java
4、简单的水池问题
5、大佬的模型例题,好几道
6、非常厉害的入门模板
7、时隔很久的一点题目总结

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【算法】深度优先搜索DFS 入门:基本知识+经典例题 的相关文章

  • 将处理后的图形绘制到另一个图形中

    我想将一个经过处理的图形绘制到另一个图形中 I have two graphics var gHead Graphics FromImage h var gBackground Graphics FromImage b Transform
  • 如何进行带有偏差的浮点舍入(始终向上或向下舍入)?

    我想以偏置舍入浮动 要么总是向下 要么总是向上 代码中有一个特定的点 我需要这个 程序的其余部分应该像往常一样四舍五入到最接近的值 例如 我想四舍五入到最接近的 1 10 倍数 最接近 7 10 的浮点数约为 0 69999998807 但
  • Blazor 与 Razor

    随着 Blazor 的发明 我想知道这两种语言之间是否存在显着的效率 无论是在代码创建方面还是在代码的实际编译 执行方面 https github com SteveSanderson Blazor https github com Ste
  • 在 C++11 中省略返回类型

    我最近发现自己在 C 11 模式下的 gcc 4 5 中使用了以下宏 define RETURN x gt decltype x return x 并编写这样的函数 template
  • 调试内存不足异常

    在修复我制作的小型 ASP NET C Web 应用程序的错误时 我遇到了 OutOfMemoryException 没有关于在哪里查看的提示 因为这是一个编译时错误 如何诊断此异常 我假设这正是内存分析发挥作用的地方 有小费吗 Thank
  • 为什么密码错误会导致“填充无效且无法删除”?

    我需要一些简单的字符串加密 所以我编写了以下代码 有很多 灵感 来自here http www codeproject com KB security DotNetCrypto aspx create and initialize a cr
  • 在 C# 中将位从 ulong 复制到 long

    所以看来 NET 性能计数器类型 http msdn microsoft com en us library system diagnostics performancecounter aspx有一个恼人的问题 它暴露了long对于计数器
  • Xamarin Android:获取内存中的所有进程

    有没有办法读取所有进程 而不仅仅是正在运行的进程 如果我对 Android 的理解正确的话 一次只有一个进程在运行 其他所有进程都被冻结 后台进程被忽略 您可以使用以下代码片段获取当前正在运行的所有 Android 应用程序进程 Activ
  • gdb 在 docker 上立即退出“进程已完成,退出代码 1”或 lldb“数据包返回错误 8”。另外:如何在 docker 中允许进行 C++ 调试

    这花了我一整天的时间才找到 所以我将其发布以供将来参考 我正在 docker 镜像上开发 C 我正在使用克利翁 我的代码是在调试模式下编译的 并且在运行模式下运行良好 但是当尝试调试时 进程会立即退出 并显示非常丰富的信息 Process
  • 事件日志写入错误

    很简单 我想向事件日志写入一些内容 protected override void OnStop TODO Add code here to perform any tear down necessary to stop your serv
  • 组合框项目为空但数据源已满

    将列表绑定到组合框后 其 dataSource Count 为 5 但组合框项目计数为 0 怎么会这样 我习惯了 Web 编程 而且这是在 Windows 窗体中进行的 所以不行combo DataBind 方法存在 这里的问题是 我试图以
  • UWP 无法在两个应用程序之间创建本地主机连接

    我正在尝试在两个 UWP 应用程序之间设置 TCP 连接 当服务器和客户端在同一个应用程序中运行时 它可以正常工作 但是 当我将服务器部分移动到一个应用程序并将客户端部分移动到另一个应用程序时 ConnectAsync 会引发异常 服务器未
  • 32位PPC rlwinm指令

    我在理解上有点困难rlwinmPPC 汇编指令 旋转左字立即然后与掩码 我正在尝试反转函数的这一部分 rlwinm r3 r3 0 28 28 我已经知道什么了r3 is r3在本例中是一个 4 字节整数 但我不确定这条指令到底是什么rlw
  • 如何检测 C# 中该字典键是否存在?

    我正在使用 Exchange Web 服务托管 API 和联系人数据 我有以下代码 即功能性的 但并不理想 foreach Contact c in contactList string openItemUrl https service
  • 无法使用 Ninject 将依赖项注入到从 Angular 服务调用的 ASP.NET Web API 控制器中

    我将 Ninject 与 ASP NET MVC 4 一起使用 我正在使用存储库 并希望进行构造函数注入以将存储库传递给其中一个控制器 这是实现 StatTracker 接口的上下文对象 EntityFramework public cla
  • Fluent NHibernate 日期时间 UTC

    我想创建一个流畅的 nhibernate 映射来通过以下方式映射 DateTime 字段 保存时 保存 UTC 值 读取时 调整为本地时区值 实现此映射的最佳方法是什么 就我个人而言 我会将日期存储在 UTC 格式的对象中 然后在读 写时在
  • 在基类集合上调用派生方法

    我有一个名为 A 的抽象类 以及实现 A 的其他类 B C D E 我的派生类持有不同类型的值 我还有一个 A 对象的列表 abstract class A class B class A public int val get privat
  • boost::program_options:带有固定和可变标记的参数?

    是否可以在 boost program options 中使用此类参数 program p1 123 p2 234 p3 345 p12 678 即 是否可以使用第一个标记指定参数名称 例如 p 后跟一个数字 是动态的吗 我想避免这种情况
  • 如何确定母版页中正在显示哪个子页?

    我正在母版页上编写代码 我需要知道正在显示哪个子 内容 页面 我怎样才能以编程方式做到这一点 我用这个 string pageName this ContentPlaceHolder1 Page GetType FullName 它以 AS
  • 如何使用 std::array 模拟 C 数组初始化“int arr[] = { e1, e2, e3, ... }”行为?

    注意 这个问题是关于不必指定元素数量并且仍然允许直接初始化嵌套类型 这个问题 https stackoverflow com questions 6111565 now that we have stdarray what uses are

随机推荐

  • 低功耗蓝牙(BLE)你入门了吗

    前言 蓝牙低功耗 Bluetooth Low Energy 或称Bluetooth LE BLE 旧商标Bluetooth Smart 用于医疗保健 运动健身 安防 工业控制 家庭娱乐等领域 在如今的物联网时代下大放异彩 扮演者重要一环 是
  • Linux中断处理程序框架

    设备的中断会打断内核进程的正常调度和运行 系统对更高吞吐率的追求势必要求中断服务程序尽量短小精悍 但是 这个良好的愿望往往与现实不吻合 在多数真实的系统中 当中断到来时 要完成的工作往往并不是短小的 它可能要进行大量的耗时处理 为了在中断执
  • Bash中各种括号

    Bash中有各种括号 包括单小括号 双小括号 单中括号 双中括号 单大括号 而且它们之间很容易混淆 所以很有必要总结一下它们的用法 1 的用法 单个小括号用来创建一个子shell 例如 pwd home xfeng cd tmp pwd t
  • matlab智能算法之模拟退火算法

    智能算法之模拟退火算法 1 起源 2 物理退火流程 2 1 加温过程 2 2 等温过程 2 3 冷却过程 2 4 组合优化与物理退化 3 原理 3 1 算法核心迭代 3 2 具体流程 4 案例 4 1 求解n元函数的极小值 4 2 求解二元
  • Java 多线程编程

    Java给多线程编程提供了内置的支持 一个多线程程序包含两个或多个能并发运行的部分 程序的每一部分都称作一个线程 并且每个线程定义了一个独立的执行路径 多线程是多任务的一种特别的形式 但多线程使用了更小的资源开销 这里定义和线程相关的另一个
  • 代码整洁之道1-6章总结

    第一章 整洁代码 总的来说就是 整洁的代码有益于团队的测试开发 往大了说会影响公司的发展 作者列举了几个公司的反面教材 由于代码不够整洁 无法继续维护 导致公司倒闭的情况 迭代周期越来越长 所以说作为一个程序员 都有义务和责任去尽量写出简洁
  • 在服务中启动带有界面的程序

    转载请标明是引用于 http blog csdn net chenyujing1234 欢迎大家拍砖 参考文章 http blog csdn net goingup article details 2932752 reply 在服务中启动带
  • android 中文权限解释

    PermissList Key android permission ACCESS CHECKIN PROPERTIES Title 访问检入属性 Memo 允许对检入服务上传的属性进行读 写访问 普通应用程序不能使用此权限 Level 0
  • linux脚本加载bashprofile,linux环境变量之profile .bash_profile .bash_login .profile .bashrc 加载详解...

    前言 这里讨论的shell都是bash shell 使用哪种shell形式可以通过修改 etc passwd 文件配置 bash sh csh 讨论的配置文件包括 etc profile etc bashrc bash login bash
  • 【Linux】Vmware虚拟机安装教程

    目录 一 下载Vmware和CentOS 二 使用Vmware创建虚拟机 1 创建虚拟机 2 稍后安装镜像 3 选择对应镜像版本 4 输入虚拟机名称和保存地址 5 指定虚拟机磁盘大小 6 完成 三 安装CentOS 1 查看cpu是否开启虚
  • 15.Linux多线程编程

    一 线程理论基础 1 定义 线程技术早在60年代就被提出 但真正应用多线程到操作系统中去 是在80年代中期 solaris是这方面的佼佼者 传统的Unix也支持线程的概念 但是在一个进程中只 允许有一个线程 这样多线程就意味着多进程 现在
  • Netty NIO 框架性能压测-短链接-对比Tomcat

    压测方案 准备多个文件大小分别为 1k 10k 100k 300k 使用ab分别按 50 2000 按50逐渐叠加 压测服务 每次请求10W次 硬件信息 CPU Intel R Xeon R CPU 1 86GHz 4 4G 统计脚本 gr
  • 嵌入式linux屏幕显示,嵌入式Linux下竖屏显示配置

    摘要 目前大多数设备的显示器是横屏 例如高清分辨率1920 1080 笔记本14寸显示器1366 768以及最近很热门的 4K 分辨率3840 2160 另外一种则是竖屏显示器 常见于娱乐 广告设备 手机最为常见的竖屏设备 以及户外的广告牌
  • git命令全家福

    1 切换分支 git checkout dev 2 拉取远程分支到本地 并切换到该分支 git pull git checkout b dev 本地分支名称 origin dev 远程分支名称 3 查看分支 git branch a
  • 2018年最常见的Python面试题&答案(上篇)

    Q 1 Python有哪些特点和优点 作为一门编程入门语言 Python主要有以下特点和优点 可解释 具有动态特性 面向对象 简明简单 开源 具有强大的社区支持 当然 实际上Python的优点远不止如此 可以阅读该文档 详细了解 https
  • ubuntu安装svn服务器

    安装命令 sudo apt getinstall subversion 创建项目目录 sudo mkdir home svn cd home svn project sudo chmod R777 project 创建svn仓库 sudo
  • rbac 另外一种逃逸

    Privilege Escalation from Node Proxy Rights in Kubernetes RBAC aquasec com
  • mysql时间相减-时间运算-转换毫秒值的问题

    mysql时间运算 一 时间相减发现与结果差距很大 二 原因 三 正确的运算 一 时间相减发现与结果差距很大 mysql gt select t1 t2 t2 t1 from mytest t1 t2 t2 t1 2013 04 21 16
  • Spring4学习笔记:Spring框架中为一个bean配置依赖注入的方式

    Spring框架为一个bean配置依赖注入的四种方式 属性注入 构造方法注入 工厂注入 泛型依赖注入 1 属性注入 属性方法注入利用setXxx 方法注入 Bean 的属性值或者依赖对象 由于属性注入方式具有可选择性和灵活性高的优点 因此属
  • 【算法】深度优先搜索DFS 入门:基本知识+经典例题

    DFS最重要的是理清搜索顺序 ps 这是我入门dfs时写的博客 后来dfs渐渐熟练了 也补充了一些题目上去 带原题和代码 个人感觉整篇博文从上到下确实由易到难 代码也由开始的冗长变得渐渐精简 自学DFS看的视频 小甲鱼 讲原理 青岛大学 王