zoukankan      html  css  js  c++  java
  • 2017年7月19日面试后记

    由于基础学的不牢,导致场面一度十分尴尬......

    一个冒泡排序都憋半天还写错了.....我深深的感受到了自己好菜

    我决定以后每天抽时间补补算法和数据结构的基础

    今天答不上来和答的不好的问题,去查了一下:

    1.迭代

    其实迭代就是用for循环遍历list或tuple。

    关于这个问题面试官提到的是yield,他应该是想问关于生成器的问题吧。

    顺便提一下迭代器:

    实际上for循环也可以对其他对象进行迭代,只要该对象实现了__iter__方法。该方法会返回一个迭代器,迭代器就是具有next方法(这个方法在调用时不需要参数)的对象。在调用next方法时,迭代器会返回它的下一个值。如果next方法被调用,但迭代器没有值可以返回,就会引发一个StopIteration异常。

    生成器:是一种用普通的函数语法定义的迭代器。

    yield是一个表达式,是有返回值的。

    当一个函数中含有yield时,它不再是一个普通的函数,而是一个生成器.当该函数被调用时不会自动执行,而是暂停。

    但它不是像return那样返回值,而是每次产生多个值。每次产生一个值,函数就会被冻结:即函数停在那点等待被重新唤醒。函数被重新唤醒后就从停止的那点开始执行。

    从别处看到了几个例子:

    例1:

    [python] view plain copy
     
    1. >>> def mygenerator():  
    2. ...     print 'start...'  
    3. ...     yield 5  
    4. ...   
    5. >>> mygenerator()            //在此处调用,并没有打印出start...说明存在yield的函数没有被运行,即暂停  
    6. <generator object mygenerator at 0xb762502c>  
    7. >>> mygenerator().next()     //调用next()即可让函数运行.  
    8. start...  
    9. 5  
    10. >>>   

    如一个函数中出现多个yield则next()会停止在下一个yield前,见例2:

    例2:

    [python] view plain copy
     
    1. >>> def fun2():  
    2. ...     print 'first'  
    3. ...     yield 5  
    4. ...     print 'second'  
    5. ...     yield 23  
    6. ...     print 'end...'  
    7. ...   
    8. >>> g1 = fun2()  
    9. >>> g1.next()             //第一次运行,暂停在yield 5               
    10. first  
    11. 5  
    12. >>> g1.next()             //第二次运行,暂停在yield 23  
    13. second  
    14. 23  
    15. >>> g1.next()             //第三次运行,由于之后没有yield,再次next()就会抛出错误  
    16. end...  
    17. Traceback (most recent call last):  
    18.   File "<stdin>", line 1, in <module>  
    19. StopIteration  
    20. >>>   

    为什么yield 5会输出5,yield 23会输出23? 

    我们猜测可能是因为yield是表达式,存在返回值.

    那么这是否可以认为yield 5的返回值一定是5吗?实际上并不是这样,这个与send函数存在一定的关系,这个函数实质上与next()是相似的,区别是send是传递yield表达式的值进去,而next不能传递特定的值,只能传递None进去,因此可以认为g.next()和g.send(None)是相同的。见例3:

    例3:

     
    1. >>> def fun():  
    2. ...     print 'start...'  
    3. ...     m = yield 5  
    4. ...     print m  
    5. ...     print 'middle...'  
    6. ...     d = yield 12  
    7. ...     print d  
    8. ...     print 'end...'  
    9. ...   
    10. >>> m = fun()              //创建一个对象  
    11. >>> m.next()               //会使函数执行到下一个yield前  
    12. start...  
    13. 5  
    14. >>> m.send('message')      //利用send()传递值  
    15. message                    //send()传递进来的   
    16. middle...  
    17. 12  
    18. >>> m.next()  
    19. None                       //可见next()返回值为空  
    20. end...  
    21. Traceback (most recent call last):  
    22.   File "<stdin>", line 1, in <module>  
    23. StopIteration  

    2.python实现二叉树

    树的遍历主要有两种,一种是深度优先遍历,像前序、中序、后序;还有一种是广度优先遍历。像层次遍历。=

    深度优先一般用递归,广度优先一般用队列。普通情况下能用递归实现的算法大部分也能用堆栈来实现。

    # _*_ encoding:utf-8 _*_
    __author__ = 'xyx'
    __date__ = '2017-7-20 22:41'

    #coding=utf-8

    class Node(object):
    """节点类"""
    def __init__(self, elem=-1, lchild=None, rchild=None):
    self.elem = elem
    self.lchild = lchild
    self.rchild = rchild


    class Tree(object):
    """树类"""
    def __init__(self):
    self.root = Node()


    def add(self, elem):
    """为树加入节点"""
    node = Node(elem)
    if self.root.elem == -1: #假设树是空的。则对根节点赋值
    self.root = node
    else:
    myQueue = []
    treeNode = self.root
    myQueue.append(treeNode)
    while myQueue: #对已有的节点进行层次遍历
    treeNode = myQueue.pop(0)
    if treeNode.lchild == None:
    treeNode.lchild = node
    return
    elif treeNode.rchild == None:
    treeNode.rchild = node
    return
    else:
    myQueue.append(treeNode.lchild)
    myQueue.append(treeNode.rchild)


    def front_digui(self, root):
    """利用递归实现树的先序遍历"""
    if root == None:
    return
    print (root.elem),
    self.front_digui(root.lchild)
    self.front_digui(root.rchild)


    def middle_digui(self, root):
    """利用递归实现树的中序遍历"""
    if root == None:
    return
    self.middle_digui(root.lchild)
    print (root.elem),
    self.middle_digui(root.rchild)


    def later_digui(self, root):
    """利用递归实现树的后序遍历"""
    if root == None:
    return
    self.later_digui(root.lchild)
    self.later_digui(root.rchild)
    print (root.elem),


    def front_stack(self, root):
    """利用堆栈实现树的先序遍历"""
    if root == None:
    return
    myStack = []
    node = root
    while node or myStack:
    while node: #从根节点開始,一直找它的左子树
    print (node.elem),
    myStack.append(node)
    node = node.lchild
    node = myStack.pop() #while结束表示当前节点node为空,即前一个节点没有左子树了
    node = node.rchild #開始查看它的右子树


    def middle_stack(self, root):
    """利用堆栈实现树的中序遍历"""
    if root == None:
    return
    myStack = []
    node = root
    while node or myStack:
    while node: #从根节点開始。一直找它的左子树
    myStack.append(node)
    node = node.lchild
    node = myStack.pop() #while结束表示当前节点node为空。即前一个节点没有左子树了
    print (node.elem),
    node = node.rchild #開始查看它的右子树


    def later_stack(self, root):
    """利用堆栈实现树的后序遍历"""
    if root == None:
    return
    myStack1 = []
    myStack2 = []
    node = root
    myStack1.append(node)
    while myStack1: #这个while循环的功能是找出后序遍历的逆序,存在myStack2里面
    node = myStack1.pop()
    if node.lchild:
    myStack1.append(node.lchild)
    if node.rchild:
    myStack1.append(node.rchild)
    myStack2.append(node)
    while myStack2: #将myStack2中的元素出栈,即为后序遍历次序
    print (myStack2.pop().elem),


    def level_queue(self, root):
    """利用队列实现树的层次遍历"""
    if root == None:
    return
    myQueue = []
    node = root
    myQueue.append(node)
    while myQueue:
    node = myQueue.pop(0)
    print (node.elem),
    if node.lchild != None:
    myQueue.append(node.lchild)
    if node.rchild != None:
    myQueue.append(node.rchild)


    if __name__ == '__main__':
    """主函数"""
    elems = range(10) #生成十个数据作为树节点
    tree = Tree() #新建一个树对象
    for elem in elems:
    tree.add(elem) #逐个加入树的节点

    print ('队列实现层次遍历:')
    tree.level_queue(tree.root)

    print (' 递归实现先序遍历:')
    tree.front_digui(tree.root)
    print (' 递归实现中序遍历:')
    tree.middle_digui(tree.root)
    print (' 递归实现后序遍历:')
    tree.later_digui(tree.root)

    print (' 堆栈实现先序遍历:')
    tree.front_stack(tree.root)
    print (' 堆栈实现中序遍历:')
    tree.middle_stack(tree.root)
    print (' 堆栈实现后序遍历:')
    tree.later_stack(tree.root)

    3.用python实现冒泡排序

    好久没看数据结构,这么简单还是忘了......

    array = [1,2,3,6,5,4]

    for i in range(len(array)-1):
        for j in range(len(array)-1-i):
        if array[j] > array[j + 1]:
            array[j+1], array[j] = array[j], array[j+1]
    print(array)


    4.restful风格

     这个确实不知道,大致差了一下restful风格的特点如下

    1.资源

    所谓"资源",就是网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的实在。资源总要通过某种载体反应其内容,文本可以用txt格式表现,也可以用HTML格式、XML格式表现,甚至可以采用二进制格式;图片可以用JPG格式表现,也可以用PNG格式表现;JSON是现在最常用的资源表示格式。

    结合我的开发实践,我对资源和数据理解如下:

    资源是以json(或其他Representation)为载体的、面向用户的一组数据集,资源对信息的表达倾向于概念模型中的数据:

    • 资源总是以某种Representation为载体显示的,即序列化的信息
    • 常用的Representation是json(推荐)或者xml(不推荐)等
    • Represntation 是REST架构的表现层

    相对而言,数据(尤其是数据库)是一种更加抽象的、对计算机更高效和友好的数据表现形式,更多的存在于逻辑模型中

    资源和数据关系如下:

    resource vs data

    2 统一接口

    RESTful架构风格规定,数据的元操作,即CRUD(create, read, update和delete,即数据的增删查改)操作,分别对应于HTTP方法:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源,这样就统一了数据操作的接口,仅通过HTTP方法,就可以完成对数据的所有增删查改工作。

    即:

    • GET(SELECT):从服务器取出资源(一项或多项)。
    • POST(CREATE):在服务器新建一个资源。
    • PUT(UPDATE):在服务器更新资源(客户端提供完整资源数据)。
    • PATCH(UPDATE):在服务器更新资源(客户端提供需要修改的资源数据)。
    • DELETE(DELETE):从服务器删除资源。

    3 URI

    可以用一个URI(统一资源定位符)指向资源,即每个URI都对应一个特定的资源。要获取这个资源,访问它的URI就可以,因此URI就成了每一个资源的地址或识别符。

    一般的,每个资源至少有一个URI与之对应,最典型的URI即URL。

    4 无状态

    所谓无状态的,即所有的资源,都可以通过URI定位,而且这个定位与其他资源无关,也不会因为其他资源的变化而改变。有状态和无状态的区别,举个简单的例子说明一下。如查询员工的工资,如果查询工资是需要登录系统,进入查询工资的页面,执行相关操作后,获取工资的多少,则这种情况是有状态的,因为查询工资的每一步操作都依赖于前一步操作,只要前置操作不成功,后续操作就无法执行;如果输入一个url即可得到指定员工的工资,则这种情况是无状态的,因为获取工资不依赖于其他资源或状态,且这种情况下,员工工资是一个资源,由一个url与之对应,可以通过HTTP中的GET方法得到资源,这是典型的RESTful风格。

    state

    stateless

    5.http协议

    我理解的应该是简述一下http协议吧

    HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。

    HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。

    HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的规范化工作正在进行之中,而且HTTP-NG(Next Generation of HTTP)的建议已经提出。

    HTTP协议工作于客户端-服务端架构为上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。Web服务器根据接收到的请求后,向客户端发送响应信息。

    http协议的特点:

    1、简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。

    2、灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。

    3.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。

    4.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
    5.支持B/S及C/S模式。

  • 相关阅读:
    【販売管理】「クレジットメモとデビットメモ」
    COALESCE [NULL でない最初の式を返す」
    【EXCEL】CONCAT(複数の文字列の連結)
    文字列内の検索 FIND
    テーブルコントロールTable Controls: スクロールを伴う場合の例
    SAP ABAP プログラム 選択画面定義 基本命令
    【転載】表示レイアウト実装方法
    php在linux中执行外部命令
    openldap+php-ldap操作
    MAC Ruby版本需要升级至2.2.2以上
  • 原文地址:https://www.cnblogs.com/xyxpython/p/7208940.html
Copyright © 2011-2022 走看看