Tuesday, December 30, 2008
Тех. Люди #2. Опыт.
Почему этот пункт первый в плане? Потому что это прямо пропорционально твоей зарплате. Об опытном человеке обычно говорят – профессионал своего дела. А некоторые в IT области уже много лет так и не могут заслужить этого названия.
Что же такое опыт? Я полностью солидарен с ЕК, относительно возраста прожект менеджера. Ну не может человек минимум до 25 стать полноценным прожект менеджером, чтобы не говорили. И 18-летний прожект менеджер в Итр@нзишн скорее показывает неопытность и молодость самой компании - это скорее недостаток, чем достоинство.
Закономерно возникает вопрос почему нельзя в 18 руководить проектом?
Ответ прост. Нехватка опыта. Но ведь он самый умный, самый коммуникабельный и лучшее знание языка имеет, ответите вы. Хороший вопрос. Но ответ всё один и тот же – нехватка опыта.
Мы с Юрой В. как-то в последний раз много поговорили о том, что такое опыт и какая его формула. С самого начала мы понимали, что опыт это не просто знание технологий, это нечто больше. А что именно – трудно было сформулировать. Но когда начинаешь говорить об этом - начинаешь находить нужные определения. Давайте ниже посмотрим, к чему мы всё таки дошли.
Опыт = знания + набор готовых решений + уровень уважения к себе.
Давайте по порядку разберём.
- Знания
Вы сами понимаете, что только через горы книг и гранит науки можно добиться в этом деле чего-то. Когда говорят про опыт, то люди прежде всего смотрят в резюме с какими технологиями человек работал, какую техническую роль выполнял.
Извини, но тебя не назовут опытным разработчиком, если ты в конце эшелона последние 10 лет проплёлся и ещё.
Какие знания ещё сюда можно отнести:- иностранного языка
- как системы строятся
- чего можно от молодого специалиста ждать, что от матёрого,
- какие основные проблемы встречаются на том или ином проекте,
- знания как вести себя с заказчиком,
- умение поддерживать отношения с окружающими,
- умение писать корректные письма и т.д.
С этим пунктом можно разобраться проще всего – большинство задач решается упорным трудом, самодисциплиной и желанием получить эти знания. - Набор готовых решений
Здесь можно рассмотреть несколько типов готовых решений:- Материальная часть проектов в виде багажа, который ты повсюду в течение многих лет за собой таскаешь.
Все более-менее проекты, над которыми я лично работал, в виде кода, документации аккуратненько хранятся у меня на диске. И что заметил интересное – довольно часто мне приходится к ним возвращаться (особенно к коду), чтобы достать уже готовое решение, или посмотреть как оно делалось и как его делать не надо.
Не могу не прокомментировать случай, который я увидел между Юрой В. и Ваней Л.
- Ваня, смотри какую штуку мы взяли с предыдущего проекта и всунем его сейчас в текущий, - грит Юра, показывая на шаблон документа, на котором ещё название старого проекта сохранилась.
- Ёпта, это и называется опыт.
Ёпта, полностью согласен с Ваней. Эту материальную часть нужно беречь как зеницу ока и аккуратно собирать её. - Сюда также можно отнести на набор техн. решений в голове. Долго думал, можно ли этот пункт оставить здесь - время, к сожалению, неумолимо. И из проектов прошлых лет, ты помнишь только основные решения и подходы. Но, всё одно, это твои знания.
- Набор решений на проблемные ситуации
Очень часто в этом пункте приходится набивать себе тумаки самому. И ещё чаще нужно несколько тумаков набить, чтобы найти себе какое-нить более-менее работающее решение для одной и той же ситуации. Особенно это связано при работе с людьми или заказчиками.
Получив пару хороших тумаков и пару хороших советов, я сам научился (по крайней мере так надеюсь) что смогу противостоять, когда тебя провоцируют при большом количестве людей. Хорошие тумаки, конечно, были. Не позавидуешь.
Какие проблемы могут встретиться:- Заказчик требует статус репорт, а в реальности ничего не готово
- Заказчик просит в очередной раз посидеть вне рабочее время
- Ты чувствуешь что заказчик пытается сесть тебе на шею
- Решения, принятые не тобой, пытаются столкнуть на тебя
- Синьор девелопер отказался делать таску или выставил на неё такую оценку, что мама не горюй (скажем в пару месяцев)
- Человек не выполняет обязанностей и тебе нужно сказать ему об этом
- Твой коллега занимается посторонними вещами, и тебе нужно сказать ему об этом
- Видишь внутренние конфликты между двумя людьми
- Можно продолжать до бесконечности
- Материальная часть проектов в виде багажа, который ты повсюду в течение многих лет за собой таскаешь.
- Уровень уважения к себе
Это скорее самый важный пункт из всех. Но он не может существовать без предыдущих.
Так что значит этот пункт. Доволно сложный в определении, но попробую. Это не какое-то абстаркное общее уважение к себе. Это ну как бы лучше выразиться. Это когда внутреннее твоё Я требует к себе уважение от других. Требовать относительно к себе отноститься – это ваше право, но здесь речь о другом уважении (уважении к моему мнению).
Пару примеров.
Общение с заказчиком по телефону. Сразу можно заприметить в разговоре малоопытных людей. Они мало говорят, редко переспрашивают, кипятятся когда отвечают. Внутреннее Я этого человека не чувствует себя в безопасности и не требует к себе уважение (т.е. уважения к его мнению), и его голос не звучит убеждённо и вообще его никто особо слушать не будет.
Ещё ярче пример. Посадить человека, незнакомого с IT вообще, между двумя архитекторами во время их разговора о сумрачности двойного вырожденного полиморфизам и... всё. Голос этого человека не будет значить, в принципе, ничего. Хотя он обладает большей реальной властью, чем архитекторы, к примеру, может уволить в любой момент кого захочет из них двоих. Но здесь кроется самое интересное. Человек сам показывает, всем своим видом и поведением, что к моему голосу прислушиваться не следует. Т.е. виноват сам человек, что его так трактуют, а не те которые к нему так относится.
А вот ещё. Приходит 2 человека с одними и теми же знаниями на проект. Одного через некоторое время начинают слушаться и доверять ему, а другого нет, чтобы он не старался делать.
В большинстве своём, человек сам виноват в том, как к нему относятся окружающие, а окружающие, в большинстве, своём не виноваты в этом. Всё зависит от того уровня уважения, которое человек сам к себе требует.
Управлять этим внутренним Я очень сложно. Большинсто оферистов, актёров умеют это делать по-настоящему, когда к его голосу начинают прислушиваются в области, где он ни в зуб ногой.
Ещё с годами у человека всё меньше и меньше остаётся областей, в которых он не может потребовать к себе уважения. И если тот человек между двумя архитекторами старец, у которого целый багажник внуков, и который прожил честную и достойную жизнь, то он не даст себя в обиду и любое слово пророненное этим старцем будет подхвачено архитекторами и рассмаковано и оценено по достоинсту.
Что подкрепляет внутреннее Я. Определённые знания в какой-то области (#1) и набор решений (#2) на ситуации, которые могут возникнуть в этой области + уже достигнутый среди окружащих уровень уважения к тебе. Только тогда ты себя можешь чувствовать как рыба в воде. Только тогда о тебе могут сказать громко - профессионал.
Как заработать дополнительно экспиренса (в героев 3, думаю, многие играли), надеюсь, вы поняли – работать, работать и ещё раз работаться и стараться заработать опыт при любом удобном случае. Помни: за двух небитых, одного битого дают. Поэтому если выпадает шанс на халяву получить экспиренса – получай. К примеру, приглашают на кол поговорить – говори.
Ещё раз напомню. Что это только моё мнение и мой опыт, который может быть вами трактован, собственно, как вам заблагорассудиться.
Тех. люди #1.Вступление.
- Почему я больше всех работаю?
- Почему я провожу на работе 12-13 часов, а другие ребята в 6 часов – go home, и не важно в каком статусе они оставили работу?
- Почему только некоторые люди в команде душой болеют за проект?
- Почему кода приходится так много за другими людьми пересматривать и переписывать?
- Почему люди не хотят учится и расти?
- Наверное, надо было резче сказать, что так делать больше нельзя?
- Я не хочу работать с людьми, мне легче писать код – я для этого учился
- Моё мнение проигнорили сегодня и моё предложение даже недослушали – они не правы
- Я технически очень сильно подготовлен и много читаю, но есть люди, которые с тем же набором знаний, но выше меня
- Как найти подход к человеку, который сильнее, опытнее и что самое главное старше тебя
- Опыт
- Принципы
- Позитив
- Человеческое здоровье
- Согласие с внутренним Я
- Удовольствие и труд
- Ничего идеального не бывает
- Проблемы не решаются
- Проблемы и способы их решения
- Роли поменялись
- Что дальше?
Monday, December 29, 2008
За 10000 лет человек ни капли не изменился
................................................................................
- Любимый, ложись спать. Уже три.
- Родненькая, работа такая. Вот я уже-уже. Сейчас код декомпилирую, чтобы команда в 8 утра смогла начать работу...
- Любимый. Уже пятый час.
- Не получается, солнышко. (в мыслях) Я ведь тебя всё равно сделаю... Главное сделать тебя статической. (вслух) Главное сделать тебя статичеcкой. Точно. И статическим классом тебя заодно сделать надо.
- Ты меня уже не любишь?
- Да, конечно.
- Что?
- Да, конечно.
- Что “да конечно”?
- Что?
- Это я у тебя спрашиваю что?
- Что? Извини. Я не помню что ты сказала. Можешь повторить?... Главное сделать тебя статической. Точно.
- (грустно) О, брат...
................................................................................
Специфика работы или я схожу с ума?
И всё же мне нравиться эта работа!
................................................................................
Спецификация?! Уж поверь ты моему опыту.
................................................................................
- Можно телефон руководителя направления?
- Его нет? Слушайте, меня сегодня не будет.
- Почему в 6 вечера?
- Я очень заболел. Заказчик звонил? А кто с ним говорил? Никто? Во млин... Меня завтра и послезавтра не будет.
- Что?
- Нет, справки не будет.
................................................................................
- Хорошо-то как. Сидишь баклуши бьёшь, а оно всё работает...
- Хорошо-то как...
- Что ты там говоришь? Не успеваем? Поговори с командой насчёт субботы... Хорошо-то как...
- Не успели? Так ведь в воскресенье работали. Ничего вытянем! И не такой объём вытягивали.
- Что? Заболел главный разработчие? Заказчик звонит?...
- Простите, я звоню по объявлению насчёт работы.
................................................................................
- Значит, так. Вот тебе, тебе, тебе и тебе задание. Я у вас главный. Меня вы можете беспокоить меня небольше 5 минут в день после полдника. Согласовывайте между собой, делите время, берите по 10 секунд, НО... Не больше 5 минут в сумме. Не больше. Я человек большОй, занятОй, строю архитектуры, посылаю заказчиков и подымаю ваш уровень как разработчиков.
................................................................................
ЙА
Friday, December 19, 2008
10 Tips to impove Linq2Sql performance
- Отключить ObjectTracking - у нас уже используется. DataContextManager.Create<tcontext>(bool readOnly) - если true, то object tracking выключен. Это позволит отключить ненужный в таком случае контроль изменений объектов.
- Разнести не связанные таблицы по разным датаконтекстам. Сокращение размера датаконтекста позволит уменьшит количество используемой памяти и операций для контроля изменений объектов.
- Использовать CompiledQuery - думаю, прирост будет, только вот какой? Тут можно посмотреть результаты тестирования compiled vs uncompiled запросов на LINQ
В двух словах - прирост есть, в зависимости от частоты похожих запросов от 10% до 70%
Пример компилированного запроса:Func<NorthwindDataContext, IEnumerable<Category>> func =
CompiledQuery.Compile<NorthwindDataContext, IEnumerable<Category>>
((NorthwindDataContext context) => context.Categories.
Where<Category>(cat => cat.Products.Count > 5));
* This source code was highlighted with Source Code Highlighter.
Далее, можно создать статический класс с набором этих компилированных запросов:/// <summary>
/// Utility class to store compiled queries
/// </summary>
public static class QueriesUtility
{
/// <summary>
/// Gets the query that returns categories with more than five products.
/// </summary>
/// <value>The query containing categories with more than five products.</value>
public static Func<NorthwindDataContext, IEnumerable<Category>>
GetCategoriesWithMoreThanFiveProducts
{
get
{
Func<NorthwindDataContext, IEnumerable<Category>> func =
CompiledQuery.Compile<NorthwindDataContext, IEnumerable<Category>>
((NorthwindDataContext context) => context.Categories.
Where<Category>(cat => cat.Products.Count > 5));
return func;
}
}
}
* This source code was highlighted with Source Code Highlighter.
Использование же этого класса будет следующим:using (NorthwindDataContext context = new NorthwindDataContext())
{
var categories = QueriesUtility.GetCategoriesWithMoreThanFiveProducts(context);
}
* This source code was highlighted with Source Code Highlighter.
Кроме того, поддержание многих запросов в одном месте позволит избежать дублирование кода и более легкую его поддержку - Использовать DataLoadOptions.AssociateWith - смысл в том чтобы не использовать LazyLoading, а грузить связанные таблицы сразу. Но грузить не все данные, а лишь по определенному условию.
using (NorthwindDataContext context = new NorthwindDataContext())
{
DataLoadOptions options = new DataLoadOptions();
options.AssociateWith<Category>(cat=> cat.Products.Where<Product>(prod => !prod.Discontinued));
context.LoadOptions = options;
}
* This source code was highlighted with Source Code Highlighter. - Использовать Optimistic concurrency - добавить в каждую таблицу поле типа TimeStamp - таким образом сам LINQ будет отвечать за concurrency. Кроме того, используя такой подход, можно передавать entity из одного датаконтекст. Если же приложению Optimistic Concurrency не нужна - ее можно отключить. В свойствах Entity в дизайнере выставить UpdateCheck равным UpdateCheck.Never
- Мониторить запросы, которые генерирует LINQ. Большинство запросов будет генерироваться на лету, поэтому, как большинство генераторов-дизайнеров от MS, LINQ может сгенерировать не совсем оптимальный запрос - подтягивать лишние колонки, к примеру. Логирование делается очень просто -
using (NorthwindDataContext context = new NorthwindDataContext())
{
context.Log = Console.Out;
}
* This source code was highlighted with Source Code Highlighter.
Так как мы используем DataContextManager, через который создаем все датаконтексты, то привязать логгирование ко всему приложению будет еще проще:internal static class DataContextManager
{
public static DataContextType Create<DataContextType>(bool readOnlyAccess)
where DataContextType : DataContext, new()
{
DataContextType dc = new DataContextType();
//DebugWriter is a TextWriter that writes to DebugInfo.txt file
dc.Log = SaM.Dept2.Common.Logging.Logger.DebugWriter;
dc.ObjectTrackingEnabled = !readOnlyAccess;
dc.DeferredLoadingEnabled = false;
return dc;
}
}
* This source code was highlighted with Source Code Highlighter. - Использовать метод Attach только тогда, когда это действительно нужно. Например, не использовать AttachAll для коллекций, а проверять каждый объект из коллекции на изменения и привязывать/не привязывать его.
- Быть более внимательным при работе c контролем изменений объектов. При работе с датаконтекстом в режиме не только чтения простые запросы могут создавать дополнительные затраты ресурсов. Например, очень простой запрос:
using (NorthwindDataContext context = new NorthwindDataContext())
{
var a = from c in context.Categories
select c;
}
* This source code was highlighted with Source Code Highlighter.
Однако этот запрос будет тратить больше ресурсов нежели следующий:using (NorthwindDataContext context = new NorthwindDataContext())
{
var a = from c in context.Categories
select new Category
{
CategoryID = c.CategoryID,
CategoryName = c.CategoryName,
Description = c.Description
};
}
* This source code was highlighted with Source Code Highlighter.
Почему? Потому что в первом все еще продолжает работать Object Tracking, в то время как во втором LINQ просто отдает вам объекты и забывает о них.
Получать только нужное количество строк используя Take и Skip методы. Стандартный сценарий для постраничного просмотра:/// <summary>
/// Gets the products page by page.
/// </summary>
/// <param name=”startingPageIndex”>Index of the starting page.</param>
/// <param name=”pageSize”>Size of the page.</param>
/// <returns>The list of products in the specified page</returns>
private IList<Product> GetProducts(int startingPageIndex, int pageSize)
{
using (NorthwindDataContext context = new NorthwindDataContext())
{
return context.Products
.Take<Product>(pageSize)
.Skip<Product>(startingPageIndex * pageSize)
.ToList<Product>();
}
}
* This source code was highlighted with Source Code Highlighter.- "Преждевременная оптимизация — корень всех зол". Это сказал еще Дональд Кнут.
Поэтому будьте внимательны, особенно с использованием CompiledQuery. Запросы LINQ не компилируются, как Regex. Компиляция запроса LINQ создает объект в памяти, в котором уже есть SQL-запрос и делегат для работы с ним.
В принципе, слова Кнута относятся к любым оптимизациям, поэтому не стоит сломя голову оптимизировать все подряд. Лучший выход - попробовать подход и проверить, приносит ли он реальную пользу.
Спасибо.
На основе статьи 10 Tips to Improve Linq2Sql Performance... и собственного опыта.
Monday, December 15, 2008
Потенциальная уязвимость в ASP.NEt приложении из-за неправильного управления ключами шифрования
Поднял для себя ещё одну уязвимость, которую можно сделать в ASP.NET приложении. Ошибку такую в уже существующих приложениях мы делали, но до дыры это не доводило. А может и доводило...
Собственно, хватит предыстории, пора и к делу.
Проблема связана с шифорованием, вернее, с использованием ключей для шифрования. Ещё вернее, с использованием одних и тех же ключей для шифрования разной информации. Помню, несколько моих ответов на вопрос, где положить ключики для шифрования, "да давай мэшин кэйем - такой чёрта-с-два угадаешь и достанешь:)". Причём не важна была задача, для которой шифруется. А между прочем, этот же ключик ASP.NET используется для шифрования auth и role "печенюшек".
В чём собственно дыра. К примеру, пользователь расскрыл для себя возможность получать с сайта шифрованный текст на его любые вводимые данные (к примеру, генерация шифрованного урл параметра по паролю пользователя для его последующего сброса (в открытом же виде не гоже пароли слать ;))). и более того, это функционал использует machinekey для шифрование и дешифрования. дальше дело техники. аuth кук содержит только имя пользователя - пароля нет в шифрованной печенюшке. пользователь составляет в текстовом виде как выглядит незашированный текст FormsAuthenticationCookie (можно рефлектором поднять место перед шифрацией (byte[] FormsAuthentication.MakeTicketIntoBinaryBlob(FormsAuthenticationTicket ticket)) для пользователя скажем admin или karlito (ты ведь помнишь, что пароль не нужен) и посылает этот текст на шифрацию. Класс, сервер возвращает нам шифрованный текст (читай аутекатионный кук). Теперь, точно дело техники. как послать запрос с определённым куком - это, надеюсь, ты знаешь. Кста, role-кук это отдельный кук содержащий только имя пользователя и роли. , но тоже пользуется мэшин кэйем для шифрования. Короче, поняли.
Посыл простой:
1) Внимательнее с использованием одних и тех же ключей для разной функциональности
2) Стараться не давать пользователю функциональности, получить по тексту его шифрованный эквивалент. Если по спеке так надо, тогда добавляй какой нить RandomId поле в шифрованный контент.
3) Осторожней с печенюшками, особенно с такими критическими как аутеканционными
Что такая уязвимость существует - это минус, что мы о ней знаем - это плюс.
Ссылочная информация:
http://www.cacr.math.uwaterloo.ca/hac/about/chap13.pdf
http://blogs.msdn.com/ace_team/archive/2008/11/29/vulnerabilities-in-web-applications-due-to-improper-use-of-crypto-part-2.aspx
ЙА - karlito
Seadragon эта штука называется
Thursday, December 11, 2008
Тыбженые идеи
http://rutube.ru/
ЙА
Wednesday, December 10, 2008
Деня жжот )
/// This method physically remove property values and does not manage statuses during removing.
/// For internal use only. Any using of this method should be argumented and commented.
///
protected void UnsafeRemoveProperty(string propertyName)
{
Friday, December 5, 2008
Наш SaM-Solutions на первом месте
Как это ни странно...
Да и если почитать, как считается рейтинг, то вроде специально накрутить сложно
Tuesday, December 2, 2008
Жизненный цикл проекта в Silverlight 2
Как и обещали, в конце ноября мы начинаем выкладывать на сайт TechDays.Ru ролики по докладам, прочитанным в различных городах России в ходе последней серии мероприятий. Для автоматического получения информации о новых докладах на сайте рекомендую подписаться на соответствующий RSS.
В частности, вчера на сайте появился мой доклад "Жизненный цикл проекта в Silverlight 2". Это часовой доклад, который является комплексным обзором практик, методик и полезных инструментов при разработке проектов в Silverlight 2 - от планирования до стабилизации и развертывания.
Доклад ориентирован на разработчиков, уже знакомых с технологией Silverlight, но желающих получить больше практической информации о ведении реальных проектов.
Обращаю ваше внимание, что кроме видеозаписи на странице доступна презентация и примеры кода.
Ваши комментарии вы можете оставлять на странице доклада или здесь в комментариях. Также напоминаю, что свое мнение о докладе вы можете высказать на сайте в виде оценок в правом верхнем углу.
P.S.: \\sc0196\Screencasts\TechDays2008\SL2
Monday, December 1, 2008
Вынос jQuery в одно место
Sent: Monday, December 01, 2008 12:48 PM
To: Aliaksandr Sarakaletau; Alexey Strakh
Cc: Yauheni Damanau
Subject: RE: single jquery location
Я за сборку.
Одна из проблем, которые она решает – это переключение packed/debug версий.
Вторая – не надо в каждом новом веб-сайте добавлять одни и те же скрипты. Т.е. у нас будет одно место для хранения всех скриптов (я давно хотел).
Третья – мы можем контролировать повторное подключение скриптов, если у нас на master page подключается, а потом в каком-нить контроле.
Для удобства предлагаю еще написать небольшую обертку или дописать наш JScriptHelper для удобного подключения jQuery и плагинов к нему.
From: Stanislau Sliunkou
Sent: Monday, December 01, 2008 10:33 AM
To: Alexey Strakh
Cc: Aliaksandr Sarakaletau; Yauheni Damanau
Subject: RE: single jquery location
http://www.west-wind.com/Weblog/posts/413878.aspx
Вот опять актуальная статья. Обсуждаются различные варианты подключения js файлов. В том числе есть способ через сборку. Сча еще раз перечитаю и скажу «What do I think» )
From: Alexey Strakh
Sent: Friday, November 28, 2008 7:10 PM
To: Stanislau Sliunkou; Aliaksandr Sarakaletau; Yauheni Damanau
Subject: single jquery location
А что если если включить ввиде ресурсов в aspcommon.dll (как альтернатива с single web location)?
Benefits:
1. Single location
2. no problem with versioning.
3. Asp.net handler to retrieve it already exists
What do you think?
Thanks,
Alexey Strakh
Inclusion of JavaScript Files
•Include in a scripts folder and link via script include as jQuery.js
•Include in a scripts folder and link via script include as jQuery-1.2.6.js (ie. version specific)
•Link to the version specific file at jQuery.com (typically jQuery-1.2.6.js)
•Link to the latest version at jQuery.com (ie. jQuery-latest.js)
•Link to some other script hosting site (ie. Google's Ajax Lib API) via script loading
•Embed scripts into ASP.NET Resources
•Use ScriptManager to load scripts either from Folder or Resources
•Use a custom script manager
Фаулер vs "анемичная модель"
Преимущества тонкой модели при работе с данными от Ивана Бодягина
http://blogs.gotdotnet.ru/personal/bezzus/CommentView.aspx?guid=6c129492-c94a-40dc-bb05-134377ae1a5e
Старые песни о главном: роль ООП при работе с данными...
Статья Ивана Бодягина MVP Microsoft. Рассуждения на тему ООП, ORM.
http://blogs.gotdotnet.ru/personal/bezzus/PermaLink.aspx?guid=7a6a69bd-bedf-425f-b09c-123b4a41f686
Свершилось чудо или EF vs Linq2SQL =)
Интересное сравнение двух технологий от Ивана Бодягина MVP Microsoft и создателя RSDN
http://blogs.gotdotnet.ru/personal/bezzus/PermaLink.aspx?guid=c6c1b34b-3577-4363-a3f0-36c52f227eb2