Da se pretstavim

Rekoh, da se predstavimo da znamo ko smo i sta smo, pa da forum bude prisniji:
Evo o meni:

Branimir Maksimovic
Cvijiceva 66
11000 Belgrade
[email protected]
Software developer experienced in Unix/Linux operating systems, worked also somewhat on Windows, specialized now in scalable
servers with vast experience in software engineering.
1992-02 - 1997-01
Blood transfusion institute, IT
Maintenance of blood transfusion application. Other applications as needed. Unix operating system.
Application was done in business basic and later on ported to progress database.
1993-01 - 1993-09
Agency Beta, IT
Developed T27 emulator program, which was competition to one of the strongest IT company Informatika in
Serbia by that time.
We had know how while they just resold Unisys program. DOS operating system.
Programmed PC interrupt controller as well as UART. Terminal uses proprietary poll/select protocol.
Zbog ovoga je izasao clanak u Racunarima i imao sam intervju na TV politika ;)

1994-01 - 1994-06
Consultant, C expert
Stratus computer, hired
Made expertize on Stratares, Stratus reservation system, solving problems on application and made live tests on
Shanghai airport. VOS operating system.
Application was Stratus specific. Used multi-thread model and everything was done from lowest level. Solved
signal handling problem which caused application to crash during runtime.
Also did several tasks regarding additional features needed.
1997-02 - 1999-02
National bank of Yugoslavia, Vault sector
Developed application for vault business, this one was for Windows.
Application is activex server as front end to Oracle database. Clients were windows 95 and server was Windows
NT. Framework used was VCL under Borland C++ builder.
1999-07 - 2000-10
HAND gmbh, IT
Lead software engineer in developing application for air traffic control training in Belgrade department. Also
worked as consultant to younger developers.
Application is custom Qt where forms were created from data stored by mine serialization library. I did event
handling instead of Qt’s moc based signal-slot and also did
custom rpc library to fetch data from simulation server. Application performed run time simulation of air traffic
where live data was fed into queue from remote network.
2001-03 - 2018
ProgrammerSeenetix, VoloMP, IT
Involved in building company from scratch. Wrote several servers HTTP/SMTP etc… Linux
This software is email marketing software.
This application has two major components. One is exploder which sends mails to mx’s and other is custom rpc
server which is front end to MySQL database as well as anything needed to process feedback data after sending
emails. Mine Http server is used to maintain site as well to process tracked links, opens and bounces. Smtp
server forwards bounce and unsub requests to main server.
Servers are event based, that is, use non blocking sockets, with event loop to process incoming data. rpc server
uses leader/follower model, while http and smtp server uses epoll loops while forwarding into queue which is later
processed by worker threads. Also did couple of custom databases , and lot of other things like importing data,
sending via amazon simple email service and others. sqlite is used mainly to store configurations.
Senior software engineer.
Involved in project for RS military, direction finder.
source: http://www.vti.mod.gov.rs/index.php?view=actuality&type=projects&category=1&id=72

1984-09 - 1988-06
VI Belgrade gymnasium, programmer
Programming classes with math.
As a final exam, wrote application for vacancy planning for firm of around 200 employees. For that I got diploma
‘Mihailo Petrovic Alas’
C, C++,x86 assembler, sql databases, with plethora of other languages like D,Haskell,Go, nim and Rust.


a sad mogu da dodam i aarch64 asembler i Swift :stuck_out_tongue:

1 Like

Mene mrzi da kucam toliko. :joy:


@Branimir_Maksimovic impresivno, ukratko ceo zivot cukas po kodu :smiley:

1 Like

Pa da ja sam Hard Core ČP

Брате, завидим вама програмерима из те генерације. Ја док не научим C, нећу се програмером звати. Авај, време је главни ограничавајући фактор.

Ви сте пратили развој свега хронолошки (асемблер, C), познајете унутрашње функционисање компа. Ок, нисте баш бушили картице, ал да не претерујемо. Нит знам како ради гомила протокола на којима се све базира.

