面試題彙總(一)

1.有一個整數列表,對於每一個鍵值,計算除它本身之外的其餘的數的乘積,編寫一個函數,get_product_at_index(),輸入一個整數數組並返回一個乘積列表。例如,給你:[1, 7, 3, 4],你將得到返回:[84, 13, 28, 21],由於[7* 3 *4, 1 * 3 * 4, 1 * 7 * 4, 1 * 7 * 3]

# 不使用除法
def get_product_at_index(nums):
   output = []
   out = 1
   for i in range(len(nums)):
       if i == 0:
           output.append(1)
       else:
           out = out * nums[i-1]
           output.append(out)
   middle = 1
   for i in range(len(nums)-1, -1, -1):
       output[i] = output[i] * middle
       middle = middle * nums[i]
   return output

# 使用除法
def abc(nums):
   a = 1
   for i in nums:
       a*=i
   output = [int(a/i) for i in nums]
   return output

2.假如你知道明天久其公司的股票狀況,股票的價格經過一個整數數組提供,表示的是每一個時間段的股價。請編寫一個程序,計算當只進行一次買入和賣出股票操做,可以得到最大利益。

例如:

stork_price = [10, 7, 5, 8, 11, 9]

get_max_profit(stork_price)

你將得到返回:6

由於你在5元的時候買入,在11元的時候賣出

注意,你必須先買入以後才能賣出。並且你不能再同一時間買入賣出操做

def maxProfit(prices):
   if not prices:
       return 0
   len_prices = len(prices)
   buy1, sell1, buy2, sell2 = -prices[0], 0, -prices[0], 0
   

   for i in range(1, len_prices):
       buy1 = max(buy1, -prices[i])
       sell1 = max(sell1, buy1 + prices[i])
       buy2 = max(buy2, sell1 - prices[i])
       sell2 = max(sell2, buy2 + prices[i])
   return sell2

3.假設存在個已知列表aDict,由整數映射組成,編寫一個函數,返回一個KeyList,List中的Key在aDict中映射Value爲惟一值。返回的List應按遞增順序排序。

例如aDict = {

1 : 'a',

2 : 'a',

3 : 'c'

}

uniqueValues(aDict) = [3]

 

def a(dict):
   result = []
   for key in dict.keys():
       result.append(key)
       result.append(dict[key])
   return result

 

4.使用遞歸,實現符合如下規範的功能:

max_val((5, [1, 2], [[1, 3, 2, 4], 1])) return 5

max_val([5, [1, 2], [[1],[9]]]) return 9

def max_value(ls, rs):
   for l in ls:
       if type(l) == list:
           rs = max_value(l, rs)
           continue
       if l > rs:
           rs = l
   return rs

# 調用
max_value((5, [1, 2], [[1, 3, 2, 4], 1]), 0)

 

5.手寫冒泡排序

a = [1, 34432, 54, 6, 56, 54, 7, 65, 7, 58, 76, 8, 67, 8, 35, 32, 5432, 4, 32, 432, 0]
for i in range(len(a) - 1):
   flag = 0
   for j in range(len(a) - 1 - i):
       flag = 1
       if a[j] > a[j + 1]:
           a[j], a[j + 1] = a[j + 1], a[j]
   if flag == 0:
       break

 

6.寫出代碼的輸出結果

def f1(a):
   a = 1
def f2(a):
   a = [10]
def f3(a):
   a.append(2)
aa = 0
f1(aa)
print(aa)   # 輸出結果爲:0
bb = [1]
f2(bb)
print(bb)   # 輸出結果爲:[1]
cc = [1]
f3(cc)
print(cc)   # 輸出結果爲:[1,2]

七、寫出代碼的輸出結果

alist = [1, 2, 3, ['a', 'b']]
b = alist
alist[3].append('c')
print(alist) #輸出結果爲:[1, 2, 3, ['a', 'b', 'c']]
print(b)     #輸出結果爲:[1, 2, 3, ['a', 'b', 'c']]

