-
Интервюта за работа, "whiteboard interviews"
- Анализиране на проблем
- Разработване на решение
- Извличане на тестови сценарии
- Тестване на решението
- Оценка на решението
-
Придобиване на разбиране за това как са имплементирани готовите структури в езика, които използваме ежедневно. Така можем да оценим:
- каква е тяхната очаквана производителност?
- как скалират при нарастване на данните?
-
Развиване на способност за оценка на сложността на даден алгоритъм. Възможност за разграничаване на бързи и бавни решения на даден проблем.
- Google Maps
- Internet
- Google, търсачки
- ДНК
- В платформата HackerRank.
- Няколко задачи на домашно.
- Предварително зададени тестови.
- Автоматично оценяване на решения.
- Неограничен брой опити за предаване на решение.
- Получавате точки от най-високия резултат, получен от някое решение.
- Дори решението да не покрива 100% от тестовете, получавате точките за тестовете, които покривате.
- Автоматичните тестове не могат да се виждат преди да е приключило домашното.
- Възможност за собствено тестване преди предаване.
Различните грешки при изпълнение на автоматичен тест:
- Wrong Answer - Логическа грешка в алгоритъма.
- Runtime error - Синтактична грешка в кода, възникване на изключение.
- Terminated due to timeout - Бавен, неподходящ алгоритъм.
- Memory limit - Изчерпване на паметта.
- Abort called - Грешка от ниско ниво (C++ препълване на стека).
Immutable обектите не позволяват промяна след създаването си. Python използва нова променлива при възникване на промяна с immutable обект.
n = 1
print(n) # 1
print("Id of the object:", id(n)) # 2076829352176
n += 2
print(n) # 3
print("Id of the object:", id(n)) # 2076829352240
Числата, низовете и кортежите (tuples) са immutable обекти.
t = 1, 2, 3
print(t) # (1, 2, 3)
print("Id of the object:", id(t)) # 2076910038656
t += 4, 5
print(t) # (1, 2, 3, 4, 5)
print("Id of the object:", id(t)) # 2076931006016
s = "abc"
print(s) # abc
print("Id of the object:", id(s)) # 2076834978160
s += "xyz"
print(s) # abcxyz
print("Id of the object:", id(s)) # 2076910065392
Mutable обектите позволяват промяна след създаването си. Python не използва нова променлива при възникване на промяна в mutable обект.
arr = [1, 2, 3]
print(arr) # [1, 2, 3]
print("Id of the object:", id(arr)) # 2076931496320
arr += [4, 5]
print(arr) # [1, 2, 3, 4, 5]
print("Id of the object:", id(arr)) # 2076931496320
Списъци, речници, множества (sets) са mutable обекти.
D = {6: 'Saturday', 7: 'Sunday'}
print(D) # {6: 'Saturday', 7: 'Sunday'}
print("Id of the object:", id(D)) # 2076931815552
D[7] = 'Воскресенье'
print(D) # {6: 'Saturday', 7: 'Воскресенье'}
print("Id of the object:", id(D)) # 2076931815552
A = {1, 1, 2, 3}
print(A) # {1, 2, 3}
print("Id of the object:", id(A)) # 2076910498784
A |= {1, 3, 4}
print(A) # {1, 2, 3, 4}
print("Id of the object:", id(A)) # 2076910498784
Промени по Immutable обекти не могат да бъдат запазени, тъй като се създава нова променлива. Промени извършени по Mutable обекти в функция се запазват, дори след напускане на функцията.
Подаване на число като аргумент на функция:
n = 1
print(n, id(n)) # 1 2076829352176
def f(n):
n += 1
print(n, id(n)) # 2 2076829352208
f(n)
print(n, id(n)) # 1 2076829352176
Подаване на масив като аргумент на функция:
arr = [1, 2, 3]
print(arr, id(arr)) # [1, 2, 3] 2076931627264
def func(arr):
arr.append(4)
print(arr, id(arr)) # [1, 2, 3, 4] 2076931627264
func(arr)
print(arr, id(arr)) # [1, 2, 3, 4] 2076931627264
Подаване на низ като аргумент на функция:
s = 'abc'
print(s, id(s)) # abc 2076834978160
def func(s):
s += 'xyz'
print(s, id(s)) # abcxyz 2076909883568
func(s)
print(s, id(s)) # abc 2076834978160
От Python 3.0+ не съществува типът long. Всяко цяло число се представя чрез int класа.
a = 4
print(a) # 4
print(type(a)) # <class 'int'>
b = 2 ** 1024
print(b) # 179769313486231... (309 digits)
print(type(b))
Големината в байтове за обекти от тип int започва от 28 байта. С увеличаване на големината на число, Python заделя все повече памет за да го съхрани.
import sys
a = 4
print(sys.getsizeof(a)) # 28
b = 2 ** 1024
print(sys.getsizeof(b)) # 124
Това се случва автоматично до прехвърляне на лимита за големина на променлива - 9223372036854775807 байта, ~9,223,372 TB (за 64 битова машина). По-вероятно е изчерпването на паметта на машината, на която се изпълнява кода.
print(sys.maxsize) # 9223372036854775807
from math import log10
c = (2 ** 1024) ** 100
print(log10(c)) # 30825.471555991677 (the digits of c)
print(sys.getsizeof(c)) # 13680 bytes, ~0.01368 MB
Компактен и бърз начин да създадем масив.
arr = [i for i in range(10) if i % 2 == 0]
print(arr) # [0, 2, 4, 6, 8]
Постига се същият ефект като използването на for-цикъл.
arr = []
for i in range(10):
if i % 2 == 0:
arr.append(i)
print(arr) # [0, 2, 4, 6, 8]
List comprehension-а се оказва до 30% по-бърз. Това е така, защото се интерпретира до C-код. Интепретаторът го превежда до поредица команди на езика C, които се изпълняват много по-ефективно от чист Python код.
List comprehension-a поддържа else-клауза:
arr = [i ** 2 if i % 2 == 0 else -(i ** 2) for i in range(10)]
print(arr) # [0, -1, 4, -9, 16, -25, 36, -49, 64, -81]
Позволя използването и на вложени цикли.
arr = [(i, j) for i in range(3) for j in 'XY']
print(arr) # [(0, 'X'), (0, 'Y'), (1, 'X'), (1, 'Y'), (2, 'X'), (2, 'Y')]
- механизъм, който не позволява изпълняването на две нишки код паралелно.
- предотвратява race conditions и гарантира thread safety.
- паралелизмът може да се постигне чрез multiprocessing.
- някои външни библиотеки като Numpy могат да използват повече от едно ядро.
Всички снипети са налични в тетрадката.
Решения на задачите: тук