Ја направим објекат и заболе ме где је алоциран. Алгоритам? Не знам шта то значи… Довуци библиотеку и терај.

Стоји чињеница да нам то олакшава да се бавимо сложеном бизнис логиком, ал и даље имам осећај да ми фали фундаментало знање на тему.

О Хаскелу да и не говорим. Скоро сам почео да се бакћем са функционалиним језиком и потпуни је mindfuck у сваком позивитивном смислу и недостатку адекватног превода тог англицизма…


1 Like

Haskell posle assembler-a je najteжи језик за капирање.
Ево мог бенч програма различите врсте сортева у Хаскеллу ЧП

import Data.List
import qualified Test.QuickCheck as QC
import System.Random
import Criterion.Main
import Data.Bits
import qualified Data.Vector.Mutable as VM
import qualified Data.Vector as V
import Data.Word
import System.IO.Unsafe
import Data.Bits

lsdSort :: (Ord a, Bits a, Num a) => [a] -> [a]
lsdSort = fixSort positiveLsdSort

msdSort :: (Ord a, Bits a, Num a) => [a] -> [a]
msdSort = fixSort positiveMsdSort

-- Fix a sort that puts negative numbers at the end, like positiveLsdSort and positiveMsdSort
fixSort :: (Bits a, Ord a, Num a)=>([a]->[a]) -> [a] -> [a]
fixSort sorter list = uncurry (flip (++)) (break (< 0) (sorter list))

positiveLsdSort :: (Bits a) => [a] -> [a]
positiveLsdSort list = foldl step list [0..bitSize (head list)] where
    step list bit = uncurry (++) (partition (not . flip testBit bit) list)

positiveMsdSort :: (Bits a) => [a] -> [a]
positiveMsdSort list = aux (bitSize (head list) - 1) list where
    aux _ [] = []
    aux (-1) list = list
    aux bit list = aux (bit - 1) lower ++ aux (bit - 1) upper where
                  (lower, upper) = partition (not . flip testBit bit) list