八、寫出代碼的輸出結果

import copy

alist = [1, 2, 3, ['a', 'b']]
c = copy.copy(alist)
alist.append(4)
alist[3].append('c')
print(c)   #輸出結果爲:[1, 2, 3, ['a', 'b', 'c']]
print(alist)    #輸出結果爲:[1, 2, 3, ['a', 'b', 'c'], 4]

九、寫出代碼的輸出結果

import copy

alist = [1, 2, 3, ['a', 'b', 'c']]
c = copy.deepcopy(alist)
alist.append(4)
alist[3].append('d')
print(c) #輸出結果爲:[1, 2, 3, ['a', 'b', 'c']]
print(alist)     #輸出結果爲:[1, 2, 3, ['a', 'b', 'c', 'd'], 4]

十、*arg和**dwarg做爲參數的區別

# 在python中,這兩個是python中的可變參數,*arg表示任意多個無名參數,類型爲tuple,**kwargs表示關鍵字參數,爲dict

十一、filter、map、reduce函數的做用,每一個舉一例

filter(function, sequence):對sequence中的item依次執行function(item),將執行結果爲True的item組成一個List/String/Tuple(取決於sequence的類型)。 filter(function or None, sequence) -> list, tuple, or string:入參爲函數和列表/元組/字符串,返回值爲item列表/元組/字符串。 map(function, sequence) :對sequence中的item依次執行function(item),將執行結果function(item)組成一個List返回。 map(function, sequence[, sequence, ...]) -> list:入參是爲函數和列表/元組/字符串,返回值爲function(item)列表。 reduce(function, sequence, starting_value):對sequence中的item順序迭代調用function,若是有starting_value,還能夠做爲初始值調用。function接收的參數個數只能爲2,先把sequence中第一個值和第二個值當參數傳給function,再把function的返回值和第三個值當參數傳給function,而後只返回一個結果。 reduce(function, sequence[, initial]) -> value:入參是爲函數和列表/元組/字符串和初始值,返回值爲數值。 前端

#2.filter用法:返回執行結果爲TRUE的入參(入參是列表字符元組)
print filter(lambda x:x*x-4,range(10))
#結果:[0, 1, 3, 4, 5, 6, 7, 8, 9]

#3.map的用法:對列表入參依次執行函數。入參爲列表,有多少個列表,就應該有多少個入參。
print map(lambda x:x*x-4,range(10))
#結果:[-4, -3, 0, 5, 12, 21, 32, 45, 60, 77]
print map(lambda x,y:x*y-4,range(3),[8,9,10])
#結果:[-4, 5, 16]

#4.reduce用法:先把sequence中第一個值和第二個值當參數傳給function,再把function的返回值和第三個值當參數傳給fuction,最終返回一個結果值
#接收的入參個數只能爲2
print reduce(lambda x,y:x*y-4,range(4))
#結果:-40
#計算0到100的和
print reduce(lambda x,y:x+y, range(101))
#結果:5050
print reduce(lambda x,y:x+y, range(101),100)
#結果:5150

十二、寫一個父類和子類,有初始化函數,有銷燬函數,有子類繼承父類的函數便可

class Pre:
   def __init__(self,name,sex):
   self.name = name
   self.sex = sex
       
   def __del__(self):
       print('對象:{}已被刪除'.format(self.name))

       
class Stu(Pre):
   def __init__(self, name, sex, age):
       super().__init__(name, sex)
       self.age = age

1三、班級表class(id,name),學生表student(id,name,classid,score)

(1) 寫SQL語句建立表python

CREATE TABLE `class` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`classid` int(11) NOT NULL,
`score` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
KEY `keys()` (`classid`),
CONSTRAINT `keys()` FOREIGN KEY (`classid`) REFERENCES `class` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
);

(2)寫SQL語句,插入2個班級,2個學生redis

