Przerzuciłem projekt z wersji 4.0 .NET to wersji 3.5 bo nie używam żadnych ficzerów z 4.0, dodatkowo przerzuciłem wszystko do MonoDevelop, takiego aspiranta do bycia .NETowym Eclipsem ;-) jeden plus, że wygodniejszy od Visual C# Express 2010, choć taką nowomodną funkcjonalność jak pokazywanie lokalnych zmiennych w trakcie debugowania to by mu mogli dodać ;-)
No i dziś dzięki temu wszystkiemu udało mi się w końcu zupdatować dokument w Google Docs :-) Jest to o tyle osiągnięcie, że biblioteki .NET dla wersji 2.0 Google Docs API nie potrafią updatować plików, trzeba więc zrobić to samemu :-) ale jakieś szczególnie trudne to nie jest.
Google mówi, że do updatowania trzeba zbudować takiego requesta:
PUT /feeds/media/private/full/document%3Adocument_id
Host: docs.google.com
Authorization: <your authorization header here>
Content-Length: 70581
Content-Type: application/msword
Slug: test.doc
... doc contents here ...
Oczywiście w miejscu content lenghta podajemy długość naszego pliku ;-) Praktyka pokazuje, że użycie czegoś takiego powoduje wyrzucenie przez serwer Google Docs błędu 400 z komunikatem "Missing Resource Version ID", dlatego trzeba dodać do nagłówków naszego requesta nagłówek GData-Version, w moim przypadku "GData-Version: 2.0", który mówi serwerowi jakiej wersji API używamy. To oczywiście nadal nie działa, bo serwer Google Docs zwraca błąd, tym razem już w XMLu o treści "If-Match or If-None-Match header required". Czyli trzeba dodać kolejny nagłówek do requesta tym razem albo "If-Match" albo "If-None-Match", nie do końca rozumiem rozróżnienia dlatego użyłem "If-Match", jako jego wartość podajemy ETag związany z dokumentem, a ten ETag już znałem.
Ostatecznie request wygląda tak:
PUT /feeds/media/private/full/document%3Adocument_id
Host: docs.google.com
Authorization: <your authorization header here>
User-Agent: rmk-Short_beaked_Echidna-0.0.2
Content-Type: application/msword
Slug: przemelkowyTest2.doc
GData-Version: 2.0
If-Match: "XEdaTR9ABSp7ImBr"
Content-Length: 16896
... doc contents here ...
Tu od razu uwaga, jak chcesz gadać z jakimś serwerem którego nie kontrolujesz to używaj Fiddlera, bo dzięki temu o wiele łatwiej śledzić co się wysyła i co się dostaje. Próbowałem używać Whiresharka, ale się uparł i nie widzi połączenia bazującego na moim modemie do Blueconnecta.. gupek ;-)
Oczywiście multum ci innych problemów [a może multum Ci innych problemów? to ci to Ci czyli forma od Ty, czy może ci to oni, albo jeszcze jakieś inne znaczenie?], np. do teraz wszystkie dokumenty otwierane z dysku R:\ otwierają się w OpenOffice.org w trybie tylko do odczytu, coś pewnie trzeba pomącić z tym kretyńskim C# wynalazkiem out czyli zwracaniem przez parametr [OK, to nie jest tak naprawdę wynalazek C#, praktycznie każdy język to wspiera, prócz Java'y za co należy ją cenić bo to o wiele ułatwia analizę kodu] którym pewnie coś powinienem zwrócić.
Wychodzi też na to, że uploadowanie dokumentów będę musiał sam sobie zaimplementować i zignorować to które jest w bibliotekach Google Docs, a to dlatego, że .NETowa biblioteka uparcie ignoruje rozszerzenie w nazwie dokumentu :-( choć to się jeszcze okaże.
Trzeba będzie też kiedyś dodać kasowanie i może foldery, ale nie wiem na 100%.
Nadal też przeraża mnie lekko partyzanckie podejście do tego dysku, bo docelowo prawdopodobnie będę musiał ten dysk R:\ traktować w taki sposób, że dokumenty rozpoznawalne przez Google Docs będą przechowywane w Google Docs, a wszystkie inne pliki będą trzymane w jakimś "RAM dysku" co jest głupie, ale może się okazać jedynym rozwiązaniem.
Ważne, że się udało zrobić dziś update :-)
Podobne postybeta
Wysyłamy pliki do Google Docs przy pomocy Go :-)
"Ochidna" Echidna ;-) czyli jak się mają prace nad RDrive.
Toperz ;-) czyli OCR + Android odsłona 2 albo któraś tam
Wredne Google Docs
Chrome OS, Chrome2Chrome i w ogóle Chrome ;-)
MonoDevelop wygodniejszy od VS2010? Co prawda w pracy używam Eclipse, ale VS2010 mi się podoba póki co i to nawet bardzo super zintegrowany UML, diagramy encji, T4 i przede wszystkim, co chyba każdy musi przyznać, najlepszy na świecie debugger, który w tej wersji pozwala na równoległe debuggowanie. Z tego, co czytałem teraz twój blog to widzę, że jesteś javowcem uczącym się .NET i C#. Wydaję mi się, że powinieneś wybrać jakiś inny projekt, żeby poczuć prawdziwą różnicę. Może prosty schemat -usługa WCF na bazie danych + klient? Zaletą Javy jest otwartość, open-source i przenośność, a zaletą .NET jest innowacyjność, BCL i C#. Wydaje mi się, że żeby tak naprawdę "poczuć" C# trzeba przede wszystkim poużywać LINQ (które gdybym korzystał w pracy z C# byłoby dla mnie prawdziwym zbawieniem) oraz pobawić się którąś z perełek w koronie tej platformy czyli np WCF albo WPF. Wiem jak było na moim przykładzie - kiedy miałem pierwszą prawdziwą styczność z .NET (wersja 2.0) i pobawiłem się WinForms w VS2005 to pomyślałem "ok, fajnie, ale jakoś będę się trzymał mojego SWT i Eclipse"). Bo tak naprawdę VS wtedy nie dorównywał Eclipse a C# to była tylko taka trochę inna Java. Przyszedł VS2008 oraz .NET3.5 i zrobiło się strasznie głośno o LINQ. Głęboko zakorzeniona microsoftfobia nakazywała trzymać mi się z daleka zwłaszcza, że było to dla mnie tylko powielenie rozwiązań ze SmallTalka. W końcu jednak przełamałem wewnętrzną niechęć i muszę przyznać, że się opłacało. Nie wiem czy C# zginie, zdominuje rynek, czy zostanie zastąpiony przez coś nowego, albo kolejne wersje Javy go przegonią. Wiem tylko, że póki co, język ten spełnia moje marzenia łącząc światy kompilowalnych, statycznie typowanych języków oraz języków skryptowych i dynamicznych (w podobnym kierunku chyba zaczyna zmierzać ActionScript, którego też bardzo cenię, a który wprowadził statyczne typowanie). Co ciekawe, C# coraz bardziej się otwiera na świat. Gdyby był tylko w 100% przenośny tak jak Java to nie miałbym wątpliwości co jest lepsze, ale że nie jest to stawiam obydwa języki/środowiska na równi i uważam, że najlepiej gdyby każdy programista C# znał Javę i na odwrót. Klucz do sukcesu w końcu zazwyczaj tkwi w tym, żeby używać odpowiednich narzędzi do odpowiednich problemów. Życzę ci więc powodzenia w dalszej nauce i pozdrawiam.
OdpowiedzUsuńOd Visual Studio C# Express [podkreślam, że chodzi o wersję Express] lepszy momentami jest nawet CSC.EXE ;-) [OK, lekko przesadzam]. Możliwe, że pełną wersję Visual Studio bym polubił, ale raczej nie, bo zawsze wydawało mi się udziwnione i jak na razie dla mnie nic nie pobiło Eclipse'a. Pamiętam jak w poprzedniej firmie kazali mi coś pisać w C# w VS2005 albo VS2003 i z utęsknieniem zawsze czekałem na moment gdy będę mógł wrócić do Java'y i Eclipse'a.
OdpowiedzUsuńCo do LINQ to jak na razie nie widziałem konieczności zastosowania go.
Osobiście liczę na to, że Java pod skrzydłami Oracle'a odzyska impet i zacznie ewoluować, choć nie zależy mi na tym by zyskiwała wszystkie ficzery C#, closures by mi pasowały, właściwości nie, mam też nadzieję, że nigdy nie dodadzą do Java'y zgadywania typu bo jak widziałem w Go kompilator nieraz wybiera coś czego nie powinien wybrać. Liczę też, że zachowany zostanie porządek w bibliotekach.
A samego C# uczę się tak bez przekonania, licząc że uda mi się obejrzeć co ma konkurencja, ale jakoś na razie nie ma tu jakiegoś wielkiego uczucia, no może poza lekką niechęcią ;-)
Zaś projekt jak najbardziej się nadaje dla C#, bo ma to być maluteńkie narzędzie, działające tylko pod Windows, z jednym czy dwoma okienkami, które ma udawać system plików.
Skoro nigdy nie miałeś okazji do użycia LINQ to moim zdaniem pisałeś w C# wyjątkowo mało. Byle prosta aplikacja bazodanowa oparta o LINQ-To-SQL albo Entity Framework daje wystarczająco dużo sposobności do użycia tego (wg mnie) cudownego wynalazku:) Może gdybyś wyszedł ze środowiska takich języków jak SmallTalk albo Ruby to byś bardziej entuzjastycznie podszedł do tej technologii.
OdpowiedzUsuńCzy nic nie pobiło Eclipse? Hmm.. zależy co robisz. Jeżeli chodzi o Javę to tutaj się z tobą zgodzę... ale tylko jeżeli chodzi o Javę (no i parę innych rzeczy jak np ActionScript etc). Do Ruby lepiej nadaje się NetBeans. VS też jest bardzo dobrym IDE i pod pewnymi względami na pewno przebijającym Eclipse (wspominałem już o najgenialniejszym debuggerze?;) ). Wreszcie dodano porządną refaktoryzację etc. Czy to środowisko jest "udziwnione"? Raczej nie - jest po prostu mocno inne niż Eclipse. Póki co widzę, że Eclipse dosyć zainspirował VS i mam nadzieje, że stanie się tak w drugą stronę. Np strasznie brakuje mi w Eclipse szablonów transformacji albo porządnego uzupełniania kodu (które czasami w ogóle nie działa).
Brak domknięć to rzeczywiście na dzień dzisiejszy chyba główna wada Javy i mam nadzieję, że się to szybko zmieni. Właściwości czy powinny być czy nie to tego ci nie powiem - zależy to tylko od tego kto co woli. Przydałyby się delegaty, kontrakty i nazwane parametry.
Z wnioskowaniem typów to nie słyszałem, żeby ktokolwiek, kiedykolwiek spotkał się z tym, żeby typ został niepoprawnie wywnioskowany w żadnym z "dużych" języków jak C#, OCaml czy C++. Ja bym jednak wolał, żeby inferencja typów była w Javie - chyba nie miałeś do czynienia z naprawdę długimi nazwami typów (wielokrotne złożenia kolekcji itp.) - słówko "auto" albo "var" naprawdę potrafi zaoszczędzić troszeczkę czasu.
Nadal będę też utrzymywał, że twój program nie jest dobry do nauki C#. Co to za projekt C#, w którym nie ma zbyt wiele sposobności, żeby użyć LINQ? Piszę "zbyt wiele" bo jakieś zawsze są - w C# praktycznie nigdy nie korzystam z foreach itd. To, że korzystasz z natywnych funkcji to żadnej problem - zapoznaj się z J/Invoke, dzięki któremu dosyć łatwo osiągnąłbyś swój cel w Javie.
Nie rozumiem twojej niechęci. Wydaje mi się, że jesteś trochę zbytnio zapatrzony w jedną stronę. W dzisiejszym świecie jest wielu takich programistów - ludzi dla których istnieje tylko Java, tylko C#, tylko Python.. tylko Eclipse, tylko VS.. tylko Flash, tylko Silverlight. Wnioskuje to z tego, że określiłeś ten język mianem konkurencji. Moim zdaniem, dla dobrego programisty takie rozumowanie jest niedopuszczalne. Tak jak napisałem w poprzednim poście - kluczem do sukcesu jest dobierać odpowiednie narzędzia do określonych problemów. Nie powinno się opowiadać po stronie żadnego języka "bo już i koniec". Języki i technologie można porównywać tylko i wyłącznie w poszczególnych aspektach - to po pierwsze. Po drugie, zanim chce się zabrać za porównanie, trzeba wiedzieć dokładnie co się porównuje. Wiedzieć tzn mieć doświadczenie i odpowiedni staż. Wielokrotnie w przeszłości miałem okazję się przekonać, że pozory potrafią naprawdę mylić np potrzebowałem pracować przy odpowiednim projekcie, żeby dopiero docenić Pythona (który zawsze był dla mnie tylko gorszą wersją Ruby).
Jeszcze raz powtarzam - życzę ci powodzenia i zrozumienia, że do zdobywania nowej wiedzy nie można NIGDY podchodzić z niechęcią.
Zacznijmy od tego, że ja nie mam zamiaru nigdy pisać w C# dla pieniędzy, po prostu żadna poważna firma w której pracowałem lub w której bym chciał pracować nie używa C#. W każdym bądź razie do poważnych rzeczy. No może w Motoroli coś tam skrobali w C#, ale nie było to nic ważnego.
OdpowiedzUsuńI nie chodzi tu o język, a o to, że jest on silnie przywiązany do Windows, a raczej rozwiązań enterprise się do Windowsa nie przywiązuje. Mogą na nim działać, nawet powinny, ale nie powinny być tworzone tylko dla Windows.
No i przez to wszystkie słodycze składniowe C# są zbyt mało istotne.
Uczę się tego C# żeby zobaczyć co ma i jak się tego czegoś używa w ramach poznania innego spojrzenia na świat, np. w Java'ie nie ładnie jest sterować przepływem przy pomocy wyjątków, a w C# proszę wyjście z pętli w wątku realizowane jest właśnie przez sterowanie przepływem przy pomocy wyjątków.
Jak na razie C# mi się nadal nie podoba, bo strasznie skomplikowali tej język, np. LINQ którym się tak zachwycasz jest bardzo miły, ale trochę dziwne jest to, że jest to ficzer języka, a nie biblioteka. Fakt, takiej składni by nie można było inaczej otrzymać. Ale to takie wiązanie języka do tego akurat zastosowania.
Albo nadal nie mogę zrozumieć po co w C# jest rozróżnienie między metody wirtualne a niewirtualne, szczerze mówiąc to piszę dla pieniędzy kod obiektowy od ładnych 5 lat i w życiu nie musiałem jeszcze użyć metody nie wirtualnej która byłaby widoczna gdziekolwiek poza klasą.
Mówiąc inaczej, nadal nie przemawia do mnie filozofia C#. Ma potężne narzędzia, ale sprawiają wrażenie strasznie bałaganiarskich [to jest całkowicie subiektywne odczucie, bo ktoś inny może uważać, że w C# jest idealny porządek, a w Java'ie czy np. Pythonie jest bałagan] i czasem dodanych na siłę.
Domknięcia w Java'ie by się przydały, bo są sytuacje gdy ich brakuje, a istniejące workaroundy są zbyt ciężkie, ale w C# próbuje się rozwiązywać na poziomie języka problemy, które ma 1% userów. To już widać na samym początku, bo żeby developerowi było łatwiej stworzyć nową klasę niż w Java'ie to zamiast class ClassName extends SomeSuperClass implements SomeInterface używa się class ClassName:SomeSuperClass, SomeInterface. Niby fajnie, niby szybciej, ale akurat tworzenie nowych klas to nie jest miejsce gdzie potrzebuję takich ułatwień, no i wymusza to stosowanie dziwnej konwencji z nazwami interfejsów startującymi od I bo inaczej to nie wiem patrząc na deklarację klasy czy ona coś rozszerza czy może implementuje.
LINQ jest miły, ale dla mnie nie przydatny.
Po tym, co przeczytałem hm.. wnioskuję, że jesteś programistą, który nie ma po prostu zbyt dużego doświadczenia:) .....ale od początku. Nie zgodzę się z tezą, że nikt ważny nie używa .NET. Pracowałem swojego czasu w firmie powiązanej z Autodeskiem - firmą bardzo poważną, która postawiła na .NET. Z resztą Java jest starsza, więc na wstępie miała sporą przewagę i duża część kodu w wielu firmach był napisana w Javie w momencie, kiedy prawie nikt jeszcze nie słyszał o C#. Ogólnie w Javie pisze się 3 do 4ech razy częściej niż w C#, ale to o niczym nie świadczy. Każdy, kto pracował w dużej firmie wie, że to są sprawy, które zależą od managerów i dyrektorów, a nie od programistów. Podobno nadal więcej pisze się w C niż w C++.. i co z tego wynika? Dla mnie nic.
OdpowiedzUsuńCo do twoich zarzutów wobec C# to w ogóle ich nie rozumiem. Sterowanie przepływem przy pomocy wyjątków? Jeżeli uczysz się z jakiejś książki to ją jak najszybciej zmień.
Rozróżnienie metod wirtualnych i niewirtualnych jest BARDZO przydatne szczególnie w bardzo dużych projektach. Wie o tym chyba każdy, kto pisał kiedyś dużo w C++, gdzie jest taki sam podział. Przyczyny są dwie - architektoniczna i wydajnościowa. Architektoniczna - jest to część hermatyzacji tzn. każda klasa powinna zagwarantować swoje działanie. Oznaczasz jako wirtualne tylko te metody, których nadpisanie nie zepsuje działania klasy bazowej. W zupnkty widzenia dobrego projektowania hermetyzacja powinna mieć przewagę nad otwarciem - dlatego np w klasach pola i metody są domyślnie prywatne, anie publiczne. Drugi powód (moim zdaniem mniej ważny) to wydajność - wywołania metod wirtualnych potrzebują vtable co zwiększa zapotrzebowanie na pamięć oraz sprawia, że wywołania metod są wolniejsze. Jestem osobą, która ma bzika na punkcie "ładnego" projektowania oprogramowania i wzorców projektowych i jestem GORĄCYM zwolennikiem rozwiązania a la C++. Naprawdę, kiedy dostajesz jakąś klasę, sama klasa powinna ci pozwolić zrobić tylko to, co nie wpłynie na jej poprawne działanie - kiedy tej gwarancji nie ma, musisz samemu sprawdzać co można, a co nie. Uwierz mi proszę, gdyby w Javie metody były domyślnie nie-wirtualne, byłoby O WIELE lepiej. To, że nie musiałeś pisać takiej metody... hmm... Powiem tak, ja pracuję przy aplikacji, który ma prawie 2mln linii kodu i którego większość jest dla mnie nie zbadana. Nieraz spotykałem się z sytuacją kiedy to własnie z tego powodu musiałem się zagrzebywać w kod, który w ogóle nie powinien mnie obchodzić. Wnioskuje, że ty pracujesz przy mniejszych projektach (może w zespole Agile), gdzie dobrze znasz większość kodu. Nie pojmuję, że przeszkadza ci literka "I" w interfejsach i jest to dla ciebie na tyle znaczącą wadą, żeby to w ogóle poruszyć. Jest to pozostałość tzw. notacji węgierskiej - czegoś, co może niektórzy uważają za koszmar, ale wg mnie są to głównie osoby, które tej notacji tak naprawdę nigdy nie chciały się nauczyć. C++ jako tako nie rozróżnia klas pomiędzy sobą (nie rozróżnia praktycznie nawet klas i struktur), więc ktoś wpadł na (moim zdaniem dobry) pomysł, żeby klasom dawać przedrostki - "T" lub "C" dla zwykłych klas, "I" dla interfejsów, "Co" dla coklas. Dla mnie nie jest to dziwna konwencja. Wnioskuję po raz kolejny, że musiałeś zaczynać od Javy i nie mieć wcześniej doświadczenia z C++, bo gdyby było na odwrót to ta konwencja nie byłaby na pewno dziwna. Bądź co bądź, jesteś naprawdę pierwszą osobą z dziesiątek, z którymi rozmawiałem na podobny temat, który poruszył tą sprawę (!).
Z resztą sam już nie wiem co mam powiedzieć. Przeszkadzają ci literki "I", a LINQ uważasz za nieprzydatny... czemu więc chcą wprowadzić odpowiednik LINQ w Javie? Czemu tak głośno się o tym zrobiło? Myślisz, że to tylko marketing? Proszę, napisz jakąś aplikację bazodanową (na ok 20-30 tabelach) w oparciu o Javę i Hibernate, a potem przepisz ją w oparciu o C# i LINQ-TO-Entities. Myślę, że wtedy poczujesz DIAMETRALNĄ różnicę. Musisz naprawdę pisać programy tyczące się bardzo wąskiej klasy problemów, skoro uważasz tą technologię za nie przydatną.
OdpowiedzUsuńDzięki LINQ można o wiele czytelniej zapisywać w jednej linijce rzeczy, które zapisywało się kiedyś w ponad 10ciu. Czy coś przebije czytelnością i zwięzłością wyrażenia typu;
var s = Users.Where(u => u.Age >= 25).Select(u => u.Company).Distinct().GroupBy(c => c.City);
które możesz wykonywać na obiektach, bazie SQL czy praktycznie czymkolwiek (LINQ-To-XML, LINQ-To-Google, LINQ-To-CSV, LINQ-To-Wikipedia itd itd itd)? Zobacz jakie są typowe kwerendy LINQ. Przepisz je z użyciem Javy. Porównaj nakład pracy, czytelność i prostotę utrzymania tego kodu. Prooooszeeę cieę.....
Przyglądnąłem się trochę dokładniej twojemu blogowi i innym twoim profilom. Widzę, że trochę jednak się napisałeś i pracujesz w Sabre (podobno wielu programistów w południa Polski chciałoby tam pracować)... ale tym bardziej się dziwie niektórym twoim przekonaniom. Spotkałem w życiu ludzi, którzy pracowali w IBM i podobał im się C#, dyskutowałem jakiś czas temu droga elektroniczną z pracownikiem Microsoftu i gorącym zwolenniku Pythona (który notabene pracował nad .NET DLR i IronPython). Nawet jakiś czas temu czytałem wywiad z twórcą Rails, który słynie ze swoich bardzo silnych, antykorporacyjnych poglądów (i ciętego języka), który przyznał, że o ile nienawidzi Microsoftu z definicji to C# mu się podoba (szczególnie LINQ) i uważa, że środowiska OpenSource mogłyby z tego wyciągnąć wiele dobrych wniosków. Z resztą ja też jestem przede wszystkim programistą Javy. Po prostu nie wiem... twoja postawa (wydaje mi się tak z własnego doświadczenia) cechuje przede wszystkim świeżych absolwentów uczelni wyższych, którzy przez całe studia pisali tylko w Javie, tylko w C#, tylko w Pythone lub tylko w PHP.
OdpowiedzUsuńWspomniałem o DLR. Jest to nowa rzecz w .NET. Ma stać się częścią .NET 4.0, a póki co dostępna jest osobno. Na DLR powstał własnie IronPython i IronRuby, ale co ważniejsze - wprowadza on dynamiczne programowanie do C#. Poczytaj trochę o tym. Dla mnie, jako miłośnikowi języków dynamicznych, to jest naprawdę coś. Stanie się możliwe definiowanie języków dziedzinowych.. już sobie wyobrażam dynamiczne klienty REST itd. Jeszcze co prawda nie miałem okazji się w to zagłębić. Piszę o tym, bo wydaje mi się, że skoro LINQ do ciebie nie przemawia (nadal utrzymuje, że to tylko dlatego bo w nim chyba nawet nie próbowałeś nic napisać) to może przemówi do ciebie coś takiego? Swoją drogą ciekawe, czy w takim razie ASP.NET MVC zacznie być takie elastyczne jak Django/Rails. To by było coś... chyba musisz mi przyznać rację?
Domyślnie nie wirtualne metody to gwałt na poliformizmie, bo patrząc na kod nie wiesz czy wykona się metoda najbardziej szczegółowa czy może bardziej ogólna. W Java'ie gdy zależy Ci na tym by publiczna metoda już nie była wirtualną to ją finalizujesz i wtedy nikt jej już nie nadpisze. Unikasz problemu polegającego na zgadywaniu co się wykona w danym kontekście.
OdpowiedzUsuńNakłada to na programistę niewielki wysiłek dbania o to by jego klasa przestrzegała kontraktu określonego w klasie bazowej, ale ponieważ dostęp do elementów nadklasy możliwy jest tylko przez publicznych lub chronionych członków to wiele narozrabiać nie może.
W C++, a nawet w Delphi można zrozumieć podział na wirtualne i niewirtualne metody, gdzie niewirtualne są domyślne bo oba te języki nie są li tylko obiektowe, ale C# jest językiem obiektowym i wypadałoby by się tak zachowywał. No i akurat i w C# i w Java'ie czas przeszukiwania tabeli metod wirtualnych to tzw. pikuś ;-)
Wracającego do tego co pisałeś wyżej, to w Java'ie akurat P/Invoke nie ma, tutaj to się nazywa JNI tudzież JNA, ale to tylko sprawa nazwy. A w przypadku mojego cosia, musiałbym napisać własny wrapper na biblioteki Dokana, co jakoś trudne szczególnie nie jest, ale jednak jest to pisanie jakiegoś dodatkowego niepotrzebnego kodu.
Co do projektów w których pracowałem i pracuje, to są to średnie aplikacje od 300 do 500 tysięcy linii kodu, z zespołami w okolicach 5-10 developerów.
Co do wyboru technologii to management ma technicznych do doradzania i wyboru technologii. Przez to jak na razie zawsze miałem mniejszy lub większy wpływ na wybór technologii :-)
Co do wykorzystania C#, to jak pisałem żadna z firm w których ja bym chciał lub dopuszczał pracowanie nie używa C# do poważnych rzeczy, u mnie w firmie króluje Java i C/C++, gdzie ten drugi zestaw języków odpowiada za soft bez którego nie byłoby sprzedaży biletów lotniczych na świecie, do tego dochodzi Delphi, które jest wykorzystywane z powodów historycznych, ale platformy .NET w ogóle nie używamy, bo dość trudno ją uruchomić na Solarisie ;-) W mojej firmie marzeń nie używają C# praktycznie do niczego [OK, mają jeden system napisany w ASP.NET, ale na pewno bym się nim nie chciał zajmować ;-)].
Ja nie chcę LINQ w Java'ie :-) gdyby dało się go dodać jako bibliotekę [może być standardowa], a nie element języka to nie mam nic przeciwko, a co do Twojego przykładu, to jak często musisz pisać coś takiego? ;-)
W moim obecnym projekcie musimy podejrzanie często gadać z bazą, ale użycie LINQa dotyczyło by pewnie z 2-5% kodu. Czyli mogłoby pomóc, ale nie jakoś szczególnie. Inna sprawa, że niestety przez to, że musimy pracować z 2 różnymi bazami danych [tzn. zależnie od konfiguracji możemy pracować z Oraclem albo InterBasem] to potrzebujemy dość silnego związania się z SQLem bo po prostu bazy czasem wiedzą lepiej, co jest istotne przy rozbudowanych zapytaniach użytkowników [chyba w najbardziej wypasionych zapytaniach mamy w użyciu do 20 tabel z ponad 100 warunkami] i tutaj nawet LINQ nie pomoże. Bo jak użytkownik chce np. dostać listę 25 klientów z jakimiś tam parametrami, którzy korzystając z tych dostawców wydali w ciągu zadanego czasu najwięcej pieniędzy, ale nie mniej niż to trzeba czasem niestety SQLa budować samemu.
Nie twierdzę, że LINQ to zło, to świetny mechanizm pomagający w pewnych specyficznych zastosowaniach, ale akurat w aplikacjach które piszę w pracy czy też samemu nie ma dlań praktycznie żadnego zastosowania.
Co do sterowania przepływem przy pomocy wyjątków. To wyjątki są do obsługiwania sytuacji wyjątkowych, czyli jak ktoś nam wciska obiekt w złym stanie, to tak wyrzucamy wyjątek, i ktoś go obsługując stara się zażegnać straty, ale chyba zgodzisz się, że jak ktoś zrobi coś takiego:
OdpowiedzUsuńint a = 10;
int b = 0;
int c;
try {
c = a/b;
} catch (ArithmeticException e) {
c = 10000;
}
to powinien ponieść srogą karę ;-) Bo tutaj wyjątek służy tylko do obsłużenia sytuacji gdy b jest równe 0, czyli sytuacji w pełni przewidywalnej.
Tak samo wracając do tego o czym pisałem wyżej ze sterowaniem przepływem przy pomocy wyjątków w C# - mamy sytuację przerwania wątku, po wywołaniu abort() poleci ThreadAbortException, i jedyną uwagę w dokumentacji .NET/C# że to nie jest jednak najlepsza metoda jest komentarz usera MSDN ;-) dla porównania w JavaDoc z JDK tak 1/4 1/5 całego opisu mówi o tym, że stop() [które rzuca w wątku ThreadDead] jest złe i powinno się go unikać. I postawa Java'owa jest o tyle bardziej uzasadniona, że planowe przerwanie pracy wątku to rzecz jak najbardziej przewidywalna i wątek powinien sobie z tym sam poradzić.
Co do konwencji nazw, to notacja węgierska była wynikiem bałaganu jaki zrobił sam Microsoft w bibliotekach WinAPI dla C++ [znaczy się, sam MS używał notacji węgierskiej już wcześniej, ale później mieli wybuch radosnej twórczości już w WinAPI], jeszcze oryginalna wersja była dość jasna, ale późniejsze zmiany z których wynika lpsz jako odległy wskaźnik do stringa zakończonego zerem to był po prostu straszny bałagan. No i sami do teraz się borykają z jej wadami w tym, że nadal przekazują wParam, choć on już wcale nie jest słowem [co ja się te 10 lat temu namęczyłem z tym gdy przenosiłem kod z Win16, na Win32 to moje ;-) bo na początku nie mogłem zrozumieć czemu mi to nie działa :-)].
Konieczność użycia I przed nazwą interfejsu wynika z tego, że patrząc w C# na pierwszy element po : w deklaracji klasy nie wiesz czy to interfejs czy klasa, bo później w kodzie w większości przypadków mało Cię interesuje czy używasz interfejsu czy klasy konkretnej, więc to jest dodatkowa, niepotrzebna informacja. A największa słabością tej konwencji jest to, że aby działała wszyscy jej muszą używać.
Choć tu jedno zastrzeżenie ;-) to też zależy od tego czy musisz wiedzieć czy to coś po : to interfejs czy klasa ;-) Bo znowu akurat przyglądanie się deklaracji klasy nie jest głównym zajęciem programisty ;-)
Ogólnie w problemie akurat tym najbardziej boli mnie to, że konwencją muszą nadrabiać coś co można było spokojnie zrobić na poziomie języka.
Sprowadzając wszystko co wyżej do jednego :-)
OdpowiedzUsuńJa jestem prosty człowiek i wolę proste rozwiązania, w których nie ma niedomówień i domysłów. Gdy widzę float a=10.0f; to wiem, że w a jest coś typu float, gdy widzę var a=10/7; to żeby w ogóle móc domyślać się co jest w a muszę wiedzieć, że np. w danym języku wynikiem 10/7 gdzie oba wyrazy są całkowite wynik też będzie całkowity i wyniesie 1. W języku z dynamicznym typowaniem mi to problemu nie sprawia bo tam wiem, że 10/7 to będzie 1 z hakiem, ale w języku silnie typowanym to jest powód do poważnego zastanowienia się co kompilator wykoncypuje.
To też hamuje mój entuzjazm do LINQ i wszelkich frameworków, bo żeby czegoś używać to trzeba to znać perfect, a zwykle ułatwiacze ułatwiają rzeczy proste, a komplikują trudne. W takim Swingu banalnie prosto można zbudować proste okienko z prostymi guziczkami, ale zrobienie czegoś bardziej skomplikowanego wymaga dogłębnego poznania biblioteki, w WinAPI używałeś po prostu klasy okna, pisałeś do niej funkcje obsługującą komunikaty i co prawda banalne okienko z 2 przyciskami pisałeś w 20 liniach, a nie 3 czy 5, ale w WinAPI gdy użyłeś guziczka w jakiejś tabelce to nadal guziczek dostawał komunikaty, a w Swingu już tak łatwo nie jest.
Gdy na callu jeden z moich amerykańskich managerów mówi, że nie powinniśmy robić akurat takiego zapytanie SQL bo ono męczy bazę i zamiast robić LEFT JOIN na tej tabeli a później JOIN na drugiej i kolejnego na trzeciej to powinienem robić je inaczej to po prostu zmieniam to zapytanie, a co w LINQ? Nie mam z tego co widzę kontroli nad providerem, sam mam go napisać żeby mieć nad tym kontrolę? Ale to jest zadanie o wyższym stopniu komplikacji. Mogę też robić doświadczenia by zmienić kolejność wywołań "kodu LINQa" tak by akurat zapytanie było takie jak powinno być, ale to mi się może nie udać. Mogę zrobić workaround i tutaj akurat zrobić wszystko ręcznie, ale wtedy ułatwiacz w postaci LINQ ułatwia mi tylko prost rzeczy.
Mówiąc inaczej, ja jestem typ, który woli REST od WebService bo obsługę REST na JSONie napiszę sam w dowolnym języku w ciągu góra 1 dnia, a w przypadku WebServices banalne rzeczy zrobię w ułamku sekundy, ale gdy trafię na coś bardziej złożonego [czyli np. użycie WS-Security] to najpierw zużyję kilka dni na stwierdzenie, która biblioteka z dostępnych na rynku akurat tu mi pomoże, a później będę musiał ślęczeć tydzień nad dokumentacją by się dowiedzieć jak to działa, tudzież okaże się, że akurat tego się nie da zrobić.
Dlatego wiele słodyczy składniowych mnie nie przekonuje bo właśnie zwykle ułatwiają proste rzeczy, ale nie pomagają zbytnio w skomplikowanych sprawach ;-)
Znając LINQ nie musisz znać SQLa, ale w pewnym momencie możesz trafić na sytuację, że rezultaty na różnych bazach danych zawierających te same dane są różne i jak to wytłumaczyć testerom? ;-) No i jak to naprawić?
1)Wirtualne metody - Powiedz mi szczerze jak często spotykasz się z tym, żeby programiści używali final wtedy, kiedy potrzeba? Ja się z tym spotykam naprawdę rzadko nawet w uznanych projektach. Nie nazwałbym tego napewno zamachem na polimorfizm... zastanów się czemu we wszystkich systemach administracji prawo "deny" ma pierwszeństwo nad prawem "allow". Tego się będe niestety trzymał i nie odpuszczę. Problemu zgadywania co się wykona w danym kontekście nie unikasz, bo tego problemu nie powinno się w ogóle stwarzać (co zostało uznane za jedno z podstawowych praw agile).
OdpowiedzUsuń2)Czas przeszukiwania tabel wirtualnych to nie musi być pikuś - ziarno do ziarnka. Myślisz, że twórcy gier komputerowych też tak mówią?
3)Nie pisałem o P/Invoke tylko o J/Invoke. Pogoogluj sobie. Jest to takie JNI zainspirowane włśnie P/Invoke (proszę, nie oskarżaj mnie, że nie wiem co jest, a co nie dostępne w Javie:P).
4)To, że akurat podoba ci się w jakimśtam stopniu ASP.NET baaardzo mnie dziwi. Oczywiście jeżeli masz na myśli WebForms. O ile małe rzeczy może i pisze się w tym szybko i fajnie.. ale wg mnie jest to zdecydowanie najgorszy punkt całego .NET - coś od czego trzymam się zdala na kilometr. Cholernie trudne w utrzymaniu, całkowicie nie testowalne, cięzkie w rozwoju. Nie wiem np jak ktoś, kto zakosztował Rails albo Django, mógłby patrzeć bez niechęci na to coś. Mam nadzieję, że ta technologia odejdzie w niepamięć zastąpiona przez ASP.NET MVC. O ile ta druga technologia nadal nie jest taka fajna jak Rails czy Django to łączy jednak podejście z tych technologii z .NET. Mam nadzieje (o czym pisałem już wcześniej), że dynamiczny C# (DLR dokładnie) sprawi, że ASP.NET MVC stanie się taki fajny jak Railsy. Moze kiedys...... ale o "normalnym" ASP.NET (czyli WebForms) nie wspominaj przy mnie, bo dostaję gęsiej skórki.
5)Czy to, że LINQ to element języka to coś złego? Czy trzeba go używać? Chyba nie.
Jak czesto piszę zapytania w stylu jakim napisałem? W moich C#owych projektach cały czas. I to nie na bazie danych. Na normalnych tablicach, listach, słownikach, xmlu i wszelakich obiektach. Jeżeli chodzi o LINQ na bazach danych to jest to coś innego. Potraktuj to jako formę ActiveRecord, a nie zamiennik SQLa. Spytaj się jakiegoś programisty Ruby jak czesto korzysta z bloków - odpowie ci, że cały czas.. a LINQ to własnie takie C#owe bloki. Bo LINQ to nie jest coś, z czego się od czasu do czasu korzysta, tylko to jest inna forma podejścia do danych zaczerpnięta bezpośrednio z języków funkcyjnych. SQL to inna sprawa. Mamy w pracy hurtownię danych. Nie mam z nią zbyt bliskiego kontaktu - tym się zajmują osobni ludzie. Oni nią administrują, dostrajają, piszą procedury składowane z których potem korzystają inni. To jest troche inna skala zastosowań - zrozum (powtórze to chyba po raz trzeci): nie ma uniwersalnych narzędzi - narzędzia powinno się dobierać odpowiednio do problemu.
Tylko, że często, kiedy pobieram dane z hurtowni przy pomocy jakiejś procedury, to musze jednak te dane trochę obrobić, gdyż te procedury są zbyt ogólne. Naprawdę byłoby mi milej, gdybym miał LINQ sdo pomocy.
6)Cieszę się, że masz wpływ w pracy na to z czego będziesz korzystał. Większość programistów w dużych firmach nie ma danego wyboru, czy pomiędzy słowem kluczowym "if" a "(" dawać spację czy nie.
7)Jeżeli chodzi o stop() i abort() to się bardzo mocno mylisz. One nie działają tak samo! Konwencja dotyczaca wątków jest całkowcie zrozumiała i wynika ona z budowy systemów operacyjnych oraz zarządzania w nich pamięcią. Ogólnie wątki są encjami na niższym poziomie abstrakcji niż metody javove czy C#, które chodza na tych wątkach. W C# i w Javie jest to trochę inaczej rozwiązane - stąd twoje niezrozumienie tej różnicy. Zatrzymanie wątku w stystemie to jego zatrzymanie i tyle. Wątek chodzi, zatrzymujesz go i w tym momencie koniec - wątek jest dead. Problem pojawia się wtedy, kiedy wątek używał jakiś dynamicznych danych. O ile w C++ o tym się po prostu pamięta, bo ma się nad tym kontrolę, o tyle w C# i Java tej kontroli nie ma. A wątki mogły przecierz zaalokować jakieś dane, coś na nich robić etc etc. W Javie nie zaleca się używania stop(), bo zabija ona bezpośrednio wątek systemowy, co może spowodować, że część danych może spowodować niespójność danych. W C# abort() działa zupełnie inaczej. Metoda ta rozpoczyna cały mechanizm zabijania wątku. Najpierw czeka na moment kiedy wątek będzie mógł być bezpiecznie przerwany (Java nie robi nawet tego), ustawia flagę przerwania wątku, dodaje metodę obsługi przerwania wątku do jego kolejki asynchornicznych wywołań i wznawia wątek. Wątek wywołuje metodę obsługi przerwania, która ustawia wątek w stan przerwania, zgłasza wyjątek i po jego obsłużeniu (lub nie) dopiero kończy wątek systmowy. Innymi słowy, o ile takie przerwanie wątku w Javie nie jest bezpieczne (i metody stop nie powinno się w ogóle używać), to w .NET jest bezpieczne na 100%, a ów uzytkownik MSDN, o którym wspomniałeś, się głęboko mylił (zapewne myślał, że sprawa wygląda tutaj tak samo jak w Javie). Z resztą ten przypadek jak dla mnie świadczy jednoznacznie na korzyść .NET. Nie wiem, jakim prawem w javie metoda stop() w ogole się znalazła w takim kształcie.
OdpowiedzUsuń8) Co do przykładu z dzieleniem przez zero to się znowu nie zgodzę. Zależy to, tylko li od sytuacji. Jak wsponałem, pracowałem kiedyś w pewnej firmie w Krakowie (która potem została przejęta przez Autodesk), a która zajmowała się opragromawniem inżynieryjnym. Uwierz mi, gdyby sprawdzać "z buta" wszystkie operacje aytmetyczne to byłoby ciężko...
9)Tak ci przeszkadza ta literka "I"? Dla mnie jest to trochę natręctwo. Nigdy mi nie przyszło do głowy, żeby rozwiązanie przyjęte przez Javę albo C# mogłobyć lepsze lub gorsze od tego drugiego. Czy konwencje są czymś złym? Hmmm.. wnioskuję, że wy w tym Sabre macie naprawdę lekko pod tym względem:P Np cały Ruby opiera się na konwencjach - Duza litera=stała, rozdzielanie podkreśleniami itd. Do notacji węgierskiej też nie mam wielu zarzutów. Korzystałem z niej swojego czasu i nie było źle. Myślę, że jej czasy odeszły w zapomnienie, ale naprawdę... są o wiele gorsze rzeczy, których możnaby się czepiać. Do dzisiaj za to stosuję w pracy obowiązkowo "pozostałości" tej notacji pisząć w Pythonie. Nie cały czas, tylko wtedy kiedy wiadomo, że po jakimś czasie (lub dla obcej osoby) mogłoby to (wywnioskowanie typu zmiennej) sprawiać kłopot. Jeszcze raz... dla mnie zarzut z literka "I" jest hmm... nie wiem co powiedzieć... jest najdziwniejszym zarzutem wobec jakiegoś języka z jakim się spotkałem kiedykolwiek.
10)Z wnioskowaniem typów ech.. jak dzielisz int przez int to otrzymasz int. Czemu mialbyś nie wiedzieć co dostaniesz? To chyba nie jest trudniej zapamiętać niż w językach dynamicznych. W Pythonie dostaniesz 3 z hakiem, w Ruby (który jest stuprocentowo-dynamiczny) dostaniesz 3 dokładnie tak, jak w C#. Jak dla mnie ten argument jest więc całkowicie z kosmosu. Poza tym, kto by w ogóle próbował używać wnioskowania typów do czegoś takiego. Nigdy się nie spotkałeś z listami słowników z kluczami o typie z bardzo długą nazwą i warościami będącymi listami innego typu o długiej nazwie? To jedna rzecz. Druga -atut wnioskowania typów w C# wynika z C#owej specyfiki, a mianowicie LINQ. Jesteś w stanie tworzyć naprawdę baaardzo skomplikowane zapytania (wielokrotnie złożone, z przekazywaniem wyników do kolejnych zapytań etc). Jedyne na czym musisz się wtedy skoncentrować to samo zapytanie, a nie to jakiego typu jest wynik, bo wynik może być typu anonimowego (i często tak jest).
OdpowiedzUsuń11)Wolisz REST od WS. To jest kolejna rzecz której nie rozumiem. Tam gdzie trzeba używać usług REST używasz REST, tam gdzie WS, używasz WS. Dla mnie te architektury nie są zamienne. A czy to taki problem pisać WS? Heh.. problem to było pisać gołe aplikacje korzystające z dużych WS i publikujące WS. Rozwiazanie problemu jak dla mnie przyniósł.... .NET, a konkretnie WCF, który jest po prostu świetny. Co prawda, Ms na poczatku olał świat REST (biznes bazuje przede wszystkim jednak na WS), ale poprawił się w tym względzie. Ogólnie WCF sprawia, że można zapomnieć o WS-Security. Radze ci się zainteresować tym wynalazkiem, bo jest wg mnie naprawdę najlepszą technologią w świecie ogólnie aplikacji rozproszonych. W Javie robiłem to samo z wykorzystaniem WSS4J... niestety, ale nijak to się ma do rozwiązań WCF. W cholerę więcej kodu, strasznie słabo wyrazistego, trudnego do utrzymania, strasznego do debuggowania.. grzebanie się we flakach SOAPa zamiast pisanie logiki.. w ogóle masakra.. syf, kiła i mogiła.
Hmm.. z ciekawości odwiedziłem stronę J/Invoke i okazało się, że życzą sobie kasę za każde użycie ich biblioteki (kiedyś chcieli pieniądze tylko za użycie komercyjne). Nie polecam więc. Istnieje jeszcze coś, co się nazywa JNA, ale nie miałem z tym większej styczności. Bądź co bądź, z tego co czytam, JNA wcale nie jest gorsze od J/Invoke.
OdpowiedzUsuń1) akurat w naszym kodzie praktycznie nigdy, ale to dlatego że zwykle każda z metod może zostać nadpisana i takie jest założenie w trakcie pisania [co ułatwia szukanie błędów bo można łatwo dotrzeć do miejsca skąd przychodzi zła wartość czy coś podobnego]
OdpowiedzUsuń2) kto normalny w C# lub Java'ie pisze gry? To są języki wykonywane przez maszyny wirtualne i przy pierwszym uruchomieniu danego fragmentu kodu zwykle "lecą w trybie" interpretowanym, a wtedy czas wyszukiwania nie jest istotny, przy kolejnych wykonaniach gdy JIT i podobne wchodzą do gry to może być istotne, ale wtedy już wiadomo co dla danego obiektu czy typu wołać więc jak dobrze pójdzie to nie trzeba już będzie tutaj nigdy nic wyszukiwać.
3) mój błąd, sam znałem tylko JNI i JNA, z czego JNI jest straszne, JNA miłe, ale oba na tyle kłopotliwe [choć JNA dużo mniej jednak] by zniechęcać developerów od używania kodu natywnego, co jest dobre bo nie wiąże do OSa, czy trybu pracy procesora [ani .NET, ani Java nie są w stanie wykonać kodu natywnego o innej "bitowości" niż "bitowość" srodowiska, czyli 64 bitowe JRE czy .NET nie wykona 32 bitowego kodu natywnego]
4) Nigdzie nie napisałem, że mi się podoba ASP.NET, nie podobało mi się gdy w nim pisałem [choć możliwe, że to przez jakość kodu w tej firmie gdzie go miałem pecha używać]. Napisałem jedynie, że moja firma marzeń ma jeden duży projekt na .NET [najbardziej niestabilny] i akurat w tym projekcie bym nie chciał pracować [ale rozwijają go głównie w Brazylii chyba więc nie mam problemu ;)]
5) u mnie to my momentami [w sensie nasz kod] jesteśmy hurtownią danych ;-) i u nas LINQ by nie pomógł, mamy zbyt dynamiczne zapytania. A co do czynienia z LINQ części języka, to jest to wprowadzanie kolejnej komplikacji do języka "bo się komuś może przydać".
6) oficjalnie to ja jestem od wybierania co najmniej części technologii, których używamy ;-) bycie lead developerem zobowiązuje ;-) choć sam lubię gdy robi się ten wybór przy dyskusję z ludźmi którzy jej będą używać bo to wtedy lepiej działa.
7) możesz podać jakieś źródło na poparcie swojej tezy? Jedyna różnica jaką widzę jest to, że ThreadDeath w Java'ie nie zostanie automatycznie rzucony po złapaniu w metodzie, a stanie się tak z ThreadAbortException w C#, ale oba wyjątki powodują to samo, czyli zdjęcie wszystkich monitorów synchronizacyjnych i przez to mogą prowadzić oba do pozostawienia obiektów synchronizowanych w nieokreślonym stanie, dodatkowo oba pozostawią problem ze zwalnianiem zasobów [czyli trzeba to robić po ich złapaniu]. W ogóle w Java'ie stop nie zabija wątku systemowego, on zginie dopiero po wyjściu z finally "łapiącego" wyjątek ThreadDeath. Czyli stop() zaznacza wątek jako ubity i JVM zabije go w systemie dopiero po opuszczeniu finally, dlatego jeżeli w catchu łapiącym ThreadDeath nie zrobimy rethrowa, a po prostu zawołamy jeszcze raz run() to wątek może to przeżyć, zginie tylko wtedy gdy [pomijamy sytuację gdy za dużo razy rekurencyjnie wywołamy run() ;-)] w tym catchu łapiącym ThreadDeath poleci jeszcze raz ThreadDeath, a to możliwe jeżeli będziemy wołać stop() w pętli. Ale nie ma tu nic z ubijania wątku systemu operacyjnego bez współpracy z JVM! To JVM zabija wątek i to ona określa warunki tego zabicia wątku. To działa tak samo w .NET jak i w Java'ie. Z tym, że w Java'ie oznaczono takie rozwiązanie jako Deprecated w Java 1.1 albo 1.2 a w C# do teraz jest to OK.
8) Można łapać wyjątek, ale nie w takiej sytuacji jak w przykładzie który podałem. Tam wyjątek został wyrzucony nie dlatego, że coś poszło nie tak w obliczeniach, ale po to by przypisać zmiennej wartość w pewnej konkretnej sytuacji. Wyjątki służą do obsługi sytuacji wyjątkowych, a nie do sterowania przepływem. W przykładzie który dałem było by to OK, tylko w sytuacji gdy wartość 0 w b byłaby spowodowana czymś czego nie jesteśmy w stanie przewidzieć/nie byłaby wartością dopuszczalną, ale nie wolno tego tak użyć tylko po to żeby obsłużyć sytuację gdy b=0, bo po pierwsze to strasznie drogie [bo wyjątki są wolniejsze do if'a [choć nie sprawdzałem o ile]], a po drugie utrudnia to czytanie kodu.
OdpowiedzUsuń9) W Motoroli też mieliśmy lekko, była coding convention i była używana, ale coding convention służy do zapewnienia spójności całego kodu w firmie, a nie powinna służyć do nadrabiania "braków" w języku. Mówiąc inaczej, jeżeli wszędzie w kodzie interfejsy zaczynają się do I, a jest jeden wyjąteczek który tego I na początku nie ma to w przykładzie z deklaracją klasy NIE WIESZ, że to jest interfejs, nie masz pełnej informacji.
10) A ja się spotkałem z tym problemem w Go, Go uznało, że ja chcę użyć typu float, ale później wymagało ode mnie typu float64 [najlepsze, że jako parametru :-)] i przez to zostałem zmuszony do zmiany kodu z użycia var a=10.0 na użycie a:float64=10.0 czy jakoś tak.
Wnioskowanie typu ma pomagać, a nie utrudniać. W przypadku list pomoże, w przypadku prymitywów może spowodować problemy, szczególnie w językach które nie potrafią jakoś sensownie obsługiwać rzutowania [a Go wydaje się na razie nie potrafić ;-)]
11) Widzisz, WS to tryumf podejścia "informatyka" nad podejściem programisty. REST jest prosty i czytelny, WS jest zamotany. Do REST możesz wystartować w dowolnym języku i w ciągu dnia czy mniej napiszesz całą maszynerię do obsługi REST, w WS musiałbyś napisać gigantyczną kobyłę by móc skorzystać z 1 czy 5 metod na odległej maszynie. Na szczęście świat IT już to zrozumiał i WS są w defensywie i ustępują miejsca rozwiązaniom RESTowym. Google wyłączyło już rok temu czy jakoś tak swoje WSy, i wszystko robi na REST.
Technologia ma służyć, a nie zmuszać do służenia. Np. do serwisów tłumaczących Google można dostać się z dowolnego języka który potrafi połączyć się z siecią i może to zrobić każdy kto przejrzy góra 2 strony dokumentacji, by skorzystać z technologii PWN dostępnej przez Translatic'ę [też tłumaczenie i to lepszej jakości często niż Google'owe] trzeba najpierw przebrnąć przez dokumentację Web Services/dokumentację biblioteki i dowiedzieć się jak używać WS-Security i zrobisz to tylko w języku który ma biblioteki które akurat WS-Security wspierają, przez to w Pythonie mi się nie udało do draństwa podłączyć choć próbowałem przez ładnych parę dni, w Java'i zresztą też bo uznałem po 3 dniach przeglądania różnych bibliotek, że jak będę potrzebował tłumaczenia to choć mam nadal darmowe konto do Translatica'i to użyje Google bo będzie to prostsze.
WS to kolejny przykład czynienia rzeczy łatwych łatwiejszymi i utrudnianie robienia rzeczy ciut bardziej złożonych. Inna sprawa, że nadal są poważne problemy w interoperacyjności WSów między np. .NET a Java'ą.
1)Równie dobrze mógłbym uzasadniać to, że pola powinny być domyślnie publiczne, bo w kodzie, który piszę nie ma potrzeby tego, żeby były prywatne - nie trzeba się motać z getterami i setterami a na dodatek, kiedy naprawdę trzeba, to można przecież ustawić je jawnie jako prywatne. Cóż.. chyba się nie dogadamy w tej kwestii. Ja będę stał po stronie hermetyzacji.
OdpowiedzUsuń2)Kto normalny pisze w C# lub w Javie gry? To pytanie to chyba żart? Codziennie wychodzi kilkadziesiąt (sic!) gier w Javie i C#. Java króluje na komórkach, a C# w tzw casualach na XBoxa. Jezeli chodzi o uruchamianie po raz pierwszy... C# nie leci nigdy w trybie interpretowanym! Programy .NET są zawsze w całości kompilowane przed wykonaniem po raz pierwszy. Dlatego pierwszy raz uruchamiają się wolniej, ale po uruchomieniu lecą z ta sama prędkością, co przy kolejnych uruchomieniach!
3)Jest możliwość pokonania problemu bitowosci. Jest na to stosunkowo (kładę nacisk na słowo stosunkowo) prosty sposób pod Windows. Pod systemami Unixowymi trzeba by się bardziej namachać. Pierwsza opcja - tworzysz serwer COM dla 32bitowego kodu i korzystasz z interfejsow COM do komunikacji z nia. Druga opcja - ładujesz go do 32bitowego procesu, z którym porozumiewasz się za pomocą IPC. Przerabiała to chyba każda większa firma informatyczna, kiedy zaczęły wychodzić pc-towe systemy 64bitowe:)
4)Czyli przynajmniej co do ASP.NET się zgadzamy. Chociaż chciałbym znowu podkreślić, że widzę duże nadzieje z ASP.NET MVC tak, jak wiąże zdecydowanie większe nadzieje z Groovy niż Javą jezeli chodzi o aplikacje webowe.
5)Wsadzanie LINQ do języka, bo może się komuś przydać jest bez sensu? W tym momencie przekreśliłeś takie jezyki jak: SmallTalk, Ruby, Scala, Groovy i wiele wiele innych!!
6)Hmm.. oczywiscie. Jakies pole wyboru jest, ale jak duze? Gdybys chcial napisac część kodu z wykorzystaniem w/w Scala to pozwolonoby ci? Jeżeli tak to wracam do Polski i składam papiery do Sabre:)
7)Z tymi wątkami zbiłeś mi ćwieka. Jeżeli chodziło mi o zabijanie wątków od razu to nie chodziło mi o to, że dzieje się to bez finalizacji tylko o to, ze Java nie patrzy czy wątek może zostać bezpiecznie ubity i kiedy ostatecznie zostaje ubita javowa encja wątku, zostaje ubity także wątek systemowy. Wyobraź sobie metody w trakcie natywnych wywołań. Java będzie miała to gdzieś i wyrzuci ThreadDeath, który zakończy wątek, .NET poczeka do zakończenia wywołania i dopiero wtedy wyrzuci wyjątek. Wygrzebałem aż pewną książkę, którą kiedyś czytałem "CLR via C#" (Autor: Jeffrey Richter). Książka ta dokładnie opisuje cały CLR z .NET 2.0 z perspektywy jego flaczków. Z książki wynika, że procedura ubijania wątku w .NET jest wręcz bardziej skomplikowana niż ta, którą przytaczałem. W każdym razie wg autora, procedura ta jest po tym względem bezpieczna. Zakładanie locka (Monitor.Enter) wywołuje metodę Thread.BeginCriticalRegion, wyjscie z locka wywołuje EndCriticalRegion (obie metody są w miarę dobrze udokumentowane). Wszelkie alokacje wewnątrz takiego bloku sa automatycznie oznaczane jako krytyczne. Abort wewnątrz tej sekcji wywoła jako zabezpieczenie procedurę wyładowania domeny aplikacji. Czyli jednak mechanizm ubijania wątku w C# i w Javie wygląda inaczej:))))
8)I tutaj też się zgadzamy. Nigdy nie twierdziłem, że ten przykład jest usprawiedliwiony. Bardziej chodzi o to, że granica przewidywalności i nieprzewidywalności nie jest czasami zbyt jaskrawa. Jako ciekawostka - w języku Ruby throw/catch są używane własnie do sterowania przepływem (wyjąki obsługuje się przy pomocy raise/rescue).. mam nadzieję, że nie przyprawiło cię to o zawał;)
OdpowiedzUsuń9)Po pierwsze, mając konwencję z interfejsami zaczynającymi się od literki "I", jakby coś takiego (brak tej literki na początku) mogło przejść w normalnej firmie? W sztywniejszych metodykach zostałoby to wyłowione przez kogoś innego przy walidacji, a w lżejszych przy refaktoryzacji. Nie znam żadnej uznanej metodyki, która pozwoliłaby na przepuszczanie czegoś takiego, ale ok - powiedzmy, że się zdarzyło.. Visual Studio z miejsca pokazuje, czy dany typ to interfejs czy klasa - wystarczy na niego najechac myszka, albo dać "go to definition":) Myślisz, że naprawdę mogłoby to sprawić jakiś poważniejszy problem?
10)Niestety, ale nie miałem do czynienia Go. Nigdy nic nie napisałem w tym jezyku. Za to w językach, które wcześniej wymieniłem, naprawdę nie słyszałem o jakiś problemach z wnioskowaniem typów. Tak jak już wspomniałem, nie ma sensu używać tej opcji dla bardzo prostych typów. Z resztą... wnioskowanie typów dosięgnęło nawet C++ (najnowszy GCC je obsługuje, VC++ 2010 Beta z tego co widzę - też).
11)Ja też trochę ponarzekałem w pewnym momencie na WS, ale z tego co zauważyłem i miałem okazję popróbować, wydaje mi się, że większość problemów jest rozwiązywana przez WCF (jak np grzebanie się we flakach WS-*). Pisanie WS w Pythonie moglo byc rzeczywiście ciężkie... no cóż.. mówiłem już, że wyznaję zasadę dobierania odpowiedniego narzędzia do odpowiedniego problemu?:P. Chodzi mi bardziej o to, że REST nie jest w stanie całkowicie wyprzeć WS. Przyznaję, że REST jest o wiele prostszy i lepszy w wielu zastosowaniach, w których wcześniej były używane WS. Ale nie mozna nim zastąpić wszystkiego. Jakbyś chciał zaimplementować obliczenia rozproszone na REST? Wyobrażasz sobie system bankowy oparty na REST? Rozproszone transakcje, glosowania, złożone informacje o błędach - tego nie zastąpisz przy pomocy REST.
1) Ale poliformizm nie zaprzecza hermetyzacji, on na niem bazuje, właśnie po to wszystkie pola są prywatne by dostępne były tylko przez Twoje API, dzięki czemu klasy potomne też muszą używać dostępu do pól w klasie bazowej prze to API. A tworząc API udostępniasz tylko to co należy.
OdpowiedzUsuń2) Akurat KVM dla komórek to inna para kaloszy i tam zwykle nie ma w ogóle wyszukiwania metod w tablicy metod wirtualnych, szczegółów już nie pomne, ale są dość ciekawe. No i nawet Google w przypadku Androida uczula by w przypadku pisania dla Androida używać innego podejścia bo urządzenia mobilne programuje się inaczej [np. nie należy używać wtedy jako typów zmiennych czy parametrów interfejsów, a klas konkretnych]. A to nie wiedziałem, że tam nie ma JIT podobnego jak w Java'ie.
3) O tym wiedziałem, ale to jest dodawanie kolejnej warstwy między kodem w CLR/JVM a natywnym, czyli kolejny narzut czasowy, a w takim przypadku czasem warto w ogóle wyrzucić w cholerę korzystanie z kodu natywnego jak tyle czasu ma być spędzane w tej "warstwie".
5) Tak przekreślam je jako języki ogólnegoprzeznaczenia, mogą być językami domenowymi, taki np. Python świetnie się zagnieździł w pewnej domenie.
6) W mojej części pewnie gdybym się uparł to bym przepchnął Scale, z tym że musiałbym mieć poparcie innych developerów żeby nie wleźć w technologię, której nikt nie zna.
7) W Java'ie kod natywny nie jest w ogóle przerywany przez stop(). Jeżeli wątek wykonuje kod natywny to puki nie wróci do JVM to JVM nie przerwie wątku [za wyjątkiem sytuacji gdy będzie System.exit(), ale to jest ubicie JVM co pociąga za sobą zabicie wszystkich wątków przez system operacyjny]. Nawet jeżeli w kodzie natywnym użyte jest Sleep(int) z WinAPI [bo testuje na Windows] to wątek nie jest przerywany. Na razie testowałem to z JNA, ale podejrzewam, że z kodem natywnym z JNI jest identycznie. To samo w C#/.NET, sprawdziłem przed chwilą i Abort() nie przerywa kodu natywnego, co zresztą jest dość logiczne.
7 kontynuacja ;-) ) No i z JVM jest jeszcze tak, że wątki wcale nie muszą być wątkami systemowymi, na systemach nie wspierających wątków twórcy JVM mogą to zaimplementować po swojemu, choć inna sprawa, że nie słyszałem o JVM która by robiła wątki inaczej niż w oparciu o systemowe.
OdpowiedzUsuńOgólnie jak widać JVM i .NET podobnie to traktują, w obu wyjątek nie poleci jeżeli wykonywany jest kod natywny, co oznacza że np. oczekiwanie na coś co ma przyjść z sieci w przypadku socketów blokujących oznacza, że Abort() czy stop() nie przerwą wątku. I w obu to wyrzucenie wątku jest tak samo niebezpieczne, bo jeżeli go jawnie nie obsłużysz to możesz skończyć z obiektami w "niepewnym" stanie ;-)
Tutaj http://www.przemelek.pl/file/z.zip masz programiki, które napisałem w Java'ie i C# do przetestowania tego, w dllmain.c jest kod "natywny" :-) z którego jest JNAToster.dll. Program w C# to Program.cs, Java'owy to JNATest. Wszystko trzeba uruchamiać na 32 bitowej Java'ie i 32 bitowym .NET bo dll'ka jest też 32 bitowa.
9) Błędy się zawsze zdarzają, inspekcja nie wyłapie wszystkiego, a wsparcie przez pokazywanie przez VS to mało, bo wymaga od Ciebie działania polegającego na przejechaniu myszką, a to jest np. niemożliwe gdy robisz inspekcje kodu [taka prawdziwą, faganowską z wydrukowanym kodem. jajx jak ja tęsknię za tym jednym aspektem Motoroli :-)]
10) W tym Go im się to nie udało, w takim JS też bywają problemy, dlatego co jakiś czas trzeba dokonać jawnej konwersji, która akurat w JS jest dość zabawna ;-) bo gdy JS nie wie czy coś jest String'iem czy int'em to najlepiej chcąc dostać int'a zrobić mnożenie razy 1, a by dostać String'a zrobić dodawanie z dowolnym stringiem.
11) Python jest dość często używany z WS :-) A obliczenia rozproszone i inne wymienione przez Ciebie rzeczy da się spokojnie zrobić w REST, przecież na dole oba maja to samo, czyli HTTP, faktem jest jednak, że może się okazać, że w pewnych zastosowaniach dla REST będzie trzeba zaimplementować własne mechanizmy, które WS może już mieć.
1)Tak samo pisząc metody powinieneś udostępniać jako wirtualne tylko te, o których wiesz, ze nie zepsują działania twojej klasy. Ja nie widzę różnicy.....
OdpowiedzUsuń2)Nie mam żadnego doświadczenia w pisaniu w Javie dla urządzeń mobilnych, więc jest mi się naprawdę trudno na ten temat wypowiedzieć. W C# z reszta też nie.. z tego co tylko widziałem w C# dostaje się gratisowo WinForms i SqlServer przez co nie ma teoretycznie większych rozbieżności pomiędzy pisaniem na desktopy i na komórki.
3)IPC rzeczywiscie potrafi być wolne, ale COM jest bardzo szybki. Tutaj .NET ma znowu trochę przewagę, bo jest bardzo dobrze dostosowany do współgrania z COM.
5)Python językiem domenowym? Przez języki domenowe rozumiem tylko te języki, które nadają się do zastosowań w pojedynczych dziedzinach. Python natomiast udowodnił (moim zdaniem), że nadaje się zarówno do aplikacji webowych jak i symulacji fizycznych. Językiem dziedzinowym może być tutaj dla mnie Django. Scale tez przekreślasz? Przecież to jedna z najlepszych rzeczy jaka wyszła w ciągu ostatnich lat i napewno nie jest to język dziedzinowy!
6)Ja się spotkałem z przypadkami, kiedy grupa programistów chciała przepchnąć technologię, którą dobrze zna, ale ktoś u góry powiedział "nie i koniec" i na tym się skończyło (btw. to była właśnie Scala). Cóż, takie są uroki molochów..
7)Hmmm.. widzę, że mocno się nie zrozumielismy w tym względzie. Pozwól, ze rozwinę ten temat w nastepnym poście.
9)Powiem inaczej..... nigdy nie słyszlaem o tym, żeby jakikolwiek zespól C# miał kłopoty, bo ktos zapomniał literki "I". Skończmy ten temat proszę, bo dla mnie na prawdę ten zarzut jest zbyt "z kosmosu", żeby o nim dyskutowac.
10)JS nie ma wnioskowania typów! JS jest w 100% dynamicznie typowany, więc nie potrzebujesz żadnego wnioskowania! To, o czym piszesz, to problem z niejawnymi konwersjami dokonywanymi przez JS, a nie z wnioskowaniem typów. Wnioskowanie typów to cecha języków statycznie typowanych, kiedy to KOMPILATOR (a nie runtime, tak jak w JS) określa typ na podstawie wyrażenia. To sa dwie różne rzeczy!
11)Będziesz potrzebował takiego przebudowania typowego schematu dla REST, że to, co otrzymasz nie będzie już tak naprawdę REST (albo przynajmniej będzie bardzo odległe od tej ideii). Póki co, do tych zastosowań pasuje jak ulał WS-* i nie widzę sensu wpychanie w to REST tylko li dla zasady.
7)Cd.. nie mowie o przerywania wywołania metody natywnej, bo to jest niemożliwe. Chodzi mi o to jak Java i .NET traktują wątki (te niskopoziomowe, a nie javowe, albo .NETowe). Weź za przykład taki bardzo prosty kod:
OdpowiedzUsuńDWORD WINAPI Run( LPVOID );
HANDLE mtx;
void ThrCall(void)
{
cout << "native: start" << endl;
HANDLE thr1;
HANDLE thr2;
DWORD tid1;
DWORD tid2;
mtx = CreateMutex(NULL, FALSE, NULL);
thr1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) Run, NULL, 0, &tid1);
thr2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) Run, NULL, 0, &tid2);
HANDLE thrs [] = {thr1, thr2};
cout << "native: thr wait" << endl;
cout << "native: end" << endl;
}
DWORD WINAPI Run(LPVOID prm)
{
if (WaitForSingleObject(mtx, INFINITE) == WAIT_OBJECT_0)
__try
{
cout << "native: thread(" << GetCurrentThreadId()
<< "): got mtx " << endl;
Sleep(1000);
} __finally {
ReleaseMutex(mtx);
}
else
return FALSE;
cout << "native: thread(" << GetCurrentThreadId()
<< "): released mtx" << endl;
return TRUE;
}
----
Oraz owijke dla Javy
extern "C" {
JNIEXPORT void JNICALL Java_Main_DoNtvStart
(JNIEnv *, jobject);
}
--
gdzie Java_Main_DoNtvStart po prostu wywoluje ThrCall
Teraz mam dwa takie same programy dla Javy i dla .NET. Java:
OdpowiedzUsuńimport java.util.*;
class Main implements Runnable {
native void DoNtvStart();
native void DoNtvEnd();
static {
System.loadLibrary("ntvlib");
}
private static Main mn=new Main();
public static void main(String args[]) throws InterruptedException {
Thread th = new Thread(new Main());
th.start();
Thread.sleep(500);
System.out.println("Aborting");
th.stop();
}
public void run() {
mn.DoNtvStart();
}
}
------
C#:
class Program
{
[DllImport("d:\\ntvlib.dll")]
public static extern void NtvDoStart();
static void Main()
{
Thread th = new Thread(new ThreadStart(() =>
{
NtvDoStart();
}));
th.Start();
Thread.Sleep(500);
Console.WriteLine("Aborting");
th.Abort();
Console.ReadLine();
}
}
------
Program Java wyrzuca mi na output:
native: start
native: thr wait
native: end
native: thread(7104): got mtx
Aborting
-----------
Program C# wyrzuca:
native: start
native: thr wait
native: thread(6716): got mtx
native: end
Aborting
native: thread(6716): released mtx
native: thread(7800): got mtx
native: thread(7800): released mtx
Musisz chyba przyznać, że takie zachowanie ze strony Javy jest całkowicie niedopuszczalne! Przecież co jeżeli moje wątki zaalokowały dużo pamięci? Memory-leak gotowy! Oczywiście pisząc program w Javie nie powinno się dopuścić do zaistnienia takiej sytuacji, bo nie powinno się używać metody stop. Chcę tylko, żebyś zrozumiał, że metody abort z .NET i stop z Javy to sa dwie różne metody i abort nie boryka sie z tymi samymi problemami, z którymi boryka sie stop. Dlatego twoje zarzuty wobec tej metody są w mojej opinii CAŁKOWICIE bezpodstawne. W ogóle .NET jednak (na początku) bardziej się postarał od Javy jeżeli chodzi o wątki. Już nie muszę chyba wspominać o baaardzo długim, wieloletnim oczekiwaniu, aż Java pozbędzie się problemu tzw blokady z podwójnym zatwierdzeniem we wzorcu Singleton - czyli problemu, który w .NET nigdy nie istniał.
OdpowiedzUsuńps. Jeżeli chcesz kody źródłowe i/lub binaria w/w programów w postaci archiwum Windows lub Linux to daj znać.
1) Jest różnica, bo gdy wszystko jest wirtualne nie dochodzi do sytuacji, że wołanie tej samej metody na tym samym obiekcie może dać różne wyniki zależnie od kontekstu w jakim go użyjesz.
OdpowiedzUsuń2) Standardowo w JME czy tej Google'owej wersji dla Androida pisze się tak samo jak w zwykłej Java'ie, ale KVM [czyli maszyna dla JME] zwykle działa w dość specyficzny sposób mieszając znacznie kod natywny z Java'owym. Zresztą część procesorów dla urządzeń mobilnych ma zdolność do wykonywania bytecode'u Java'owego :-)
3) Możliwe, ale nadal [i tu mi się wydaje bo nie wiem jak to działa w rzeczywistości] jest tu punkt pośredni przez system operacyjny. Ale głowy nie dam :-)
5) Zwykle spotykałem się z Pythonem w Web i w robieniu niektórych bakcendów, aplikacji "okienkowych" się w nim raczej nie robi. Scala to też głównie Web, choć nie musi to być tylko to. Java i C# są wykorzystywane w okienkach, mobile, backednach i webie, no i trochę smutno wkładać do języka elementów które są przeznaczone do pewnej domeny, fajniej by było gdyby zrobili z tego rozszerzenie w postaci biblioteki [a patrząc na LINQ nie byłoby to znów takie trudne], choć może się mylę z tym LINQ? Czy on generuje coś na poziomie tego CLRowego bytecode'u? I czy w specyfikacji jest oddzielny kawałek dla LINQ?
6) To się zawsze może zdarzyć, ale głównie gdy idzie z pomysłem "przepiszmy wszystko".
7) Problem nie jest w Abort() czy stop(), bo one jak nadal twierdzę działają tak samo, problem jest w tym, że w Twoim programie JVM po prostu się wyłączyła :-) Wygląda na to, że .NET zakłada, że wszystkie wątki wystartowane z wątków C# są używając nomenklatury Java'owej wątkami użytkownika, JVM zaś przyjmuje że są to wątki które są demonami. Jeżeli w kodzie Java'owym dodasz na końcu Thred.sleep(5000); to wszystko zadziała identycznie jak w C#.
kontynujaca 7) Nie ma więc możliwości memory-leaka w Java'ie z tego powodu który przedstawiłeś bo po prostu takie zachowanie występuje tylko w sytuacji gdy JVM jest już ubijana.
OdpowiedzUsuńW Java'ie istniało od początku rozwiązanie które działało, ale ktoś kiedyś naopowiadał ludziom, że synchronized jest złe i dlatego chcieli przenosić do Java'y rzeczy bazujące na modelu pamięci procesora co w przypadku języka niezależnego od sprzętu było nierozsądne. Chcąc uniknąć synchronized można było użyć też idiomu z klasą z polem statycznym. Ale, że ludzie się uparli to zrobiono zmienne volatile trochę bardziej "sztywnymi"
1)Bo do takiej sytuacji nie powinno w ogóle dochodzić (chyba, że jawnie zadeklarujesz, że tak z jakiegoś powodu chcesz). Kompilator C# wyrzuca warningi, które raczej powinny być impulsem do zmienienie nazwy metody, niż robienia shadowa.
OdpowiedzUsuń3)Obiekty COM na serwerach oop są wywoływane przy pomocy niskopoziomowego RPC. Oczywiście niesie to za sobą spadek wydajności, ale wydaje mi się, że w większości wypadków (zwłaszcza na dzisiejszych komputerów) jest to coś, co można bez większego bólu przełknąć..
5)Są ludzie, którzy piszą w Pythonie aplikacje okienkowe. Z resztą samemu parę razy pisałem co nieco w wxPython i nie było najgorzej.
LINQ to jest biblioteka! Tyle, że biblioteka zintegrowana z językiem. Wystarczy, że wyrzucisz z początku programu "using System.Linq" i już go nie masz - znikają słowa kluczowe from, where, select etc etc tak jakby go nigdy nie było:P To, że jest zintegrowany z językiem nadal będę jednak uważał za zaletę. LINQ został zaimplementowany bez żadnych zmian w CLR, ale szczegółów niestety nie znam.
7)Hmm.. rzeczywiście:) To, co wkleiłem to na prędce okrojona część pewnego bardzo niedużego i wiekowego programiku, który wygrzebałem, a który oryginalnie miał własnie sprawdzić jak stop() się zachowuje w stosunku do natywnych wątków potomnych. Oczywiście, to że w C# program się kończył inaczej (nawet bez Console.Readline()) zrzuciłem automatycznie i bez zastanowienia na głównego podejrzanego, czyli metodę stop. Nie przypuszczałem, że problem może tkwić w czymś takim i już zawsze myślałem, że stop ubija wątki systemowe jak leci. To, czego się dzięki tobie dowiedziałem, jest jeszcze gorsze - używanie stop jest niezbyt ładne i tak jak wcześniej napisałem, nie był to dla mnie problem realny. Teraz widzę, że wycieki pamięci przy korzystaniu z natywnych wątków mogą się pojawiać przy normalnie napisanym kodzie. Naprawdę mi się to nie spodobało... co prawda nie spotykam się zbyt często osobiście z JNI (w pracy ani razu w przeciągu powiedzmy 2ostatnich lat), ale jednak...
Co do podobieństw i różnic pomiędzy abort i stop to po przeanalizowaniu metod BeginCriticalRegion oraz EndCriticalregion, nadal będę podtrzymywał, że nie działają one tak samo.
5c.d.)Jako ciekawostka. Słyszałeś o PLINQ? Czyli LINQ zrównoleglonym? Odpalasz normalne zapytanie (niczym się nie różniące od zwykłego LINQ) z tym, że jest one automatycznie wykonywane na paru rdzeniach na raz - fajna rzecz:)
OdpowiedzUsuń1) A nie prościej było wstawić wymóg by nie można było zrobić takiego pseudo override'a na czymś co nie jest wirtualne? :-)
OdpowiedzUsuń3) Ale to oznacza też pewnie, że spokojnie można zrezygnować z kodu natywnego :-)
5) Na początku też myślałem, że to biblioteka ale znalazłem w sieci gdzieś parę przykładów które wyglądały jakby wychodziły poza składnie C#, zamiast lambdy wyglądało to jakoś inaczej i stąd moje przypuszczenie, że to była część języka. Ale w takim przypadku można zaryzykować, że w momencie gdy do Java'y dodadzą domknięcia to pojawi się coś takiego jak JLINQ ;-) choć i tak go pewnie nie będę używał :-)
7) kod natywny to ZŁO! ;-) W 99% przypadków nie ma powodów by go używać, a w pozostałym 1% wynika to z tego, że np. trzeba korzystać z "obcego" softu, który jako całe API udostępnia jedną DLLkę z której można sobie coś tam wołać. Takie coś chyba też przyświecało twórcom Java'y, bo widać, że JNI jest dość "wymagające" [czyli jest szansa, że bawić się nim będą ludzie, którzy choć w części rozumieją zagadnienie], za to JNA które jest prostsze jest dużo wolniejsze ;-) Sami jeszcze chyba w 1.2 i 1.3 używali natywnego kodu do arytmetyki na BigDecimal, ale później przepisali ją na Java'e.
A skąd wiesz, że Java tego też tak nie robi?
stop() został uznany za deprecated dlatego, że może zostawić obiekty w postaci niezsynchronizowanej, Abort ma to samo, i przez to, że wyjątki nie powinny służyć do sterowania przepływem.
1)Hmm.. tutaj pojawia się za to konflikt jak pomiędzy zwolennikami i przeciwnikami bezpośredniego grzebania w pamięci - "więcej możliwości kosztem większej zawodności czy na odwrót?". Oczywiście tutaj jest to o wiele mniej jaskrawe. Ktoś mógłby po prostu chcieć aby jego klasa posiadała pewne zachowania tylko wtedy, kiedy korzysta się z niej bezpośrednio (chociaż muszę przyznać, że nie jestem w stanie na poczekaniu wymyślić takiej sytuacji). Póki co, myślę, że warning w momencie, kiedy nie następuje ani jawny overriding ani shadowing, powinien wystarczyć.
OdpowiedzUsuń5)Chodziło ci zapewne o składnię typu
from u in Users
where u.Age > 40
select u.Children;
Ta składnia jest właśnie wbudowana w C# i często jest bardzo przydatna podnosząc czytelność kodu zwłaszcza przy bardzo złożonych zapytaniach, kiedy np wyniki jednego przekazuje się bezpośrednio do następnego itp. Ona też "znika", kiedy usuniesz referencję do LINQ.
Co do tego czy będziesz używał JLINQ, kiedy takowe powstanie. Popisz przez jakiś czas chociażby w Scali albo Ruby, a gwarantuję ci, że będziesz używał.
7)Kod natywny to zło? Najczęściej tak.. ale czasami po prostu trzeba z niego korzystać, a wtedy powinno się to odbywać w jak najbezpieczniejszy sposób. Co ciekawe, zdarzało mi się pisać dużo kodu natywnego korzystając w Ruby on Rails, gdzie bardzo łatwo można robić wstawki C. Naprawdę nie pogarszają one czytelności kodu, a czasami są wstanie zwiększyć wydajność niektórych obliczeń 20 razy - w tym przypadku to nie jest zło:P Oczywiście w Javie i w C# to nie ma sensu, bo są to zbyt szybkie języki.
Co do problemu osieracania monitorów, wysłałem maila do znajomego z Redmond... który co prawda zajmuje się całkowicie czymś innym, ale mam nadzieję, że uda mu się dowiedzieć czegoś więcej na ten temat u samego źródła.
7) Tak, kod natywny to zło gdy używa się języka takiego jak Java czy C#. Są oczywiście sytuacje gdy trzeba go użyć, bo np. chce się sterować sprzętem, albo akurat mamy taki kawałek kodu, który jest istotny, często wykonywany, ale nadal za wolny choć stosuje się już najszybszy algorytm, w rzadkich przypadkach jeszcze wtedy gdy trzeba się połączyć z innym systemem, który udostępnia jakieś funkcje, ale nie dostarcza wrappera dla danego języka. Ale ponieważ to są krytyczne miejsca systemu to powinny być pisane tylko przez ludzi, którzy świetnie rozumieją oba światy, bo np. po co wyrzucać do natywnego kodu coś co zmniejszy czas wykonania z powiedzmy 100 ms do 10 ms, skoro może się okazać, że całe przekazanie parametrów i wyniku między kodem natywnym, a nazwijmy go po .NETowemu zarządzalnym trwa 50 ms?
OdpowiedzUsuńDo tego kod natywny oznacza zwykle "nieprzenaszalny" i przywiązanie do jednego systemu operacyjnego. Kod natywny może też powodować wycieki pamięci i większą podatność na ataki w stylu buffer overflow. Że już właśnie o przywiązaniu do nawet poszczególnych trybów pracy procesora nie będę wspominał.
A ilu jest wśród programistów takich, którzy potrafią to wszystko dobrze zrobić? 10% Zwykle za to ludzie chcą używać kodu natywnego "bo to szybsze" i zamiast użyć profilera to sami dokonują przedwczesnej optymalizacji, a i tak używają wolnych algorytmów.
Dlatego wydaje mi się, że dobrze jest jak użycie kodu natywnego jest trudne, bo to od razu podnosi poprzeczkę dla programistów którzy się będą tym zajmowali.