msort :: Ord a =>[a] -> [a]
msort xs
  | n < 2 = xs
  | otherwise = merge (msort x1s) (msort x2s)
    n = length xs
    (x1s,x2s) = splitAt (n`quot`2) xs
    merge xs ys = case (xs,ys) of
      ([], ys') -> ys'
      (xs', []) -> xs'
      (x:xs',y:ys') | x < y -> x : merge xs' ys
                    | otherwise -> y : merge xs ys'

isort :: Ord a => [a] -> [a]
isort xs = foldr insert [] xs
        insert x [] = [x]
        insert x (y:ys) = if x<y then x:y:ys
                          else y: insert x ys

qsort :: Ord a => [a] -> [a]
qsort [] = []
qsort [x] = [x]
qsort xs =
        pivot = mot
        (x1s,x2s,pivots) = foldl (\(ys,zs,pivots) x->
                            if x<pivot
                            then (x:ys,zs,pivots)
                            else if x>pivot
                                 then (ys,x:zs,pivots)
                                 else (ys,zs,x:pivots)) ([],[],[]) xs
    in qsort x1s ++ pivots ++ qsort x2s
          mot =
            let n = length xs
                (a,b,c) = (xs !! 0, (xs !! (n`quot`2)), xs !! (n-1))
            in if a>b
               then if a<c
                    then a
                    else if c>b
                         then c
                         else b
               else if b<c
                    then b
                    else if c>a
                         then c
                         else a

rsort :: [Word32] -> [Word32]
rsort xs = unsafePerformIO $ do
    let base = 16

        add_bucket :: Int -> Word32 -> VM.IOVector [Word32] -> VM.IOVector [Word32]
        add_bucket i n b = unsafePerformIO $ do
                        lst <- VM.read b i
                        VM.write b i (n:lst)
                        return b
        clear b = mapM_ (\i-> VM.write b i []) [0..base-1]
    bucket <- VM.replicate base [] :: IO (VM.IOVector [Word32])
    let loop = return $ foldl body xs [0..7]
                body :: [Word32] -> Word32 -> [Word32]
                body nums n = unsafePerformIO $ do
                        v <- V.freeze (foldl disp bucket nums)
                        clear bucket
                        return $ V.foldr gather [] v
                        disp :: VM.IOVector [Word32]->Word32->VM.IOVector [Word32]
                        disp b val = add_bucket (fromIntegral ((val`shiftR`fromIntegral (n`shiftL`fromIntegral 2)).&.0xf)) val b
                        gather :: [Word32]->[Word32] -> [Word32]
                        gather b nums = foldl (\xs x->x:xs) nums b

prop_msort :: [Word32]->Bool
prop_msort xs = msort xs == sort xs && sort xs == isort xs && sort xs == qsort xs && sort xs == rsort xs &&
                lsdSort xs == sort xs && msdSort xs == sort xs

deepCheck p = QC.quickCheckWith (QC.stdArgs { QC.maxSize = 1000}) p

n :: Word32
n = 4096 * 16
tl :: [Word32]->[Word32]
tl = take (fromIntegral n)

main = do
    putStrLn $ "list size " ++ show n
    deepCheck prop_msort
    g <- getStdGen
    let rl = randomRs (0,n) g
    let (s,rs) = ([(0::Word32)..],[(n-1::Word32),n-2..])
    let rnd = tl rl
        srt = tl s
        rsrt = tl rs
    defaultMain [
        bgroup "msdSort" [
            bench "random"  $ nf msdSort rnd,
            bench "sorted"  $ nf msdSort srt,
            bench "reverse sorted"  $ nf msdSort rsrt
        bgroup "lsdSort" [
            bench "random"  $ nf lsdSort rnd,
            bench "sorted"  $ nf lsdSort srt,
            bench "reverse sorted"  $ nf lsdSort rsrt
        bgroup "qsort" [
            bench "random"  $ nf qsort rnd,
            bench "sorted"  $ nf qsort srt,
            bench "reverse sorted"  $ nf qsort rsrt
        bgroup "sort"  [
            bench "random" $ nf sort rnd,
            bench "sorted" $ nf sort srt,
            bench "reverse sorted" $ nf sort rsrt
        bgroup "msort" [
            bench "random" $ nf msort rnd,
            bench "sorted" $ nf msort srt,
            bench "reverse sorted" $ nf msort rsrt
        bgroup "isort" [
            bench "random" $ nf isort rnd,
            bench "sorted" $ nf isort srt,
            bench "reverse sorted" $ nf isort rsrt
        bgroup "rsort" [
            bench "random" $ nf rsort rnd,
            bench "sorted" $ nf rsort srt,
            bench "reverse sorted" $ nf rsort rsrt
    print $ take 10 $ rsort rnd

Не могу да тврдим да разабирам синтаксу у целости, ал функционалан приступ је ту (еурека :grin:). Мутабилно користиш због перформанси? Колика је разлика кад би писао чисту рекурзију са непроменљивим типовима?

pa ono sve zavisi, po prilici, kad radis sa nizovima svakako da mora mutabilno,
jer u funkcionalnom niz apdejt je O(n)

И грђе ако имаш још неку угњеждену петљу. Али ако је у хаскелу прихватљиво, онда је и овде. Трудим се да избегавам било какву мутацију, вежбе ради…

Pa ono, petlje nemaš u Haskellu, to je imperativno programiranje.

Тим горе. Рекурзија у рекурзији… Па још кад је све непроменљиво, па се прави копија листе за сваку операцију над елементом… :woozy_face:
Не знам дал Хаскел има оптимизацију за репату рекурзију (tail recursion)

Pogreshno razmishljash :stuck_out_tongue:
Znash shta je tail optimizacija :stuck_out_tongue:
Kada ne izlazish iz f-je nego idesh u rekurziju sa jmp :stuck_out_tongue:

1 Like

Ууу. Што мрзим/волим кад ме неко избаци из шина. Идемо опет Јово наново…

1 Like

Haskell je vrlo komplikovan da se shvati, zato je neupotrebljiv da
se uradi bilo shta realno u njemu…

Па оно. Ја сам почео да учим чисто због функционалне парадигме. Увек је боље имати у глави више начина приступања проблему. Неки концепти могу да буду итекако згодни. Користиш где се шта добро уклапа.

Znash kako Haskell kao nema memory leak, ali ima space leak, shto je zapravo isto.
Fora je shto je lazy, pa kada opalish neku rachunicu cache-ira u memoriji
zato shto rezultat daje on demand ne kako idu algoritamski koraci.
Tako da recimo prosto inkrementiranje varijable u petlji
mozhe izazvati da probijesh plafon, tako da imash striktno rachunanje,
tj da forsirash rachunicu sa ! znakom ili deepseq.

I josh jedna stvar, kod Haskell-a ako hotjesh da imash stabilan kod,
da ne morash da menjash chesto i presipash iz shupljeg u prazno,
ne smesh da koristish ove njihove biblioteke. Jer to pishu studenti,
kojih je briga za stabilnost koda i api-ja.

Dakle recimo evo ga moj server u Haskell-u:

[email protected] server % cat hs_tmain.hs
import Sockets
import Foreign.C.String
import Data.IORef
import Control.Concurrent

main = do
    ref <- newIORef 1
    s <- socket defaultCallbacks {
                                    constructor = \ci -> set_cb ci defaultCallbacks {
                                        done_connected = binded ref,
                                        done_reading = process
    pl <- epoll 1000
    pl1 <- epoll 1000
    pl2 <- epoll 1000
    pl3 <- epoll 1000
    listen s "8080"
    pl_accept pl s
    pl_accept pl1 s
    pl_accept pl2 s
    pl_accept pl3 s
    let run pl = do forkIO $
                     run_loop pl (-1)
    run pl
    run pl1
    run pl2
    run_loop pl3 (-1)

binded ref pl s = do
    i <- readIORef ref
    putStrLn $ "connection nr:"++show i
    writeIORef ref (i+1)
    pl_read pl s
    return 0

process pl s buf len = do
        str <- peekCStringLen (buf,fromIntegral len)
        ip <- client s
        str1 <- peekCString ip
        putStrLn $ "from "++str1++" \ngot "++str
        write pl s "Hello World!!!\r\n"
        return 0

lib i cpp kod ako nekoga zanima

Ај ти направи неки блог, да шириш мало прагматизам :grin:, ствари иду у погрешном смеру у последње време

Ma jok blog je za one koji hotje da HIPNOTiSHU MASE, koji NE TRPE KRITIKU :stuck_out_tongue:
Pogle ovo gde si video da server odrzhava konzistentan broj requesta/sec za 1000 i 10000 konekcija :stuck_out_tongue:
I TO U HASKELLU :stuck_out_tongue:
/…/rust/webserver >>> ./target/release/sockclient localhost 8080 1000 100000
ticks 3350000 [0/1875]
ticks 3360000
ticks 3370000
ticks 3380000
ticks 3390000
ticks 3400000
ticks 3410000
ticks 3420000
ticks 3430000
ticks 3440000
ticks 3450000
ticks 3460000
ticks 3470000
ticks 3480000
ticks 3490000
ticks 3500000
ticks 3510000
ticks 3520000
ticks 3530000
ticks 3540000
12673 recs/sec
Timeouted 21
~/…/rust/webserver >>> ./target/release/sockclient localhost 8080 10000 100000
ticks 4110000
ticks 4120000
ticks 4130000
ticks 4140000
ticks 4150000
ticks 4160000
ticks 4170000
ticks 4180000
ticks 4190000
ticks 4200000
ticks 4210000
ticks 4220000
ticks 4230000
ticks 4240000
ticks 4250000
ticks 4260000
ticks 4270000
ticks 4280000
ticks 4290000
ticks 4300000
13389 recs/sec
Timeouted 8356