python学习中相关问题整理(补充)

本文整理了Python学习中的一些重点问题,包括SQL注入的原理、危害及防治,冒泡排序算法的实现,以及Python的全局解释器锁(GIL)的概念与多线程使用。此外,还探讨了线程池的设计和协程实现的生产者消费者模型。
摘要由CSDN通过智能技术生成

25. 数据库联接操作,左连接,右链接,全链接的操作以及区别(手写 SQL 语句)

left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 (通俗点讲就是,左边的表是老大,要显示全部内容,右边的表是小弟,只有跟老大相同的东西才显示出来,不相同的就是null);

right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录(通俗点讲就是,右边的表是老大,要显示全部内容,左边的表是小弟,只有跟老大相同的东西才显示出来,不相同的就是null;

inner join(等值连接|全连接也叫内连接) 只返回两个表中联结字段相等的行(左右两边势均力敌,不相上下。两边都不想妥协,所以只有共同的东西才显示出来);
26. 数据库的三大范式的理解。
经过研究和对使用中问题的总结,对于设计数据库提出了一些 规范,这些规范被称为范式。
 
第一范式( 1NF) :列不可拆分 , 即无重复的域。是指数据库表的每一列都是不可分割的基本数据项。
符合第一范式的特点就有:有主关键字、主键不能为空、主键不能重复, 字段不可以再分。
 
第二范式( 2NF) :唯一标识 ,即拥有实体的唯一标识 (eg: 身份证、 id 号等 )。
指每个表必须有且仅有一个数据元素为主关键字 (Primary key), 其他数据元素与主关键字一一对应。这种关系为函数依赖。
符合第二范式的特点就有:满足第一范式的前提下,消除部分函数依赖。
 
第三范式( 3NF) :引用主键 , 即每列数据都与主键直接相关。
符合第三范式的特点就有:不存在非主属性对码的传递性依赖以及部分性依赖 。

 

三大范式只是一般设计数据库的基本理念,可以建立冗余较小、结构合理的数据库。如果有特殊情况,当然要特殊对待,数据库设计最重要的是看需求跟性能,需求>性能>表结构。所以不能一味的去追求范式建立数据库。

27.什么是SQL注入?

SQL是操作数据库数据的结构化查询语言,网页的应用数据和后台数据库中的数据进行交互时会采用SQL。而SQL注入是将Web页面的原URL、表单域或数据包输入的参数,修改拼接成SQL语句,传递给Web服务器,进而传给数据库服务器以执行数据库命令。如Web应用程序的开发人员对用户所输入的数据或cookie等内容不进行过滤或验证(即存在注入点)就直接传输给数据库,就可能导致拼接的SQL被执行,获取对数据库的信息以及提权,发生SQL注入攻击。

 其特点如下:

1)、广泛性

任何一个基于SQL语言的数据库都可能被攻击,很多开发人员在编写Web应用程序时未对从输入参数、Web表单、cookie等接受到的值进行规范性验证和检测,通常会出现SQL注入漏洞。 

2)、隐蔽性

SQL注入语句一般都嵌入在普通的HTTP请求中,很难与正常语句区分开,所以当前许多防火墙都无法识别予以警告,而且SQL注入变种极多,攻击者可以调整攻击的参数,所以使用传统的方法防御SQL注入效果非常不理想。 

3)、危害大

攻击者通过SQL注入获取到服务器的库名、表名、字段名,从而获取到整个服务器中的数据,对网站用户的数据安全有极大的威胁。攻击者也可以通过获取到的数据,得到后台管理员的密码,然后对网页页面进行恶意篡改。这样不仅对数据库信息安全造成严重威胁,对整个数据库系统安全也影响重大。

4)、操作方便

互联网上有很多SQL注入工具,简单易学,攻击过程简单,不需要专业知识也能自如运用。

28. Python的底层实现,用到的排序函数(手写冒泡算法)

答:共有八种

  • 选择排序-简单选择排序
  • 选择排序-堆排序
  • 插入排序-直接插入排序
  • 插入排序-希尔排序
  • 交换排序-快速排序
  • 交换排序-冒泡排序
  • 归并排序
  • 桶排序/基数排序

 冒泡排序:

冒泡排序是最常见到的排序算法,也是大学学习时遇到的第一种排序算法,它的实现思想是:相邻的两个元素进行比较,然后把较大的元素放到后面(正向排序),在一轮比较完后最大的元素就放在了最后一个位置,因为这一点像鱼儿在水中吐的气泡在上升的过程中不断变大,所以得名冒泡排序。在该排序算法中,要遍历n-1轮,每一轮都要比较数组中的元素,所以时间复杂度是

O(n2)。冒泡排序具体实现的代码如下:

def bubble_sort(alist):
    length = len(alist)
    for i in range(length - 1):
        # i表示比较多少轮
        for j in range(length - i - 1):
            # j表示每轮比较的元素的范围,因为每比较一轮就会排序好一个元素的位置,
            # 所以在下一轮比较的时候就少比较了一个元素,所以要减去i
            if alist[j] > alist[j + 1]:
                alist[j], alist[j + 1] = alist[j + 1], alist[j]

原文链接:https://blog.csdn.net/sensev/article/details/80908776

9. 解释一下 python 中的 GIL 是什么

1. gil是什么:全局解析器锁
2. gil的作用:单核的情况下可以实现多任务(并发)
3. gil的解决方案:

多进程vs多线程:最流行的方法是应用多进程方法,在这个方法中你使用多个进程而不是多个线程。每一个Python进程都有自己的Python解释器和内存空间,因此GIL不会成为问题。

30. GIL是单线程的,那么python中多线程的实现有什么用。

  1. 进程之间不能共享内存,但线程之间共享内存非常容易。
  2. 操作系统在创建进程时,需要为该进程重新分配系统资源,但创建线程的代价则小得多。因此,使用多线程来实现多任务并发执行比使用多进程的效率高。
  3. Python 语言内置了多线程功能支持,而不是单纯地作为底层操作系统的调度方式,从而简化了 Python 的多线程编程。

31. 对于多线程,我是怎么去使用的,如果要我去设计一个线程池,我该怎么去设计。

方法一:使用threadpool模块,这是个python的第三方模块,支持python2和python3.

方法二:使用concurrent.futures模块,这个模块是python3中自带的模块,但是,python2.7以上版本也可以安装使用

方法3:重写threadpool或者future的函数;

方法4:自己构建一个线程池
32. python协程实现一个生产者消费者模型。(手写代码)

def consumer(name):
    print('%s开始准备吃包子了' % name)
    while True:
        baozi = yield
        print('[%s]包子来了,被[%s]吃了' % (baozi, name))

def product(name):
    print('%s开始做包子了' % name)
    c = consumer('张三')  # 生成器
    c1 = consumer('李四')
    c.__next__()
    c1.__next__()

代码转自:https://www.cnblogs.com/xuehuahongmei/p/5958373.html

运行结果:

老板开始做包子了
张三开始准备吃包子了
李四开始准备吃包子了
做好了2个包子
[0]包子来了,被[张三]吃了
[0]包子来了,被[李四]吃了
做好了2个包子
[1]包子来了,被[张三]吃了
[1]包子来了,被[李四]吃了
做好了2个包子
[2]包子来了,被[张三]吃了
[2]包子来了,被[李四]吃了
做好了2个包子
[3]包子来了,被[张三]吃了
[3]包子来了,被[李四]吃了
做好了2个包子
[4]包子来了,被[张三]吃了
[4]包子来了,被[李四]吃了
做好了2个包子
[5]包子来了,被[张三]吃了
[5]包子来了,被[李四]吃了
做好了2个包子
[6]包子来了,被[张三]吃了
[6]包子来了,被[李四]吃了
做好了2个包子
[7]包子来了,被[张三]吃了
[7]包子来了,被[李四]吃了
做好了2个包子
[8]包子来了,被[张三]吃了
[8]包子来了,被[李四]吃了
做好了2个包子
[9]包子来了,被[张三]吃了
[9]包子来了,被[李四]吃了

Process finished with exit code 0


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值