字节跳动一面(凉凉)9月21

一.简介

我本着去广撒网的态度海投简历,由于年少心急,久等等不到面试通知,鬼使神差地投了字节,没想到简历被看上了,于是就有今下午长达一小时的面试。

二.面试题目

面试岗位是字节的python后端开发岗的实习。除去自我介绍

1.python是传值还是传引用

第一题掉坑里了,答得传引用。实际上两个都有,对不可变对象,在赋值时候是传值,两者指向的都是同一个内存地址;对可变对象,在赋值时是传引用,相当于开辟了一个新的内存地址。

https://www.jb51.net/article/127667.htm

2.解释一下python的GC

GC是垃圾回收机制,设立GC是为了防止内存泄漏(程序中动态分配的内存由于某种原因无法释放,造成内存的浪费,一直泄漏就导致内存溢出)。

GC分三个:引用计数,标记-清除和分代回收。

引用计数:python里万物皆对象,对象的核心是结构体PyObject,内部的一个ob_refcnt就是作为引用计数的一个计数器,当一个对象有新的引用,计数器就会增加,引用它的对象被删除,计数器会减少,当引用计数为0,对象默认会被回收。

标记-清除:顾名思义,首先标记对象(垃圾检测)再垃圾回收。为了解决循环引用(两个对象之间相互引用)问题而引入,从CGROOT出发,标记所有可达对象,不可达就删除。

分代回收:以空间换时间的技术,核心思想是对象存在时间越长,越不肯是垃圾,越少去回收。

方法是将回收对象分四个代,每个代是一个链表,代内进行标记-清除,时间和存活时间成正比。每代的threadsold值表示可容纳对象的个数,触发高代的回收,低代也会回收(0代为高代,依次类推)

3.怎么理解python里的不可变对象

不可变对象指的是不能在原对象上修改,必须创建新对象来保存修改后数据,如int,str,tuple

可变对象可以在原对象上进行修改,如dict,list,set

4.HTTP的报文结构

请求报文:请求行,请求头,空体,请求数据。请求行包括(请求方法+url(不包括域名)+HTTP版本)

例:GET /search?hl=zh-CN&source=hp&q=domety&aq=f&oq= HTTP/1.1    

响应报文:状态行,响应头,空行,响应体。状态行包括(协议版本+状态码+原因短语)

例:POST /search HTTP/1.1  

5.HTTP的常见请求,状态码

常见请求:GET,POST,PUT,DELETE

GET:从给定的url从给定的服务器中检索信息。get可缓存,不安全。

POST:将数据发送到服务器以创建或更新资源。由于post永远不会被缓存,且对数据长度没有限制,因此无法从浏览器历史记录中查到post请求。

PUT:用于将数据发送给服务器以创建或更新资源。可以用上传的内容替换目标资源中所有当前内容

DELETE:用来删除指定资源,会删除url给出的目标资源的所有当前内容。

状态码:常见:200(OK 客户端请求成功),204(No Content请求响应成功但无内容),301(Moved Permanetly 资源永久移除),302(Found 已找到),401(Unauthorized 客户端无权限),403(Forbidden 请求被服务器拒绝),404(Not Found 未找到),405(Method Not Allowed 表明服务端不支持该request方法),408(Request Time Out 请求超时),500(Internal Server Error 内部服务器错误)

6.MySQL的索引,索引的数据结构以及为什么采用这种数据结构

索引是存储引擎用来快速查找记录的一种数据结构

索引分类:聚簇型索引和非聚簇型索引。

MySQL索引结构:B+树

为什么说B+树比B树更适合数据库索引?
1、 B+树的磁盘读写代价更低:B+树的内部节点并没有指向关键字具体信息的指针,因此其内部节点相对B树更小,如果把所有同一内部节点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多,一次性读入内存的需要查找的关键字也就越多,相对IO读写次数就降低了。

2、B+树的查询效率更加稳定:由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。

3、由于B+树的数据都存储在叶子结点中,分支结点均为索引,方便扫库,只需要扫一遍叶子结点即可,但是B树因为其分支结点同样存储着数据,我们要找到具体的数据,需要进行一次中序遍历按序来扫,所以B+树更加适合在区间查询的情况,所以通常B+树用于数据库索引。

7.讲讲项目里登陆验证是如何实现的

由于用户需要登陆才能查看个人相关界面,诸如订单页,购物车页等。这些页面如果用户没有登陆都会跳转到登陆页面,所以直接单独写了个装饰器

from django.http import HttpResponseRedirect

def login(func):
    def login_fun(request, *args, **kwargs):

        if request.session.has_key('user_id'):
            # 如果登陆成功继续执行原函数
            return func(request, *args, **kwargs)
        else:
            print('请登录')
            red = HttpResponseRedirect('/user/login/') # 没有登陆就跳转到登陆界面
            red.set_cookie('url', request.get_full_path()) # 获取当前url路径存入cookie,防止路径被更改,cookie需要加密
            return red
    return login_fun

8.给你一个数组,里面的元素都是整数,如何将数组里面所有元素奇数在前,偶数在后,写出思路和代码

面试当时想到了利用双指针,两个指针front和end,分别从数组的第一个元素和数组的最后一个元素开始扫描,当遇到front指向偶数,end指向奇数,就交换,一直到front>end停止。当时没有写出代码

后来想想思路,中间少了个判断:如果front指向偶数,end也指向偶数怎么办?所以要保证"front指到偶数且end指向奇数就交换",就要加条件:front遇到奇数就后移,遇到偶数就停下;end遇到偶数就前移,遇到奇数就停下。

int sort(int n,int num[]){ //将数组中的奇数放前面,偶数放后面 	
	int x; //用于交换的临时变量
	int i = 0; // 从左到右扫描数组的指针 
	int j = n-1; //从右到左扫描数组的指针 
	scanf("%d",&n);
	for(i=0;i<n;i++){
		scanf("%d",num[i]);
	}
	
	while(i>j){ //从两边向中间扫描直至相遇 
		//左指针逢奇数就向后走 
		while(num[i]%2==1){
			i++;
		}
		//右指针逢偶数就前移 
		while(num[j]%2==0){
			j--;
		}
		//当遇到左偶右奇且前指针所指向的下标小于右指针下标情况时 
		if(num[i]%2==0 && num[j]%2==1 && i<j){
			x = num[i];
			num[i] = num[j];
			num[j] = x; 
		} 
		 
	}
	return num[n];	
	
} 

9.日常问的问题和读的什么书

推荐Mysql必知必会,高性能MySQL,图解算法,流畅的python

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值