INSERT INTO class VALUES(1, 1001),(2, 1002);
INSERT INTO student VALUES(1, '張三', 1, 100),(2, "李四", 2, 99);

(3)寫SQL語句:分組查詢每一個班級的平均分,並按降序排序,輸出,班級編號,班級名,平均分數數據庫

SELECT class.id,class.name,avg(student.score) FROM class,student WHERE class.id=student.classid GROUP BY class.id;

###Sqlalchemy的ORM相關django

(1) 用Sqlalchemy寫出多條件查詢(A=1 and B=2) or (C=3)代碼編程

from django.db.models import Q

Sqlalchemy.objects.filter((Q(A=1) & Q(B=2)) | Q(C=3))

(2)用Sqlalchemy寫出table1和table2表關聯, 而且有條件table1.A=table2.B代碼後端

models.ForeignKey(table2, models.CASCADE)

 

 

1四、@classmethod,@staticmethod有什麼區別?什麼狀況下用@classmethod,什麼狀況下用@staticmethod?

  • @staticmethod不須要表示自身對象的self和自身類的cls參數,就跟使用函數同樣。數組

  • @classmethod也不須要self參數,但第一個參數須要是表示自身類的cls參數。緩存

 

1五、dict的items() 方法與iteritems() 方法的不一樣?

字典的items方法做用:是能夠將字典中的全部項,以列表方式返回。由於字典是無序的,因此用items方法返回字典的全部項,也是沒有順序的。網絡

字典的iteritems方法做用:與items方法相比做用大體相同,只是它的返回值不是列表,而是一個迭代器。

(1)在Python2.x中,iteritems() 用於返回自己字典列表操做後的迭代器【Returns an iterator on all items(key/value pairs) 】,不佔用額外的內存。

(2)在Python 3.x 裏面,iteritems()方法已經廢除了。在3.x裏用 items()替換iteritems() ,能夠用於 for 來循環遍歷。

 

1六、什麼是lambda函數?下面這段代碼輸出是什麼?

nums = range(2,20)
for i in nums:
   nums = filter(lambda x:x==i or x % i, nums)
print(nums)
# <filter object at 0x00000163EA643EB8>
(一)什麼是lambda函數:

Python支持一種有趣的語法,它容許你快速定義單行的最小函數。這些叫作lambda的函數是從Lisp中借用來的,能夠被用在任何須要函數的地方。

lambda 函數是一個能夠接收任意多個參數(包括可選參數)而且返回單個表達式值的匿名函數。 (注意:lambda 函數不能包含命令,它們所包含的表達式也不能超過一個)

(二)使用lambda函數的好處:

一、lambda函數比較輕便,即用即扔,很適合須要完成某一項簡單功能,可是這個簡單的功能只在此一處使用,連名字都很隨意的狀況下;

二、lambda是匿名函數,通常用來給filter,map,reduce這樣的函數式編程服務;(具體使用請參考本人的上一篇博文:http://www.javashuo.com/article/p-ycwwpapr-bt.html

三、做爲回調函數,能夠傳遞給某些應用,好比消息處理等。

 

思考題:

一、對於多線程編程的理解,對於CPU密集型和IO密集型怎樣使用多線程,說說線程池,線程鎖的用法。

一)、對於多線程編程的理解:

  1. 簡單區分程序、進程和線程

程序是指一段靜態的代碼

進程是指正在執行的程序,將靜態的代碼運行起來

線程是指正在執行程序的小單元


  1. 理解進程

理解線程以前,先簡單理解一下進程。進程的三大特徵:獨立性、動態性、併發性。

獨立性:指進程是系統中獨立存在的實體,擁有獨立的資源(eg:私有的地址空間)。

動態性:這是相對於程序而言的,程序是一段靜態的代碼,而進程是活動的,擁有本身的生命週期。

併發性:多個進程能夠在單個處理器上併發執行,互不影響。

