├── .gitignore ├── .gitmodules ├── License.md ├── README.md ├── archetypes └── default.md ├── config.toml ├── content ├── about.md └── posts │ ├── anime_is_it_waste_of_time.md │ ├── design_thinking.md │ ├── immutability.md │ ├── little_known_things_in_python.md │ ├── model_view_controller.md │ ├── oo_python.md │ ├── python_ftw.md │ ├── python_yield_generators.md │ ├── some_really_cool_python_packages.md │ ├── stack_overflow.md │ └── system_design_interviews_cheatsheet.md ├── netlify.toml ├── resources └── _gen │ └── assets │ └── scss │ └── scss │ ├── main.scss_39fa5fe97be74115670eace810202c56.content │ └── main.scss_39fa5fe97be74115670eace810202c56.json └── static ├── android-chrome-192x192.png ├── android-chrome-512x512.png ├── apple-touch-icon.png ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon.ico ├── images ├── anime │ ├── death_note.jpg │ ├── fullmetal_alchemist.jpg │ ├── naruto.jpg │ └── one_piece.jpg ├── display.jpg ├── mvc_schematic.png ├── overflow │ ├── image1.png │ ├── image2.png │ ├── image3.png │ ├── image4.png │ └── image5.png └── xkcd_python.png └── site.webmanifest /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | public/ 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "themes/hello-friend-ng"] 2 | path = themes/hello-friend-ng 3 | url = https://github.com/naniroot/hugo-theme-hello-friend-ng.git 4 | -------------------------------------------------------------------------------- /License.md: -------------------------------------------------------------------------------- 1 | This work is licensed under the Creative Commons Attribution-NonCommercial 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Naniz Hugo Site 2 | Personal website and blog using hugo framework. Where the magic happens. 3 | 4 | [![Netlify Status](https://api.netlify.com/api/v1/badges/eabdf887-9316-42ee-a10a-835fa8244ecf/deploy-status)](https://app.netlify.com/sites/brave-pike-146256/deploys) 5 | 6 | ### Add theme as submodule using the command 7 | `git submodule add https://github.com/naniroot/hugo-theme-hello-friend-ng.git themes/hello-friend-ng` 8 | 9 | ### Got my favicon using the following link 10 | [Favicon Generator](https://favicon.io/favicon-generator/?t=N&ff=Frijole&fs=70&fc=%23FFFFFF&b=circle&bc=%23252627) -------------------------------------------------------------------------------- /archetypes/default.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "{{ replace .Name "-" " " | title }}" 3 | date: {{ .Date }} 4 | draft: true 5 | --- 6 | 7 | -------------------------------------------------------------------------------- /config.toml: -------------------------------------------------------------------------------- 1 | baseURL = "https://naniz.co" 2 | title = "Nani Ravikumar" 3 | 4 | DefaultContentLanguage = "en" 5 | 6 | theme="hello-friend-ng" 7 | 8 | PygmentsCodeFences = true 9 | PygmentsStyle = "monokai" 10 | 11 | archetypeDir = "archetypes" 12 | contentDir = "content" 13 | dataDir = "data" 14 | layoutDir = "layouts" 15 | publishDir = "public" 16 | 17 | 18 | buildDrafts = false 19 | buildFuture = false 20 | buildExpored = false 21 | canonifyURLs = false 22 | 23 | enableRobotsTXT = true 24 | enableGitInfo = false 25 | enableEmoji = true 26 | enableMissingTranslationPlaceholders = false 27 | disableRSS = true 28 | disableSitemap = false 29 | disable404 = false 30 | disableHugoGeneratorInject = false 31 | 32 | [permalinks] 33 | posts = "/posts/:year/:month/:title/" 34 | 35 | [author] 36 | name = "Narayana Ravikumar" 37 | 38 | [blackfriday] 39 | hrefTargetBlank = true 40 | 41 | [taxonomies] 42 | tag = "tags" 43 | category = "categories" 44 | 45 | [params] 46 | dateform = "Jan 2, 2006" 47 | dateformShort = "Jan 2" 48 | dateformNum = "2006-01-02" 49 | dateformNumTime = "2006-01-02 15:04 -0700" 50 | 51 | homeSubtitle = "Where the magic happens" 52 | 53 | # Set disableReadOtherPosts to true in order to hide the links to other posts. 54 | disableReadOtherPosts = false 55 | 56 | # Metadata mostly used in document's head 57 | description = "Homepage and blog by Narayana Ravikumar" 58 | keywords = "homepage, blog, economics, finance, development, programming, journal" 59 | images = [""] 60 | 61 | # Toggle this option need to rebuild SCSS, requires extended version of Hugo 62 | justifyContent = false # Set "text-align: justify" to .content. 63 | 64 | # Directory name of your blog content (default is `content/posts`) 65 | contentTypeName = "posts" 66 | 67 | # Default theme "light" or "dark" 68 | defaultTheme = "dark" 69 | themeColor = "#252627" 70 | 71 | # Colors for favicons 72 | [params.favicon.color] 73 | mask = "#252627" 74 | msapplication = "#252627" 75 | theme = "#252627" 76 | 77 | # Social icons 78 | [[params.social]] 79 | name = "instagram" 80 | url = "https://www.instagram.com/ninja_in_pyjama_217/" 81 | 82 | [[params.social]] 83 | name = "linkedin" 84 | url = "https://www.linkedin.com/in/narayanaravikumar/" 85 | 86 | [[params.social]] 87 | name = "twitter" 88 | url = "https://twitter.com/naniroot" 89 | 90 | [[params.social]] 91 | name = "github" 92 | url = "https://github.com/naniroot" 93 | 94 | [[params.social]] 95 | name = "facebook" 96 | url = "https://www.facebook.com/nanikumar17" 97 | 98 | [languages] 99 | [languages.en] 100 | title = 'Nani Ravikumar' 101 | subtitle = "Where the magic happens" 102 | keywords = "" 103 | copyright = 'CC BY-NC 4.0' 104 | readOtherPosts = "Read other posts" 105 | 106 | [languages.en.params.logo] 107 | logoText = "/home/Naniz" 108 | logoHomeLink = "/" 109 | logoCursorDisabled = true 110 | # or 111 | # 112 | # path = "/img/your-example-logo.svg" 113 | # alt = "Your example logo alt text" 114 | 115 | # And you can even create generic menu 116 | [menu] 117 | [[menu.main]] 118 | identifier = "about" 119 | name = "About" 120 | url = "about/" 121 | [[menu.main]] 122 | identifier = "posts" 123 | name = "Posts" 124 | url = "posts/" -------------------------------------------------------------------------------- /content/about.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "About" 3 | date: 2020-02-02T13:51:14-08:00 4 | draft: false 5 | --- 6 | {{< image src="/images/display.jpg" alt="Narayana Ravikumar" position="center">}} 7 | 8 | My name is Narayana Ravikumar, people call me _Nani_. I've been professionally deploying to production for over five years. I am currently coding at [Twilio](https://www.twilio.com/) and have previously worked at [AWS](https://aws.amazon.com/) and [Commvault Systems](https://www.commvault.com/). This blog is where I share my thoughts, opinions and mild insomnia. 9 | 10 | Now, [would you kindly](https://bioshock.fandom.com/wiki/Would_You_Kindly) take a look around and let me know what you think. You can reach me on my socials or email me at __narayanark17__ [at] __gmail__ [dot] __com__ 11 | -------------------------------------------------------------------------------- /content/posts/anime_is_it_waste_of_time.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Anime, waste of time?" 3 | date: 2013-07-07T18:01:44-07:00 4 | draft: false 5 | images: 6 | tags: [anime, learning, success, time] 7 | --- 8 | 9 | I have watched a lot of anime from my childhood and continue to watch them even now. I read a lot of manga as well. If you don’t know what a manga is, [this](http://en.wikipedia.org/wiki/Manga) can help you. I clearly remember dragon ballz being my first anime immediately followed by naruto and a bunch of others. Now, I have watched so many, I have lost count. 10 | 11 | But every time I started watching an anime my mom and dad used to start to say one of the following statements 12 | 13 | 1. They are such a waste of time 14 | 2. Are you still a kid to watch cartoons? 15 | 3. If you stop watching them you might do better at exams 16 | 4. If you watch anymore the world will stop spinning 17 | 5. MY feet hurt because YOU are watching anime etc etc 18 | 19 | Every time they said that I would always feel guilty and wonder, am I really wasting my time? Will I screw up my exams? What is the mystical connection between earth’s core and me watching anime? I always want to learn and keep learning from everything I do. So there was one important question I asked myself, what am I learning from all this? 20 | 21 | I did not get an answer immediately, but later I was glad I watched it. There are important life lessons to learn from anime apart from the entertainment factor. Anime has better life lessons. 22 | 23 | ## One Piece - You have to rely on your ‘nakama’ ( team) you can’t do everything alone 24 | 25 | {{< image src="/images/anime/one_piece.jpg" alt="One Piece" position="center">}} 26 | 27 | One piece is about a group of ‘nakama’ sailing the seas in search of their own dreams. Luffy (protoganist) puts them together and they have awesome adventures. Luffy being the strongest has not a lot to worry about, but he can’t do everything on his own and always takes the help of his ‘nakama’ and they have great adventures. 28 | 29 | ### What I learnt? 30 | 31 | 1. It is very important to have a team who have great dreams and ambitions. 32 | 2. Everybody should work together to achieve each other’s dream. 33 | 3. No matter what, you never, “NEVER” give up your ‘nakama’ 34 | 4. You take every blow to your chest and never show your back to anything 35 | 5. Finally, one should not worry too much, trust instincts and always make time to dance with friends. 36 | 37 | ## Naruto - you never go back on your words 38 | 39 | {{< image src="/images/anime/naruto.jpg" alt="Naruto" position="center">}} 40 | 41 | Naruto is about a young Ninja who was condemned by the society. But instead of hating them back, he chooses to train hard and become the best in the world. He believes that if he is the best then everybody would recognise him. If you determine yourself to do something, you should never go back on it. The determination he has, man, his eyes says it all. 42 | 43 | ### What I learnt? 44 | 45 | 1. Convert everybody’s oppression into the power of achieving something 46 | 2. Never go back on your words. Whether its something you promised someone else or yourself. 47 | 3. There is great power in everybody that only has to be channelled out to achieve what you need. 48 | 49 | ## Death Note - Too much power is bad and there is no shortcut to solving problems 50 | 51 | {{< image src="/images/anime/death_note.jpg" alt="Death Note" position="center">}} 52 | 53 | Death Note is one hell of an anime. Kira (protoganist) finds a mystical note book which kills anyone whose name is written in it. He uses this book to clean the world of all criminals by killing every criminal in all prisons across the world. Initially this decreases crime rates but eventually everything falls into chaos. Kira eventually falls in a lot of trouble and finds out that it was all for nothing. 54 | 55 | ### What I learnt? 56 | 57 | 1. There is no shortcuts to success. 58 | 2. There is always someone more intelligent than you, and one should not be too proud. 59 | 3. Sometimes its better to work with your competition to achieve something. 60 | 4. Too much power only corrupts you. 61 | 62 | ## Fullmetal Alchemist - Never practice taboo and handicap doesn’t matter 63 | 64 | {{< image src="/images/anime/fullmetal_alchemist.jpg" alt="Fullmetal Alchemist" position="center">}} 65 | 66 | This anime is about a young alchemist who performs the ultimate taboo of alchemy. 67 | 68 | ### What I learnt? 69 | 70 | 1. Law exist for a reason, bend them, but never break them. Anarchy is the only thing that will follow if you break them. 71 | 2. Sometimes the answer to your problems lies within you, it will spark if you keep trying and never give up. 72 | 3. Always take care of your family and support each other no matter what. 73 | 4. Finally, sometimes the greatest problems have the simplest solutions. 74 | 75 | I have watched a lot more anime and every single one has some life value to provide. I might have learnt, partly adopted most of my life values from anime, than any self-help, do-this-to-achieve-success books I have read (apart from what my Dad taught me, of course). The only takeaway I wanted to share from this article was that as long you are learning and improving yourself in some way, there is nothing stopping you from doing what you love. Anything can be the spark that morally and spiritually drives you to do something. I wish to achieve something great one day, hope these life lessons will come handy. 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /content/posts/design_thinking.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Design Thinking" 3 | date: 2013-06-29T13:51:31-08:00 4 | draft: false 5 | tags: [design thinking, software development] 6 | --- 7 | > Revitilizing very old post from the past. Of course, my thinking has changed since then, but its always fun to open a time capsule. 8 | 9 | I am writing this article at 1am with droopy eyes and cannot guarantee the quality of this article. But anyway, I came across design thinking in a special topic class I took in Spring 2013 called “visual interfaces for mobile design”. This was a really different and interesting class. It had zero importance to exams and by-hearting stuff. It was an very open-ended and fun class. It was a class where the amount of things you learnt totally depended on how much you wanted to learn. The prof had a given a bunch of topics to do a reading assignment on and one of them was, as the heading says “Design Thinking”. 10 | 11 | For this I had to read a paper (that unusually can’t be linked here) and watch [this really good TED video](http://www.ted.com/talks/tim_brown_urges_designers_to_think_big.html). I have not completely understood what design thinking actually means or how to develop it. But I feel it is very important for all us to learn what design thinking is if we want to grow as an effective developer and really enjoy what we do. 12 | 13 | All of us coders can really think well in terms of logic and get things done. We would have practised it really well and can solve any given task if we put our head into it. Suppose you want to add a new feature to your product, you get the specification required and us developers will sit and code it up. This might give you the feature right now, but how good is it? how well will it blend with the product as a whole? will it form a great experience to the users of the product? There are only a few people who can think at a very holistic level and generate a great design. 14 | 15 | Design thinking is an integrative thinking that combines opposing ideas and opposing constraints to create new solutions. This means we have to combine three things to obtain a proper design. 16 | - Desirability - What humans need? 17 | - Feasibility - Is it technically possible? 18 | - Viability - Does it have economic viability? 19 | A product that combines these three things will be highly marketable, useful and generate good revenue to the designer. 20 | 21 | I have not been able to completely understand how “design thinking” should be adopted but it has definitely changed my perspective. I know that all great visionaries in technology had great “design thinking” and that is what made them what they were. I strongly feel that is order to grow and do great things we have to fully adopt “design thinking” in everything we do. 22 | 23 | What I want to convey via this article is that design thinking, when adopted by software developers can have a huge impact on the software developed. While developing software, developers, usually give importance to whether the software is easily extendible, manageable, scalable, can it be easily tested, is it fast enough etc along with that it should be such a way that they think about the design as well i.e. the above three bullet points. 24 | 25 | What I feel is thinking with respect to the above three points with everything you do, small or big, it actually makes you not only develop a product but an experience, you don’t simply develop a new feature but a solution. I feel, this will add great value and help in the growth of any product. -------------------------------------------------------------------------------- /content/posts/immutability.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Immutability" 3 | date: 2013-05-24T20:32:27-07:00 4 | draft: false 5 | images: 6 | tags: [immutability, coding, language, programming, optimization] 7 | --- 8 | > Revitilizing very old post from the past. Of course, my thinking has changed since then, but its always fun to open a time capsule. 9 | 10 | Immutability is a very important concept that most of us might not know explicitly. An immutable object cannot be modified after it has been created. Consider the following simple python code. 11 | 12 | ```python 13 | var = "hello" 14 | print var 15 | var[1] = "6" 16 | print var 17 | ``` 18 | gives an error 19 | ```python 20 | TypeError: 'str' object does not support item assignment 21 | ``` 22 | That is because __String__ is an immutable object it cannot be modified after creation. 23 | 24 | ### Why are immutable objects needed? 25 | 1. A compiler/ interpreter does this to reduce complications and work efficiently. 26 | 2. Immutable objects are inherently thread-safe 27 | 3. Simpler to understand 28 | 4. Offer good security 29 | 30 | ### Thats great, but why should I know about immutable object? 31 | 32 | Consider an example where you want to print “My name is Nani and I have 3 friends Ravi, Sita and Ram” where “Nani”, “Ravi”, “Sita” and “Ram” are in different String objects. So, in python your code will look something like this 33 | 34 | ```python 35 | a = “Nani” 36 | b = “Ravi” 37 | c = “Sita” 38 | d = “Ram” 39 | output = “My name is “+a+” and I have 3 friends “+b+”, ”+c+” and ”+d 40 | print output 41 | ``` 42 | 43 | This gets the job done. But its a slow operation, as strings are immutable objects, output string cannot be created in place. A new memory location has to be created and the string copied to the new location from the previous place and a new string created. 44 | 45 | But instead, if you write the code like this 46 | ```python 47 | a = “Nani” 48 | b = “Ravi” 49 | c = “Sita” 50 | d = “Ram” 51 | output = “My name is %s and I have 3 friends %s, %s and %s”%(a, b, c, d) 52 | print output 53 | ``` 54 | The compiler pre-allocates the space for the string as it expects things to be added and thus the operation is __in place__ and much faster. The time difference between the first method and second is not much, but when coding huge applications every small bit of execution time you save amounts to a lot. 55 | 56 | ### What if I want to modify strings? what should I do? 57 | 58 | In Java, you can use StringBuffers which are mutable and hence can be modified. In python you can keep a list of characters and only combine them when needed like 59 | 60 | ```python 61 | >>> var = list(“hello”) 62 | >>>var 63 | [ ‘h’ , ‘e’ , ‘l’ , ‘l’ , ‘o’ ] 64 | >>>var[0] = ‘z’ 65 | >>>var 66 | [ ‘z’ , ‘e’ , ‘l’ , ‘l’ , ‘o’ ] 67 | >>>””.join(var) 68 | ‘hello’ 69 | ``` 70 | 71 | The basic structure of an mutable object would be an constructor that initializes the data and getter and setter functions. An immutable object on the other hand would only have the constructor and getter function. 72 | 73 | ```java 74 | class Mutable{ 75 | private int value; 76 | 77 | public Mutable(int value) { 78 | this.value = value; 79 | } 80 | 81 | //getter and setter for value 82 | } 83 | ``` 84 | ```java 85 | class Immutable { 86 | private final int value; 87 | 88 | public Immutable(int value) { 89 | this.value = value; 90 | } 91 | 92 | //only getter 93 | } 94 | ``` 95 | 96 | ### What are some example immutable objects? 97 | 1. In python numbers, booleans, strings, tuples, frozensets are immutable. 98 | 2. In Java all primitive wrappers like Integer, Long, Short, Double, Float, Character, Byte, Boolean are all immutable 99 | 3. Java variable prepended with “final” keyword. 100 | 101 | ### References: 102 | 103 | - http://en.wikipedia.org/wiki/Immutable_object 104 | - http://stackoverflow.com/questions/1228299/change-one-character-in-a-string-in-python 105 | - http://stackoverflow.com/questions/4658453/difference-between-mutable-objects-and-immutable-objects 106 | 107 | 108 | -------------------------------------------------------------------------------- /content/posts/little_known_things_in_python.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Some Little Known Things in Python" 3 | date: 2013-08-08T22:25:25-07:00 4 | draft: false 5 | images: 6 | tags: [python, quirks, coding, optimization] 7 | --- 8 | > Revitilizing very old post from the past. Of course, my thinking has changed since then, but its always fun to open a time capsule. 9 | 10 | This article came after a long hiatus from the previous one and I would like to apologize for that. I came across many neat things in python recently and am somewhat finding it overwhelming to master them all. Every time I learn something, there is something else that completely baffles me or at least intrigues me to solve problems differently. 11 | 12 | Hopefully writing this article would be comforting of some sort. In this article I am going to document some little capabilities available to python users to help them in their day to day adventures. 13 | 14 | ## Lambda Function 15 | 16 | Python gives a powerful utility to create anonymous functions to users. These functions are not bound to any name (i.e they are anonymous, as already stated, by me :-P). Lambda functions are apparently well built into the core of python structure and support all possible optimizations and provide good performance. Let me just start off with an example so that my rants make sense. 17 | 18 | ```python 19 | >>g = lambda x: x**2 # lambda function returns 20 | >> 21 | >>print g(8) 22 | 64 23 | >>print g(5) 24 | 25 25 | ``` 26 | 27 | You can assign lambda functions to variables and they act as function names, but not exactly. Note that lambda function does not use any return statements explicitly, but they always have some expression that they return. 28 | 29 | Suppose you want a function that increments the number given to it by 2, 5 and 7. You can have 3 different functions or pass different arguments to them or you can use lambda functions like this 30 | 31 | ```python 32 | >>def incrementor(n): return lambda x: x+n 33 | 34 | >>two_incrementor = incrementor(2) 35 | >>five_incrementor = incrementor(5) 36 | >>seven_incrementor = incrementor(7) 37 | >>print two_incrementor(10), five_incrementor(14), seven_incrementor(11) 38 | 12 19 18 39 | 40 | #you can also chain them up like 41 | >>print incrementor(11)(55) 42 | 66 43 | ``` 44 | 45 | One other really cool application I want to point out is that lambda functions can be used to operate as path joiners for different folders you might need in some configuration files. 46 | 47 | ```python 48 | >>import os 49 | >>def joiner(basefolder): return lambda x: os.path.join(basefolder, x) 50 | >>root_joiner = joiner(“/”) 51 | >>home_joiner = joiner(“/home/usr”) 52 | >>print root_joiner(“etc”) 53 | /etc 54 | >>print home_joiner(“code/sites”) 55 | /home/usr/code/sites 56 | >>print home_joiner(“../..”) 57 | /home/usr/../.. 58 | ``` 59 | 60 | Lambda functions would work awesome with python map, filter and reduce operations. But more on that later. 61 | 62 | ## Dictionaries as arguments to functions 63 | 64 | In python you can send a dictionary to a function for all the arguments. This feature is like that gizmo you read about, you know it's expensive, you may not use it as well, but you want it. Now, after knowing about this feature, I may not use it, but I want it in all programming languages I use. 65 | 66 | Its amazing how well it is integrated in python. You can now organize your code even better and not worry about the order of the arguments at all and also write really good tests as well. Here is how you do it. 67 | 68 | ```python 69 | def TVfunction( channel, volume): 70 | print “The channel is %s and the volume is %s”%channel, volume 71 | 72 | argDict = {“channel”: “23”, “volume”: “45”} 73 | TVfunction(**argDict) 74 | ``` 75 | 76 | The double '\*\*' does the trick of taking your dictionary and passing the required arguments to the function, in the order required. 77 | 78 | ## Arbitrarily Long Argument List 79 | 80 | There are many instances where you don’t have a specific number of arguments that you want to pass to a function. So, you can send any number of arguments to a function by adding '\*' before an argument at the end of the argument list. The arguments will be given to you as a tuple and can be zero or more in number. There can be zero or more arguments before the variable argument, but none after. An example would be 81 | 82 | If you want to send filenames to a function that deletes it, but you don’t know how many files you have to delete at the time of programming you can do something like this. 83 | 84 | ```python 85 | def delete_files(basefolder, *arg): 86 | for t in arg: 87 | fullFile = os.path.join(basefolder, t) 88 | os.remove(fullFile) 89 | 90 | #You can call the function using 91 | 92 | delete_files(“file1.txt”, “file2.txt”) 93 | delete_files(“file.txt”) 94 | delete_files() 95 | ``` 96 | 97 | Notice the '\*' before __arg__ in the first line, but not in the second line. The '\*' just informs python that the argument should be considered as a tuple containing variable number of arguments. 98 | 99 | ## Doc comments 100 | 101 | It's very surprising how long it took me to discover this functionality when I first started to learn python. All these while I thought that python only came with single line comments using the ‘#’ symbol. I found it hard to comment a large number of lines until I learned of the doc string. This feature is mainly, let me stress, “mainly” used for documentation of various parts of code. But like most things doc strings can be used to comment sections of code that you don’t want to use right now but don’t want to delete as well. Doc string does not require you to indent your text to work. 102 | 103 | Example of using doc string for documenting. 104 | 105 | ```python 106 | def some_function(a, b, c): 107 | ‘‘‘ 108 | This is some function, that does something, takes some variables and returns something else. 109 | ‘‘‘ 110 | pass 111 | ``` 112 | It can also be used as. 113 | 114 | ```python 115 | def config_server(): 116 | ‘‘‘ 117 | # Local config 118 | server = localhost 119 | port = 1024 120 | user = blah 121 | ‘‘‘ 122 | #Deployment config 123 | server = something.com 124 | port = 80 125 | user = admin 126 | ``` 127 | Doc strings are three continuous single quotes and everyone should use them as much as possible. 128 | -------------------------------------------------------------------------------- /content/posts/model_view_controller.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Model View Controller (MVC) Best Practices" 3 | date: 2019-03-23T09:22:53-07:00 4 | draft: false 5 | images: 6 | tags: [model, view, controller, mvc, programming, abstract] 7 | --- 8 | 9 | If you have ever taken a web framework tutorial like Django, Rails etc, one of the first things they introduce is the Model-View-Controller pattern. This is a very simple pattern to organize your web service and distribute responsibilities for readability and maintainability. Since many (Service Oriented Architecture) SOA frameworks have similar constructs, this pattern is used widely. Exceptions of this pattern could be found in dequeuer services that generally don't have endpoints to be invoked. 10 | 11 | Here is a simple diagram explaining this pattern, 12 | 13 | {{< image src="/images/mvc_schematic.png" alt="MVC Schematic" position="center">}} 14 | 15 | What I want to do with this article is to cement the objectives of each component- model, view and controller. I am hoping at the end of this you will understand why we structure our services in a certain way and its advantages. 16 | 17 | ### Main Objectives of each component 18 | 19 | - **Model** - Reusability 20 | - **View** - Readability 21 | - **Controller** - Testability 22 | 23 | ## MODEL 24 | 25 | ### Main objective - Reusability 26 | 27 | Model could be DAOs or service clients. It is the component that goes out of the service to get the data needed to do your business logic. It should be designed such that it can be passed and used by any controller without any modification. 28 | 29 | The model 30 | 31 | - Should have its own **execution context or thread pool**. 32 | - Should specify number of connections to use, so that the total connections opened is constant across all controllers. 33 | - Should set the timeout to the requests. 34 | - Should be **agnostic** to the controller using it. 35 | - Should handle exceptions, 400s, timeouts etc and wrap them in service exceptions to pass back to the controllers. 36 | - Should **NOT have any business logic** as reusability is key. 37 | 38 | It's important to wrap client exceptions with service exceptions, this allows controller to not worry about the zillion different exceptions throw by clients and can only worry about the business logic. Once the model is written and has tests, they can be reused among any number of controllers. 39 | 40 | ## VIEW 41 | 42 | ### Main Objective - Readability 43 | 44 | View also known as resource or REST specification is the contract that the service has with its clients. It specifies what input it takes and what output it generates for the input. Your clients don't care how you achieve the response, they only care about the response. Keep this as simple as possible, so clients know exactly what to expect when integrating with your service. 45 | 46 | The view 47 | 48 | - Should have its own **execution context or thread pool**. 49 | - Should specify the input (path param, query param, request type like GET, POST etc). 50 | - Should do validation on input and throw 400s. 51 | - Should NOT handle things like timeout for the clients. 52 | - Should **NOT have any business logic**. 53 | - It's recommended to specify the view using open API specification [https://swagger.io/specification/](https://swagger.io/specification/) so that code generation tools can be used to generate the client and tests. 54 | 55 | ## Controller 56 | 57 | ### Main Objective - Testability 58 | 59 | Controller (sometimes known as manager) is the core of your service. It is responsible for the business logic and should do all the heavy lifting. It will take the validated input from the resource/view, call the necessary model/client to get additional data, process it and send the output back to the view. 60 | 61 | General rule of thumb, a resource can call any controller, a controller can call any of the model/clients to get its data. This makes it easy to test as all the business logic will reside in the controller. 62 | 63 | Since controller does the business logic in your service, it should be covered by comprehensive tests. 64 | 65 | - Should have its own **execution context or thread pool**. 66 | - Should have extensive tests to cover your business logic. 67 | - Should depend only on MODELs to get its data, not other controllers. 68 | - Should NOT call other controllers 69 | - Can have until/helper classes to [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) up the processing but those util classes should not use any of the model/client classes or respond back to views. 70 | 71 | 72 | -------------------------------------------------------------------------------- /content/posts/oo_python.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Object Oriented Python?" 3 | date: 2013-09-05T22:24:46-07:00 4 | draft: false 5 | images: 6 | tags: [python, programming, coding, object oriented, object, oo] 7 | --- 8 | > Revitilizing very old post from the past. Of course, my thinking has changed since then, but its always fun to open a time capsule. 9 | 10 | Most people I have spoken to about python do not believe in the object oriented capabilities of python. Python does not require you to always create a class like Java or C# but it is a language that is inherently object oriented. Like we say that __“In linux everything is a file”__, in python, everything is an object. Even functions are objects and can be passed around. Python decorators pass around functions but that will be an article for some other time (and maybe a long one as well). 11 | 12 | Python follows the __Verb__ method of programming. The two ways of programming verb vs noun are explained beautifully [here](http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html). But let me brief it for you. Suppose the task is to take out the garbage, in the verb world you would do something like this 13 | ``` 14 | Get up from the couch. 15 | Take the garbage out. 16 | Dump it. 17 | Walk back. 18 | Plop back on the couch. 19 | ``` 20 | 21 | But in certain programming world __"Noun is god"__ and you would have to do something like this. 22 | ```java 23 | cv = CouchWakeUpper( Person) 24 | gw = GarbageWalker(cv) 25 | dc = Dumper(gw) 26 | wb = WalkBacker(dc) 27 | Plopper(person) 28 | ``` 29 | or something similar, but you get the point. This is explained much better in the above link. I am only trying to convey the point. The noun form is not bad, but it takes away the natural flow a program should have which are verbs. Python, according to its BDL (Benevolent Dictator for Life) Guido Van Rossum gives maximum importance to readability of code and hence follows the __Verb__ way of programming and that is what I enjoy the most about python. 30 | 31 | ## Objects 32 | I can’t start an article called __OO Python__ and not tell about some technical aspects of python’s object oriented programming. An example class in python would be 33 | 34 | ```python 35 | class Admin: 36 | def display(self, name): 37 | print “Hello, World” + str(name) 38 | ``` 39 | 40 | here the class __Admin__ has a member function called ‘display’ which takes an argument ‘self’ that corresponds to ‘this’ keyword in Java and is used to access all member variables. ‘self’ has to be passed to all functions in a class that are going to be called outside the class i.e by the objects. 41 | 42 | A way to call the above class would be 43 | 44 | ```python 45 | >>>objA = Admin() 46 | >>>objA.display(“ Nani”) 47 | ``` 48 | 49 | The output would be 50 | ``` 51 | Hello, World Nani 52 | ``` 53 | The call can be visualized as 54 | ```python 55 | Admin.display(objA, “Nani”) 56 | ``` 57 | hence the ‘self’ keyword is used. 58 | 59 | ## Inheritance 60 | 61 | Python supports simple inheritance and also multiple inheritance. The class definition with simple inheritance would look something like this. 62 | 63 | ```python 64 | class DerivedClass( BaseClassName): 65 | → member functions 66 | → member variables 67 | ``` 68 | 69 | Python also supports multiple inheritance and the syntax is 70 | ```python 71 | class DeriveClass( Base1, Base2, Base3): 72 | → member functions 73 | → member variables 74 | ``` 75 | member variables are created and called using 76 | 77 | ```python 78 | self.variableName = something 79 | ``` 80 | 81 | -------------------------------------------------------------------------------- /content/posts/python_ftw.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Python FTW" 3 | date: 2013-09-27T14:15:17-08:00 4 | draft: false 5 | images: 6 | tags: [python, coding, xkcd, winning] 7 | --- 8 | > Revitilizing very old post from the past. Of course, my thinking has changed since then, but its always fun to open a time capsule. 9 | 10 | Python has made programming an absolute pleasure for me. I simply love working with python. The ease of programming and the importance given to programming logic than programming syntax is an absolute delight. I first learnt python from this [tutorial](http://cscircles.cemc.uwaterloo.ca/). It is an awesome website to learn python. Whenever someone asks me how is it to code in python? I always remember this xkcd comic. 11 | 12 | [{{< image src="/images/xkcd_python.png" alt="XKCD Python" position="center">}}](https://xkcd.com/353/) 13 | 14 | According to me, python is the only true “high” level language. I mean, if programming languages took part in “Game of Thrones” python would be on Iron Throne the whole time and nobody would dare rebel against it. 15 | 16 | Some common observations is the syntax. There is absolutely very minimal syntax, there are no semicolons, parentheses or type declaration. There are tons and tons of packages that you can import and work on. Writing modules in python is also a cakewalk, you find modules for a lot of things. You want to access UNC path there is a module, want to SFTP, there is a module, want to write a web crawler, there is a module. There are gateway and wrapper modules that supports almost all common programming languages and frameworks. 17 | 18 | Even web programming is amazing. _Django_ and _Pylons_ are the major ones and they take web programming to a whole new level. These web frameworks take a lot of work out of your hands and provide you with a lot of power to simply code and build beautiful things. 19 | 20 | Some examples of why python is a breeze to learn and use. 21 | 22 | This is a common one. 23 | 24 | ### How do you print “hello, world” in python? 25 | 26 | ```python 27 | print “Hello, World” 28 | ``` 29 | ### How do you print “hello, world” in say, Java? 30 | 31 | ```java 32 | class Foo{ 33 | public static void main(String v[ ]){ 34 | System.out.println(“Hello, World”); 35 | } 36 | } 37 | ``` 38 | 39 | ## List Comprehension 40 | ### Generate a list of even integers below 100 41 | 42 | One line, 43 | ```python 44 | A = [ x for x in range(2, 100, 2)] 45 | ``` 46 | List of square numbers below 10. 47 | No problem, just one line again 48 | ```python 49 | A = [x * x for x in range(10) ] 50 | ``` 51 | Suppose you have a huge list of numbers and you want to extract only even numbers from it. 52 | ```python 53 | A = [ 3, 5, 34, 77, 88, 500, 145, 338, ….., 1538] 54 | even = [ x for x in A if x%2 == 0] 55 | ``` 56 | Yes, just two lines and the first line does not even count. 57 | 58 | Python eases coding a lot. But **do not** get carried away, other programming languages are also very good . And depending on the requirement you should choose the appropriate language. **Compiled languages are faster and should always be considered before interpreted language.** If speed of execution is important then compiled languages, if speed of development is essential then python is an amazing choice. 59 | 60 | Another good example of python would be the ‘with’ statement. 61 | 62 | As a programmer you tend to forget sometimes. You will have open files, sockets or other connections and forget to close it. The python ‘with’ statement comes in handy. One can simply say 63 | 64 | ```python 65 | with open(“filename”, “r”) as fs: 66 | do something 67 | ``` 68 | and python takes care of closing the file on its own after the scope is over. In a broader sense, what ‘with’ statement is trying to accomplish is this 69 | ``` 70 | set things up 71 | try: 72 | do something 73 | finally: 74 | tear things down 75 | ``` 76 | Here the `tear things down` will be taken care by `with` statement and does not require explicit `finally` block. 77 | 78 | Python is very powerful, I am sure there are plenty of other examples out there that show the power of python. I highly recommend development in python. 79 | 80 | 81 | -------------------------------------------------------------------------------- /content/posts/python_yield_generators.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Python Yield Command and Generators" 3 | date: 2013-07-14T14:15:17-08:00 4 | draft: false 5 | images: 6 | tags: [python, coding, yeild, generators] 7 | --- 8 | > Revitilizing very old post from the past. Of course, my thinking has changed since then, but its always fun to open a time capsule. 9 | 10 | I come across a lot gems in python. Some are easy to understand, some require more time. The best way to understand them is by working with them and using them in programs. To make the understanding stronger you can write about them. I wanted to understand the yield command better so here it is. 11 | 12 | To understand **yield** you first have to understand generators, iterables and their differences. 13 | 14 | ## Iterables 15 | 16 | Iterables are a pretty well-known concept. They are anything that you can iterate on. Remember in basic C you first had to find the length and then run a ‘for’ loop to find all the elements. Iterables you can directly iterate and access all the elements. They are now available in most languages. Since we are talking about python, here are few examples 17 | 18 | ```python 19 | A = [1, 2, 3] 20 | for ch in A: 21 | print ch 22 | ``` 23 | ``` 24 | output: 25 | 1 26 | 2 27 | 3 28 | ``` 29 | ```python 30 | B = [ x*x for x in range(3)] 31 | for x in B: 32 | print x 33 | ``` 34 | ``` 35 | output: 36 | 0 37 | 1 38 | 4 39 | ``` 40 | ## Generators 41 | 42 | Now, these are not that well-known. Generators are also iterables, they can also be iterated on, but only once. They do not store every value in memory. An example in python would be 43 | 44 | ```python 45 | A = (x*x for x in range(3)) 46 | for x in A: 47 | print x 48 | ``` 49 | ``` 50 | Output: 51 | 0 52 | 1 53 | 4 54 | ``` 55 | Notice that the generator uses ‘(‘ compared to a ‘[‘ of a iterable. Now, why would somebody need a generator? 56 | Whenever there is a function call in python, the function continues to execute until it finds a return statement or an exception or end of context where the default “return None” is executed. After this, all the context of the function is lost like the local variables, stack frames etc. This is good for many scenarios but sometimes you would need the function to retain context, like, for example you want to 57 | 58 | ### Print squares of the first 1000 numbers 59 | 60 | You can do this in 3 ways. 61 | 62 | 1. Create a list of numbers and print from there. 63 | 64 | ```python 65 | def square_print(): 66 | return [x*x for x in range(1000)] 67 | ``` 68 | This creates a huge list takes a lot of memory, and its too cumbersome to move an entire list around if you need the squares at different point of time. 69 | 70 | Remember in python the integer object has no limit and can take values as much as the memory you have. 71 | 72 | 2. You could use global variable and send the square only when you need it. That would work right? 73 | ```python 74 | glbV = 0 75 | 76 | def square_print(): 77 | global glbV 78 | if glbV <1000: 79 | square = glbV*glbV 80 | glbV+=1 81 | return square 82 | ``` 83 | This would work, will not take much memory as well. But again global variables are ugly, they act weird when threads are used and also the variable would not be protected, security and accidental modification is a concern. So, what should we do? 84 | 85 | 3. We use generators. 86 | Generators were created to ease programmers woes. They very cleanly take care of situation exactly like this. This is where the **yield** command also comes into picture. A generator for the above application would look something like this. 87 | ```python 88 | def square_print(): 89 | num = 0 90 | while num<1000: 91 | yield num*num 92 | num = num+1 93 | 94 | generator = square_print() 95 | for x in generator: 96 | print x 97 | ``` 98 | This is a very clean way to program and python automatically takes care of context, it protects accidental modification, provides security to the variable, is thread safe and very neat. Python is fun ain’t it? 99 | 100 | ## References 101 | - http://stackoverflow.com/questions/231767/the-python-yield-keyword-explained 102 | - http://wiki.python.org/moin/Generators 103 | - http://www.jeffknupp.com/blog/2013/04/07/improve-your-python-yield-and-generators-explained/ -------------------------------------------------------------------------------- /content/posts/some_really_cool_python_packages.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Some Really Cool Python Packages" 3 | date: 2013-06-25T19:54:15-07:00 4 | draft: false 5 | images: 6 | tags: [python, packages, mechanize, beautifulsoup, antigravity, pycountry] 7 | --- 8 | > Revitilizing very old post from the past. Of course, my thinking has changed since then, but its always fun to open a time capsule. 9 | 10 | These definitely must be checked out. 11 | 12 | ## Mechanize 13 | 14 | [Mechanize](https://pypi.org/project/mechanize/) is an awesome package. It basically gives you a programmable browser. It takes care of https, cookies and all the forms. It gives you immense power to do a lot of things. 15 | 16 | Imagine you have a browser that fills all the forms for you, submits them and processes the response. Imagine doing it 1000 times or hey, a million times or more depending on the processing power you have. Imagine spamming comments using this, I am not saying that you should, I am only saying you can. But most comments have captcha and limit on comment flooding anyway. 17 | 18 | But this package can help you do some managing if required. It helps you access resources required, have custom filtering, provide custom services etc. Things you can probably do is make a separate archive of your emails, email contacts, code alerts based on constraints etc. The most freakingly awesome thing you can do is write your own web crawler. Crawl through the web, index info, handle loops and maybe finally start your own search engine that kicks google’s ass. 19 | 20 | I am pretty sure [Aaron Swartz](https://en.wikipedia.org/wiki/Aaron_Swartz) used mechanize to download all the copyrighted content provided by MIT and the law documents. I have not fully explored the package but I am currently working on a kickass project that uses mechanize and I plan to write all about it once I am done. 21 | 22 | ## BeautifulSoup 23 | 24 | [BeautifulSoup](https://pypi.org/project/beautifulsoup4/) is one weird name for a python package but it is an amazing package in python to navigate, search, modifying parse trees in html and xml files. BeautifulSoup when combined with mechanize forms a very powerful tool to navigate the DOM structure of an website and perform the required function. 25 | 26 | Have you ever tried to guess how if you post a link to facebook, it tries to find a picture in that website to post along with your link. That is done by something like BeautifulSoup that navigates that link’s html or DOM structure to find the images required. BeautifulSoup wraps around python packages [lxml](https://lxml.de/) and [html5lib](https://pypi.org/project/html5lib/) and gives a very powerful parsing tool I am just starting to explore. 27 | 28 | ## Antigravity 29 | [Antigravity](http://python-history.blogspot.com/2010/06/import-antigravity.html) was a fun package developed based on [this](http://xkcd.com/353/) xkcd comic. I have already shown this comic in my [previous]({{}}). It is really amuzing that engineers develop packages based on likes and whims. But ain’t all packages a result of something like that. 30 | 31 | Antigravity is a package that simply opens up a link to the comic in your default browser and also performs geohashing as given in [this](http://www.xkcd.com/426/) comic. Who knows? maybe you will meet your life partner while geo hashing using antigravity package. 32 | 33 | ## Pycountry 34 | 35 | [Pycountry](https://pypi.org/project/pycountry/) is a very useful package that contains the entire world’s ISO country names, ISO numbers, subdivisions, languages, currencies, script definitions and their translations. If you are writing a global application and want to keep track of your user’s global addresses and languages in a standardised format that is easy for later processing like analytics or customised servicing then PyCountry is your best bet. At least in python. It is very easy to use like any python package with upto date ISO codes. 36 | 37 | I’ll try to find more cool python packages and keep this list updated as and when I find them. 38 | -------------------------------------------------------------------------------- /content/posts/stack_overflow.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Stack Buffer Overflow" 3 | date: 2013-06-03T22:25:39-07:00 4 | draft: false 5 | images: 6 | tags: [security, vulnerability, stack, overflow, buffer] 7 | --- 8 | 9 | > Revitilizing very old post from the past. Of course, my thinking has changed since then, but its always fun to open a time capsule. 10 | 11 | ### What is stack buffer overflow? 12 | 13 | Stack Buffer Overflow is a very neat security vulnerability. I was fortunate enough to learn and work on it during my security course at NC State. It can be defined as an anomaly where a program overwrites the buffer allocated to it and writes into adjacent memory. 14 | 15 | ### How can this be beneficial? 16 | 17 | Well, you can potentially overwrite a return address and make it point to some malicious code. When the system returns to that address it executes the malicious code allowing an adversary to take control of your system. 18 | 19 | ### Why would anyone want to do this? 20 | Money, research, fun, your kung fu master ordered, some celestial being commanded, I am not the one to judge. 21 | 22 | ### How do you do it then? 23 | Well, to understand how to overflow a buffer you must know how the stack works and for that you must know where the stack is located. This is a typical diagram of the system memory layout. 24 | 25 | {{< image src="/images/overflow/image1.png" alt="Memory Layout" position="center">}} 26 | 27 | Stack usually take higher addresses and grow downwards. Yes, the stack grows downwards. Would stack buffer overflow problem be solved if the stacks grow upwards? Hold on, I have not even explained how buffer overflow works. As a matter of fact the stack growing direction does not matter as we will find out soon. 28 | 29 | Every program that calls a function uses a stack. The contents of a stack are logically divided into a stack frame that belongs to a particular function that are monitored by two pointers __ebp__ and __esp__. A function uses a stack to do the following 30 | 1. To store the return address of the caller function. 31 | 2. To pass any parameters to callee function. 32 | 3. Callee uses it to store local variables. 33 | 4. Any flags and state of the registers before the function call. 34 | 35 | Check out this [awesome site](http://www.csee.umbc.edu/~chang/cs313.s02/stack.shtml) to know more on how stack works during a typical function call. In the above enumeration, No. 3 is the one that causes all the trouble. We shall see why. Here is the diagram of a typical stack with everything I have told you so far. 36 | 37 | {{< image src="/images/overflow/image2.png" alt="Typical Stack Layout" position="center">}} 38 | 39 | Now, consider a simple program like 40 | 41 | ```c 42 | void bar(char *str) 43 | { 44 | char c[7]; 45 | strcpy(c, str); 46 | } 47 | 48 | void foo() 49 | { 50 | bar(“wolf”); 51 | } 52 | ``` 53 | The stack frame of the function __bar__ will look something like this 54 | 55 | {{< image src="/images/overflow/image3.png" alt="Stack After Function Call" position="center">}} 56 | 57 | what would happen if I sent, instead of ‘wolf’, a parameter of size greater than 7? __strcpy__ is a function that simply keeps writing into a buffer without bothering about size. Any argument of size greater than 7 will overwrite the return address. 58 | 59 | A potential attacker could send malicious code to the function and it will be happily overwritten onto the stack. So exactly how can an adversary use the stack to gain control of the system? 60 | 61 | All he has to do is overwrite the return address and more data with malicious code. This is important, the return address should be pointing to the overwritten malicious code. Or, another hack you can do is point the return address to a bank deposit function and money will be deposited in your account again and again. Neat eh? Well, it's not that simple. Here is how the stack should look after your attack. 62 | 63 | {{< image src="/images/overflow/image4.png" alt="Layout After Attack" position="center">}} 64 | 65 | Now, the return address points to the stack itself, which will be popped into the __EIP__ register and potentially executing your malicious code. The malicious code is usually shellcode which is used to obtain a new shell to run your commands. 66 | 67 | ### This is cool. But how do you counter such an attack? 68 | 69 | Some basic best practices could be to always code using strncpy instead of strcpy which is not vulnerable to such an attack. But, there is tons of legacy code out there and strcpy is not the only vulnerable function. Other defences against such attack are 70 | 71 | #### 1. ASLR ( Address Space Layout Randomization) 72 | 73 | Here the stack frames are allocated randomly so the return address that needs to be overwritten cannot be guessed easily. But we know that there are limited number of addresses in memory and programmatically we can try everything possible. 74 | 75 | #### 2. ExecShield and StackGuard 76 | 77 | ExecShield marks certain address space as ‘stack space’ and does not allow any code execution in this address space thus making the above buffer overflow futile. 78 | 79 | Stack guard is amazing, it modifies every stack frame to have a canary value like this 80 | 81 | {{< image src="/images/overflow/image5.png" alt="Canary Stack Guard" position="center">}} 82 | 83 | Canary value is a random value that is stored here and also somewhere else, which is verified every time a function returns. This gives very good protection against buffer overflow as it is very difficult to guess the canary value. 84 | 85 | ### So, if we have these protections are we safe against buffer overflow? 86 | 87 | Apparently not. Since other local variables can still be overwritten. What if one of the local variables is a function pointer? you can overwrite it to point to some malicious code and when that function was to be executed, it executes your code instead. It is possible to get such scenarios and CVEs (Common Vulnerabilities and Exposures) are full of them. 88 | 89 | ### One final question. Does stack growing upwards solve this problem? 90 | 91 | No, upwards stack does not solve our problem as explained [here](http://www.quora.com/Systems-Programming/Stacks-that-grow-up-are-a-solution-to-the-stack-buffer-overflow-problem-But-this-design-is-not-widely-adopted-Why). It only shifts the problem, in an upwards stack the frame hijacked would not be the callee as shown above but could be the one whose stack frame is above the one currently called. Thus, most modern architectures continue to make stacks grow downwards. 92 | 93 | ### References 94 | - http://www.cis.syr.edu/~wedu/seed/Labs/Vulnerability/Buffer_Overflow/Buffer_Overflow.pdf 95 | - http://www.csee.umbc.edu/~chang/cs313.s02/stack.shtml 96 | - http://www.quora.com/Systems-Programming/Stacks-that-grow-up-are-a-solution-to-the-stack-buffer-overflow-problem-But-this-design-is-not-widely-adopted-Why 97 | - http://www.phrack.com/issues.html?issue=56&id=5 98 | - http://www.securitytube.net/video/231 99 | -------------------------------------------------------------------------------- /content/posts/system_design_interviews_cheatsheet.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "System Design Algorithm and Interview Cheat Sheet" 3 | date: 2020-12-26T17:58:02-08:00 4 | draft: false 5 | images: 6 | tags: [interviews, system design, coding, algorithms] 7 | --- 8 | 9 | ### References 10 | 1. [Leetcode post](https://leetcode.com/discuss/interview-question/system-design/547669/algorithm-you-should-know-before-system-design/526120) 11 | 2. [Github Source](https://github.com/resumejob/system-design-algorithms) 12 | 13 | ## Steps to System Design Interview 14 | 1. Clarify Requirements 15 | * Ask lots of questions 16 | * Very **important** step 17 | * Spend good amount of time on this step 18 | 2. Adjust scope and state assumptions 19 | * Can limit scope to **simplify** and explain that you will come back to it at a later time 20 | 3. Back of the envelope calculations 21 | * This should set **upper bounds** on the high level design 22 | 4. High Level Design 23 | * Do drawings at this time 24 | * Keep it high level and **explain trade offs** 25 | * There is no one right answer 26 | * Stay in scope but try to leave room for future scale and features 27 | 5. Detailed Design 28 | * Discuss failure scenarios, how redundancy is provided, bottle necks, 29 | * Discuss prevention of issues like **thundering herd**, **hotspots**, **single point of failures** etc 30 | * Focus on **security** as well in this step 31 | 32 | ## Algorithms and their Usage 33 | 34 | ### Bloom filter 35 | A Bloom filter is a data structure designed to tell you, rapidly and memory-efficiently, whether an element is present in a set. 36 | 37 | - [Build a Web Crawler](http://blog.gainlo.co/index.php/2016/06/29/build-web-crawler/) 38 | 39 | ### Consistent Hashing 40 | It is used to evenly divide work among a bunch of resources while giving flexibility for resources to be added or removed. Mostly used in database sharding. 41 | 42 | - [Hash Ring](https://www.acodersjourney.com/system-design-interview-consistent-hashing/) 43 | 44 | ### Geohash / S2 Geometry 45 | Geohash can be used by 1) dating apps to find romantic matches within a particular cell, and to create chat apps.2) Find nearby locations, and identify places of interest, restaurants, shops and accommodation establishments in an area. 3) Geohashers go on global expeditions to meet people and explore new places. 46 | 47 | - [Location-based search results with DynamoDB and Geohash](https://read.acloud.guru/location-based-search-results-with-dynamodb-and-geohash-267727e5d54f) 48 | 49 | ### Leaky bucket / Token bucket 50 | A mechanism to control the amount and the rate of the traffic sent to the network 51 | 52 | - [Everything You Need To Know About API Rate Limiting](https://nordicapis.com/everything-you-need-to-know-about-api-rate-limiting/) 53 | - [How to Design a Scalable Rate Limiting Algorithm](https://konghq.com/blog/how-to-design-a-scalable-rate-limiting-algorithm/) 54 | - [How we built rate limiting capable of scaling to millions of domains](https://blog.cloudflare.com/counting-things-a-lot-of-different-things/) 55 | - [Rate-limiting strategies and techniques](https://cloud.google.com/solutions/rate-limiting-strategies-techniques) 56 | 57 | ### Lossy Counting 58 | The lossy count algorithm is an algorithm to identify elements in a data stream whose frequency count exceeds a user-given threshold. 59 | 60 | - [Fast and Reliable Ranking in Datastore](https://cloud.google.com/datastore/docs/articles/fast-and-reliable-ranking-in-datastore) 61 | - [Frequency Counts over Data Streams](https://www.cse.ust.hk/vldb2002/VLDB2002-proceedings/slides/S10P03slides.pdf) 62 | 63 | ### Operational transformation 64 | Operational transformation (OT) is a technology for supporting a range of collaboration functionalities in advanced collaborative software systems. 65 | 66 | - [How Google docs handle editing collisions](https://stackoverflow.com/a/36366174) 67 | - [Operational Transformation Collaborative editing](https://en.wikipedia.org/wiki/Operational_transformation) 68 | 69 | ### Quadtree / Rtree 70 | - [Spatial Indexing with Quadtrees](https://medium.com/@waleoyediran/spatial-indexing-with-quadtrees-b998ae49336) 71 | - Find nearby interest points 72 | 73 | ### Ray casting 74 | Ray casting is the most basic of many computer graphics rendering algorithms that use the geometric algorithm of ray tracing. Given a point with longitude and latitude, return the Country of the point. 75 | 76 | - [Ray Casting Algorithm](http://philliplemons.com/posts/ray-casting-algorithm) 77 | 78 | ### Reverse index 79 | Reverse Index: a reverse index is an index of keywords which stores records of documents that contain the keywords in the list. 80 | 81 | - [How search engines work: Crawling, Indexing and Ranking](https://moz.com/beginners-guide-to-seo/how-search-engines-operate) 82 | - [Building a complete Tweet index](https://blog.twitter.com/engineering/en_us/a/2014/building-a-complete-tweet-index.html) 83 | 84 | ### Rsync algorithm 85 | The rsync algorithm is a technique for reducing the cost of a file transfer by avoiding the transfer of blocks that are already at the destination. 86 | 87 | - [Streaming File Synchronization](https://dropbox.tech/infrastructure/streaming-file-synchronization) 88 | 89 | ### Trie algorithm 90 | Trie is an efficient information reTrieval data structure. Using Trie, search complexities can be brought to optimal limit (key length) 91 | 92 | - [How to Design an Autocomplete System](https://dzone.com/articles/how-to-design-a-autocomplete-system) 93 | - [prefix matching words (IP Addresses, Phone Numbers)](https://www.geeksforgeeks.org/longest-common-prefix-using-trie/) 94 | - [Auto-complete feature using Trie](https://www.geeksforgeeks.org/auto-complete-feature-using-trie/) 95 | 96 | ### Frugal Streaming 97 | Frugal Streaming uses only one unit of memory per group to compute a quantile for each group 98 | 99 | - Find the nth percentile of the data stream 100 | 101 | ### Count-Min Sketch 102 | Count frequency in a stream of data. Approximate algorithm similar to bloom filter. 103 | 104 | - [Approximate counts with Hashing](https://florian.github.io/count-min-sketch/) 105 | 106 | ### Least Recently Used (LRU) 107 | Very popular eviction algorithm for caches or other resources. 108 | 109 | - [Implementation using doubly linked list and hash map](https://www.geeksforgeeks.org/lru-cache-implementation/) 110 | 111 | ### B-Trees 112 | Self balancing tree used in systems where the contents of the tree cannot completely fit in main memory. The data structure is designed to reduce amount of disk accesses. It is heavily used in MySQL to keep track of indexes. 113 | 114 | - [Intro to B-tree](https://www.geeksforgeeks.org/introduction-of-b-tree-2/) 115 | 116 | ### Merkle Tree 117 | Merkle tree or **hash tree** is a tree in which every leaf node is labelled with the cryptographic hash of a data block, and every non-leaf node is labelled with the cryptographic hash of the labels of its child nodes. Hash trees can be used to verify any kind of data stored, handled and transferred in and between computers. They can help ensure that data blocks received from other peers in a peer-to-peer network are received undamaged and unaltered, and even to check that the other peers do not lie and send fake blocks. 118 | 119 | - Used in Bitcoin implementation 120 | - Apache Cassandra uses Merkle trees to detect inconsistencies between replicas of entire databases. 121 | - [Introduction to Merkle Trees](https://www.geeksforgeeks.org/introduction-to-merkle-tree/) 122 | 123 | ## Honorable Mentions 124 | - [HyperLogLog Algorithm for Cardinality Estimation](https://florian.github.io/count-min-sketch/) 125 | - [Skip list to search a sorted linked list faster than O(n)](https://www.geeksforgeeks.org/skip-list/) 126 | - [Hashed and Hierarchical Timing Wheels: Data Structures for the Efficient Implementation of a Timer Facility](https://blog.acolyer.org/2015/11/23/hashed-and-hierarchical-timing-wheels/) 127 | - [Fenwick Tree](https://www.geeksforgeeks.org/binary-indexed-tree-or-fenwick-tree-2/) 128 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | publish = "public" 3 | command = "hugo --gc --minify" 4 | 5 | [context.production.environment] 6 | HUGO_VERSION = "0.63.2" 7 | HUGO_ENV = "production" 8 | HUGO_ENABLEGITINFO = "false" -------------------------------------------------------------------------------- /resources/_gen/assets/scss/scss/main.scss_39fa5fe97be74115670eace810202c56.content: -------------------------------------------------------------------------------- 1 | ::-webkit-scrollbar{width:8px;height:8px;background:#212020}::-webkit-scrollbar-thumb{background:#888}::-webkit-scrollbar-thumb:hover{background:#dcdcdc}html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-display:auto;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-display:auto;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-display:auto;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}code[class*=language-],pre[class*=language-]{color:#ccc;background:0 0;font-family:Consolas,Monaco,andale mono,ubuntu mono,monospace;font-display:auto;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#2d2d2d}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.comment,.token.block-comment,.token.prolog,.token.doctype,.token.cdata{color:#999}.token.punctuation{color:#ccc}.token.tag,.token.attr-name,.token.namespace,.token.deleted{color:#e2777a}.token.function-name{color:#6196cc}.token.boolean,.token.number,.token.function{color:#f08d49}.token.property,.token.class-name,.token.constant,.token.symbol{color:#f8c555}.token.selector,.token.important,.token.atrule,.token.keyword,.token.builtin{color:#cc99cd}.token.string,.token.char,.token.attr-value,.token.regex,.token.variable{color:#7ec699}.token.operator,.token.entity,.token.url{color:#67cdcc}.token.important,.token.bold{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.inserted{color:green}:root{--phoneWidth: (max-width: 684px);--tabletWidth: (max-width: 900px)}@font-face{font-family:inter ui;font-style:normal;font-display:auto;font-weight:400;src:url(../fonts/Inter-UI-Regular.woff2)format("woff2"),url(../fonts/Inter-UI-Regular.woff)format("woff")}@font-face{font-family:inter ui;font-style:italic;font-display:auto;font-weight:400;src:url(../fonts/Inter-UI-Italic.woff2)format("woff2"),url(../fonts/Inter-UI-Italic.woff)format("woff")}@font-face{font-family:inter ui;font-style:normal;font-display:auto;font-weight:600;src:url(../fonts/Inter-UI-Medium.woff2)format("woff2"),url(../fonts/Inter-UI-Medium.woff)format("woff")}@font-face{font-family:inter ui;font-style:italic;font-display:auto;font-weight:600;src:url(../fonts/Inter-UI-MediumItalic.woff2)format("woff2"),url(../fonts/Inter-UI-MediumItalic.woff)format("woff")}@font-face{font-family:inter ui;font-style:normal;font-display:auto;font-weight:800;src:url(../fonts/Inter-UI-Bold.woff2)format("woff2"),url(../fonts/Inter-UI-Bold.woff)format("woff")}@font-face{font-family:inter ui;font-style:italic;font-display:auto;font-weight:800;src:url(../fonts/Inter-UI-BoldItalic.woff2)format("woff2"),url(../fonts/Inter-UI-BoldItalic.woff)format("woff")}.button-container{display:table;margin-left:auto;margin-right:auto}button,.button,a.button{position:relative;display:flex;align-items:center;justify-content:center;padding:8px 18px;margin-bottom:5px;background:#eaeaea;text-decoration:none;text-align:center;font-weight:500;border-radius:8px;border:1px solid transparent;appearance:none;cursor:pointer;outline:none}.dark-theme button,.dark-theme .button,.dark-theme a.button{background:#3b3d42;color:inherit}button.outline,.button.outline,a.button.outline{background:0 0;border-color:#eaeaea;box-shadow:none;padding:8px 18px}.dark-theme button.outline,.dark-theme .button.outline,.dark-theme a.button.outline{border-color:#3b3d42;color:inherit}button.outline :hover,.button.outline :hover,a.button.outline :hover{transform:none;box-shadow:none}button.primary,.button.primary,a.button.primary{box-shadow:0 4px 6px rgba(50,50,93,.11),0 1px 3px rgba(0,0,0,.08)}button.primary:hover,.button.primary:hover,a.button.primary:hover{box-shadow:0 2px 6px rgba(50,50,93,.21),0 1px 3px rgba(0,0,0,.08)}button.link,.button.link,a.button.link{background:0 0;font-size:1rem}button.small,.button.small,a.button.small{font-size:.8rem}button.wide,.button.wide,a.button.wide{min-width:200px;padding:14px 24px}.code-toolbar{margin-bottom:20px}.code-toolbar .toolbar-item a{position:relative;display:inline-flex;align-items:center;justify-content:center;padding:3px 8px;margin-bottom:5px;background:#eaeaea;text-decoration:none;text-align:center;font-size:13px;font-weight:500;border-radius:8px;border:1px solid transparent;appearance:none;cursor:pointer;outline:none}.dark-theme .code-toolbar .toolbar-item a{background:#3b3d42;color:inherit}.header{background:#fafafa;display:flex;align-items:center;justify-content:center;position:relative;padding:20px}.dark-theme .header{background:#252627}.header__right{display:flex;flex-direction:row;align-items:center}@media(max-width:684px){.header__right{flex-direction:row-reverse}}.header__inner{display:flex;align-items:center;justify-content:space-between;margin:0 auto;width:760px;max-width:100%}.theme-toggle{display:flex;align-items:center;justify-content:center;line-height:1;cursor:pointer}.theme-toggler{fill:currentColor}.unselectable{user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.logo{display:flex;align-items:center;text-decoration:none;font-weight:700;font-display:auto;font-family:monospace,monospace}.logo img{height:44px}.logo__mark{margin-right:5px}.logo__text{font-size:1.125rem}.logo__cursor{display:inline-block;width:10px;height:1rem;background:#fe5186;margin-left:5px;border-radius:1px;animation:cursor 1s infinite}@media(prefers-reduced-motion:reduce){.logo__cursor{animation:none}}@keyframes cursor{0%{opacity:0}50%{opacity:1}100%{opacity:0}}.menu{background:#fafafa;border-right:1px solid;margin-right:18px;z-index:9999}.dark-theme .menu{background:#252627}@media(max-width:684px){.menu{position:absolute;top:50px;right:0;border:none;margin:0;padding:10px}}.menu__inner{display:flex;align-items:center;justify-content:flex-start;max-width:100%;margin:0 auto;padding:0 15px;font-size:1rem;list-style:none}.menu__inner li{margin:0 12px}@media(max-width:684px){.menu__inner{flex-direction:column;align-items:flex-start;padding:0}.menu__inner li{margin:0;padding:5px}}.menu-trigger{width:24px;height:24px;fill:currentColor;margin-left:10px;cursor:pointer}.menu a{display:inline-block;margin-right:15px;text-decoration:none}.menu a:hover{text-decoration:underline}.menu a:last-of-type{margin-right:0}html{box-sizing:border-box;line-height:1.6;letter-spacing:.06em;scroll-behavior:smooth}*,*:before,*:after{box-sizing:inherit}body{margin:0;padding:0;font-family:inter ui,-apple-system,BlinkMacSystemFont,roboto,segoe ui,Helvetica,Arial,sans-serif;font-display:auto;font-size:1rem;line-height:1.54;background-color:#fff;color:#222;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;font-feature-settings:"liga","tnum","case","calt","zero","ss01","locl";-webkit-overflow-scrolling:touch;-webkit-text-size-adjust:100%;display:flex;min-height:100vh;flex-direction:column}@media(max-width:684px){body{font-size:1rem}}body.dark-theme{background-color:#292a2d;color:#a9a9b3}h2,h3,h4,h5,h6{display:flex;align-items:center;line-height:1.3}h1{font-size:2.625rem}h2{font-size:1.625rem}h3{font-size:1.375rem}h4{font-size:1.125rem}@media(max-width:684px){h1{font-size:2rem}h2{font-size:1.4rem}h3{font-size:1.15rem}h4{font-size:1.125rem}}a{color:inherit}img{display:block;max-width:100%}img.left{margin-right:auto}img.center{margin-left:auto;margin-right:auto}img.right{margin-left:auto}figure{display:table;max-width:100%;margin:25px 0}figure.left{margin-right:auto}figure.center{margin-left:auto;margin-right:auto}figure.right{margin-left:auto}figure figcaption{font-size:14px;margin-top:5px;opacity:.8}figure figcaption.left{text-align:left}figure figcaption.center{text-align:center}figure figcaption.right{text-align:right}code{font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-display:auto;font-feature-settings:normal;background:#eaeaea;padding:1px 6px;margin:0 2px;border-radius:5px;font-size:.95rem}.dark-theme code{background:#3b3d42}pre{background:#212020;padding:20px;border-radius:8px;font-size:.95rem;overflow:auto}@media(max-width:684px){pre{white-space:pre-wrap;word-wrap:break-word}}pre code{background:0 0!important;color:#ccc;margin:0;padding:0;font-size:inherit}.dark-theme pre code{color:inherit}blockquote{border-left:2px solid;margin:40px;padding:10px 20px}@media(max-width:684px){blockquote{margin:10px;padding:10px}}blockquote:before{content:'”';font-family:Georgia,serif;font-display:auto;font-size:3.875rem;position:absolute;left:-40px;top:-20px}blockquote p:first-of-type{margin-top:0}blockquote p:last-of-type{margin-bottom:0}ul,ol{margin-left:40px;padding:0}@media(max-width:684px){ul,ol{margin-left:20px}}ol ol{list-style-type:lower-alpha}.container{flex:1 auto;display:flex;flex-direction:column;justify-content:center;text-align:center}.content{display:flex;flex-direction:column;flex:1 auto;align-items:center;justify-content:center;margin:50px 0}@media(max-width:684px){.content{margin-top:0}}hr{width:100%;border:none;background:#dcdcdc;height:1px}.dark-theme hr{background:#4a4b50}.hidden{display:none}@media(max-width:684px){.hide-on-phone{display:none}}@media(max-width:900px){.hide-on-tablet{display:none}}.screen-reader-text{border:0;clip:rect(1px,1px,1px,1px);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute!important;width:1px;word-wrap:normal!important}.screen-reader-text:focus{background-color:#f1f1f1;border-radius:3px;box-shadow:0 0 2px 2px rgba(0,0,0,.6);clip:auto!important;clip-path:none;color:#21759b;display:block;font-size:14px;font-size:.875rem;font-weight:700;height:auto;left:5px;line-height:normal;padding:15px 23px 14px;text-decoration:none;top:5px;width:auto;z-index:100000}.posts{width:100%;max-width:800px;text-align:left;padding:20px;margin:20px auto}@media(max-width:900px){.posts{max-width:660px}}.posts:not(:last-of-type){border-bottom:1px solid #dcdcdc}.dark-theme .posts:not(:last-of-type){border-color:#4a4b50}.posts-group{display:flex;margin-bottom:1.9em;line-height:normal}@media(max-width:900px){.posts-group{display:block}}.posts-list{flex-grow:1;margin:0;padding:0;list-style:none}.posts .post-title{font-size:1rem;margin:5px 0}.posts .post-year{padding-top:6px;margin-right:1.8em;font-size:1.6em;opacity:.6}@media(max-width:900px){.posts .post-year{margin:-6px 0 4px}}.posts .post-item{border-bottom:1px grey dashed}.posts .post-item a{display:flex;justify-content:space-between;align-items:baseline;padding:12px 0;text-decoration:none}.posts .post-day{flex-shrink:0;margin-left:1em;opacity:.6}.post{width:100%;max-width:800px;text-align:left;padding:20px;margin:20px auto}@media(max-width:900px){.post{max-width:600px}}.post-date:after{content:'—'}.post-title{font-size:2.625rem;margin:0 0 20px}@media(max-width:684px){.post-title{font-size:2rem}}.post-title a{text-decoration:none}.post-tags{display:block;margin-bottom:20px;font-size:1rem;opacity:.5}.post-tags a{text-decoration:none}.post-content{margin-top:30px}.post-cover{border-radius:8px;margin:40px -50px;width:860px;max-width:860px}@media(max-width:900px){.post-cover{margin:20px 0;width:100%}}.post-info{margin-top:30px;font-size:.8rem;line-height:normal;opacity:.6}.post-info p{margin:.8em 0}.post-info a:hover{border-bottom:1px solid #fff}.post-info svg{margin-right:.8em}.post-info .tag{margin-right:.5em}.post-info .tag::before{content:"#"}.post-info .feather{display:inline-block;vertical-align:-.125em;width:1em;height:1em}.post .flag{border-radius:50%;margin:0 5px}.pagination{margin-top:20px}.pagination__title{display:flex;text-align:center;position:relative;margin:30px 0 20px}.pagination__title-h{text-align:center;margin:0 auto;padding:5px 10px;background:#fff;color:#999;font-size:.8rem;text-transform:uppercase;text-decoration:none;letter-spacing:.1em;z-index:1}.dark-theme .pagination__title-h{background:#292a2d;color:#73747b}.pagination__title hr{position:absolute;left:0;right:0;width:100%;margin-top:15px;z-index:0}.pagination__buttons{display:flex;align-items:center;justify-content:center}.pagination__buttons a{text-decoration:none;font-weight:700}.button{position:relative;display:inline-flex;align-items:center;justify-content:center;background:#eaeaea;font-size:1rem;font-weight:600;border-radius:8px;max-width:40%;padding:0;cursor:pointer;appearance:none}.dark-theme .button{background:#3b3d42}.button+.button{margin-left:10px}.button a{display:flex;padding:8px 16px;text-decoration:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.button__text{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.button.next .button__icon{margin-left:8px}.button.previous .button__icon{margin-right:8px}.footer{padding:40px 20px;flex-grow:0;color:#999}.footer__inner{display:flex;align-items:center;justify-content:center;margin:0 auto;width:760px;max-width:100%}@media(max-width:900px){.footer__inner{flex-direction:column}}.footer__content{display:flex;flex-direction:row;align-items:center;font-size:1rem;color:#999}@media(max-width:900px){.footer__content{flex-direction:column;margin-top:10px}}.footer__content>*:not(:last-child){border-right:1px solid;padding:0 15px}@media(max-width:900px){.footer__content>*:not(:last-child){border:none}}.footer__content>*:last-child{padding:0 15px} -------------------------------------------------------------------------------- /resources/_gen/assets/scss/scss/main.scss_39fa5fe97be74115670eace810202c56.json: -------------------------------------------------------------------------------- 1 | {"Target":"main.min.5dcefbf8102eb536dd3e2de53ffebfa58599ab2435c241a0db81728a5e015f2e.css","MediaType":"text/css","Data":{"Integrity":"sha256-Xc77+BAutTbdPi3lP/6/pYWZqyQ1wkGg24Fyil4BXy4="}} -------------------------------------------------------------------------------- /static/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naniroot/naniz-hugo-site/dec6f1ee481dc09e2ea11a0a0c262c707af6fa23/static/android-chrome-192x192.png -------------------------------------------------------------------------------- /static/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naniroot/naniz-hugo-site/dec6f1ee481dc09e2ea11a0a0c262c707af6fa23/static/android-chrome-512x512.png -------------------------------------------------------------------------------- /static/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naniroot/naniz-hugo-site/dec6f1ee481dc09e2ea11a0a0c262c707af6fa23/static/apple-touch-icon.png -------------------------------------------------------------------------------- /static/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naniroot/naniz-hugo-site/dec6f1ee481dc09e2ea11a0a0c262c707af6fa23/static/favicon-16x16.png -------------------------------------------------------------------------------- /static/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naniroot/naniz-hugo-site/dec6f1ee481dc09e2ea11a0a0c262c707af6fa23/static/favicon-32x32.png -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naniroot/naniz-hugo-site/dec6f1ee481dc09e2ea11a0a0c262c707af6fa23/static/favicon.ico -------------------------------------------------------------------------------- /static/images/anime/death_note.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naniroot/naniz-hugo-site/dec6f1ee481dc09e2ea11a0a0c262c707af6fa23/static/images/anime/death_note.jpg -------------------------------------------------------------------------------- /static/images/anime/fullmetal_alchemist.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naniroot/naniz-hugo-site/dec6f1ee481dc09e2ea11a0a0c262c707af6fa23/static/images/anime/fullmetal_alchemist.jpg -------------------------------------------------------------------------------- /static/images/anime/naruto.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naniroot/naniz-hugo-site/dec6f1ee481dc09e2ea11a0a0c262c707af6fa23/static/images/anime/naruto.jpg -------------------------------------------------------------------------------- /static/images/anime/one_piece.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naniroot/naniz-hugo-site/dec6f1ee481dc09e2ea11a0a0c262c707af6fa23/static/images/anime/one_piece.jpg -------------------------------------------------------------------------------- /static/images/display.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naniroot/naniz-hugo-site/dec6f1ee481dc09e2ea11a0a0c262c707af6fa23/static/images/display.jpg -------------------------------------------------------------------------------- /static/images/mvc_schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naniroot/naniz-hugo-site/dec6f1ee481dc09e2ea11a0a0c262c707af6fa23/static/images/mvc_schematic.png -------------------------------------------------------------------------------- /static/images/overflow/image1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naniroot/naniz-hugo-site/dec6f1ee481dc09e2ea11a0a0c262c707af6fa23/static/images/overflow/image1.png -------------------------------------------------------------------------------- /static/images/overflow/image2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naniroot/naniz-hugo-site/dec6f1ee481dc09e2ea11a0a0c262c707af6fa23/static/images/overflow/image2.png -------------------------------------------------------------------------------- /static/images/overflow/image3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naniroot/naniz-hugo-site/dec6f1ee481dc09e2ea11a0a0c262c707af6fa23/static/images/overflow/image3.png -------------------------------------------------------------------------------- /static/images/overflow/image4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naniroot/naniz-hugo-site/dec6f1ee481dc09e2ea11a0a0c262c707af6fa23/static/images/overflow/image4.png -------------------------------------------------------------------------------- /static/images/overflow/image5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naniroot/naniz-hugo-site/dec6f1ee481dc09e2ea11a0a0c262c707af6fa23/static/images/overflow/image5.png -------------------------------------------------------------------------------- /static/images/xkcd_python.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naniroot/naniz-hugo-site/dec6f1ee481dc09e2ea11a0a0c262c707af6fa23/static/images/xkcd_python.png -------------------------------------------------------------------------------- /static/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} --------------------------------------------------------------------------------