仍是上面那栗子,這個班級就是一個進程,他是一個總體,他擁有本身的教室,有本身的班級名字,這裏能夠體現出獨立性。這個班級的全體人員按照的任務清單幹活,直至把教室打掃乾淨(即完成任務),這裏能夠體現出動態性。併發性呢,首先這個班級不僅有一個,還有好多其餘的班級,他們也能夠打掃他們本身的教室,互不影響。


  1. 理解線程

線程是進程的執行單元,在程序中,線程是獨立的、併發的執行流。

線程的特色:

  1. 每一個線程有本身的堆棧,本身程序計數器,本身的局部變量,這裏體現了線程的獨立性。

  2. 相同父進程下的全部線程共享進程獨立的內存單元(eg:代碼段、進程的共有數據),爲此能夠實現線程間的相互通訊。

  3. 多個線程之間也能夠併發執行,互不影響。


  1. 多線程 VS 多進程

  2. 線程之間能夠共享內存,而進程之間不能夠。

  3. 系統建立線程代價比較小,並且多線程是實現多任務併發比多進程的效率更高。

二)、CPU密集型和IO密集型怎樣使用多線程

一個計算爲主的程序(專業一點稱爲CPU密集型程序)。多線程跑的時候,能夠充分利用起全部的cpu核心,好比說4個核心的cpu,開4個線程的時候,能夠同時跑4個線程的運算任務,此時是最大效率。

可是若是線程遠遠超出cpu核心數量 反而會使得任務效率降低,由於頻繁的切換線程也是要消耗時間的。

所以對於cpu密集型的任務來講,線程數等於cpu數是最好的了。

若是是一個磁盤或網絡爲主的程序(IO密集型)。一個線程處在IO等待的時候,另外一個線程還能夠在CPU裏面跑,有時候CPU閒着沒事幹,全部的線程都在等着IO,這時候他們就是同時的了,而單線程的話此時仍是在一個一個等待的。咱們都知道IO的速度比起CPU來是慢到使人髮指的。因此開多線程,比方說多線程網絡傳輸,多線程往不一樣的目錄寫文件,等等。

此時 線程數等於IO任務數是最佳的。

三)、線程池,線程鎖的用法

 

二、若是有一個訂單系統,包含訂單信息,商品信息,價格信息,而且要維護一些狀態,在設計系統時,你會提供哪些建議?

 

三、秒殺程序設計,大併發下如何不會超賣?

一):加入隊列,集中處理

二):

前端頁面靜態化,禁止重複提交

  • 頁面靜態化:將前端能夠靜態的資源靜態化。

  • 禁止重複提交:秒殺開始以後,能夠對用戶點擊後響應前按鈕置灰。

後端可拓展,緩存,限流,削峯,異步處理

  • 可拓展:服務的可擴展,能夠水平添加機器將用戶請求分擔到不一樣的機器上去。數據庫可擴展,支持分庫分表,對於用戶的請求,映射到不一樣的數據庫,減小單臺數據庫的壓力。

  • 內存緩存:參加秒殺系統的商品是事先可知的,能夠將參加秒殺的商品信息事先緩存到redis等緩存系統中,這樣能夠大大的提升系統的吞吐量,減小關係型數據庫的讀寫壓力。

  • 限流: 一單秒殺開始,實際秒殺成功的用戶只是庫存的數量,在庫存沒有以後,將前端的秒殺入口關閉。

  • 削峯:數據庫削峯。對於秒殺系統瞬時會有大量用戶涌入,因此在搶購一開始會有很高的瞬間峯值。對於關係型數據庫而言,這個是致命的,是壓垮系統很重要的緣由,因此如何把瞬間的高流量變成一段時間平穩的流量也是設計秒殺系統很重要的思路。實現削峯的經常使用的方法有利用緩存和消息中間件等技術。

  • 異步處理:秒殺系統是一個高併發系統,採用異步處理模式能夠極大地提升系統併發量,其實異步處理就是削峯的一種實現方式。

相關文章
相關標籤/搜索