Последнее время активизировались рекрутеры (что по большому счету есть хорошо). Лично меня, за последние две недели, приглашали пособеседоваться 4 раза. Обычно пишут через linkedin, почту, скайп или аську. Реже звонят по мобильному. Как по мне, так контакт с целью заинтересовать человека, через интернет более эффективен. Почту человек прочитает в любом случае, и ответит в спокойной обстановке. А вот мобильный в течении рабочего дня может и не взять. Ну да ладно, кому как удобнее.
Но сегодня случилась история, которая меня несколько шокировала. Звонит корпоративный телефон по нашему внутреннему номеру. Беру трубку: "Мол, Андрей, тут звонят тебе из конторы такой-то (не помню названия) и хотят с тобой поговорить". Я переспрашиваю: "А точно со мной, а не с тем-то менеджером? Я ведь всего лишь программист".
После уточнений выяснилось, что говорят хотят именно со мной. Думаю: "Может мы делали что-то для них?". Не могу вспомнить... Переключают внешний номер на меня. Представляется женщина с явно не русским акцентом. Говорит: "Я знаю, что Вы на работе. Можете ли сейчас говорить?". Ну думаю, что какое то странное начало для делового разговора, ведь по работе звонят, а не на лыжах кататься зовут. Логично было бы спросить: "Звоню по такому-то вопросу. Не сильно ли Вы сейчас заняты?", или "У Вас есть пара свободных минут?". Отвечаю, что могу говорить. Она резко начинает говорить по-английски, причем довольно быстро. Я знаю, что когда человеку тяжело говорить на одном языке, он может перейти на другой. Не люблю когда такой переход происходит так мгновенно. Почему бы не сказать: "Мне тяжело говорить по-русски. Вы говорите по-английски?". Не знаю, может это я не достаточно крут, и хоть могу общаться с англоязычными товарищами, но мне в мозгу надо переключить некую перемычку. Если бы она с самого начала говорила на английском. Типа: "Hello. My name is...". Было бы лучше, так как я бы сразу понял в какое положение эту перемычку переключить. Ну да ладно. Дело не в том, что я не въехал в первые несколько фраз после перехода на английский (или это такая проверка на знание языка?). А в том, что она мне говорила потом: "У нас есть много различных проектов и т.д. Выслать Вам описание вакансий?"
Я вежливо отказался. Собственно, я первый раз сталкиваюсь с предложением другой работы через рабочий телефон текущей работы. Когда понял, что от меня нужно, промелькнула мысль, что это такая проверка на лояльность (мой работодатель подобными вещами вроде не занимается). Мне аж стало интересно, откуда у этой конторы информация о моем месте работы. Я никаких резюме никуда не отправлял, и эта информация есть только на linkedin. Если меня нашли через linkedin, то почему бы не послать через него сообщение, это проще чем искать номер моей конторы. Если меня порекомендовал кто-то из бывших коллег, так у всех, кажется, есть мои координаты в linkedin или аське.
PS. Надеюсь, что ничего особо важного в начале разговора на английском не было. А то вдруг, она мне сказала что-то типа: "Мы набираем команду для постоянной работы в Лондоне, и готовы помочь со всеми вопросами связанными с переездом..." :)
понедельник, 8 ноября 2010 г.
понедельник, 11 октября 2010 г.
Книга Refactoring Databases: Evolutionary Database Design
Закончил читать книгу Refactoring Databases: Evolutionary Database Design (By Scott W. Ambler, Pramod J. Sadalage). У авторов получился некий структурированный справочник.
Некоторые примеры из книги знакомы до боли. К примеру, таблицы имеющие огромное количество колонок - перед глазами так и стоит некая Statlogic.PCS.Application, в которой более 100 колонок. Есть кто в теме? :)
Можно было бы побольше описать работу, когда происходит работа с несколькими базами одновременно, способы ухода от подобной необходимости (без построения мега DWH в котором есть абсолютно все), а также возможные проблемы (не знаю как в Oracle, но к примеру, MS SQL 2005 не позволяет создавать индексированные представления обращающиеся к разным базам, чего мне в свое время очень хотелось)
Несколько смущает длина переходного (transition) перода, о котором упоминалось в книге. Мне интересно, кто как реализует удаление старой схемы? Кто там через полгода вспомнит, что нужно накатить какой-то там скрипт? Даже не смотря на то, что этот процесс можно автоматизировать, все равно цифра 6-12 месяцев довольно велика.
Некоторые примеры из книги знакомы до боли. К примеру, таблицы имеющие огромное количество колонок - перед глазами так и стоит некая Statlogic.PCS.Application, в которой более 100 колонок. Есть кто в теме? :)
Можно было бы побольше описать работу, когда происходит работа с несколькими базами одновременно, способы ухода от подобной необходимости (без построения мега DWH в котором есть абсолютно все), а также возможные проблемы (не знаю как в Oracle, но к примеру, MS SQL 2005 не позволяет создавать индексированные представления обращающиеся к разным базам, чего мне в свое время очень хотелось)
Несколько смущает длина переходного (transition) перода, о котором упоминалось в книге. Мне интересно, кто как реализует удаление старой схемы? Кто там через полгода вспомнит, что нужно накатить какой-то там скрипт? Даже не смотря на то, что этот процесс можно автоматизировать, все равно цифра 6-12 месяцев довольно велика.
среда, 25 августа 2010 г.
Intel bought McAfee:)
Intel CEO: «We need antivirus, can someone buy me McAfee?» Few hours later: «Done.» «Great, which version?» «Version… ?»
суббота, 1 мая 2010 г.
MS-2784: Tuning and optimizing database queries using Microsoft SQL Server 2005
Довелось проходить данный тренинг (3 дня), в компании Softline. Ожидал несколько большего.
Из полезного для себя узнал как совмещать статистику Windows Perfomance Monitor и SQL Server Profiler.Стали после тренинга с коллегами подумывать о партицировании некоторых исторических таблиц.
Не понравились задания с рефакторингом курсоров. Сами рекомендации полезные, но примеры явно надуманные. Если после рефакторинга курсор может превратиться в банальный SELECT, то как вообще могла в голову прийти идея использовать курсор?
Последнее задание, где нужно было проанализировать базу на предмет блокировок, и переписать код, чтобы их уменьшить. Решение предлагаемое в книжке я так не понял. Какой может быть выигрыш, если перед стартом транзакции явно указывать READ COMMITED (уровень изоляции по умолчанию), и вместо автокомита транзакций, стартовать и подтверждать их явно? Нет ну может небольшой выигрыш и будет, но врядли он будет существенным.
Из полезного для себя узнал как совмещать статистику Windows Perfomance Monitor и SQL Server Profiler.Стали после тренинга с коллегами подумывать о партицировании некоторых исторических таблиц.
Не понравились задания с рефакторингом курсоров. Сами рекомендации полезные, но примеры явно надуманные. Если после рефакторинга курсор может превратиться в банальный SELECT, то как вообще могла в голову прийти идея использовать курсор?
Последнее задание, где нужно было проанализировать базу на предмет блокировок, и переписать код, чтобы их уменьшить. Решение предлагаемое в книжке я так не понял. Какой может быть выигрыш, если перед стартом транзакции явно указывать READ COMMITED (уровень изоляции по умолчанию), и вместо автокомита транзакций, стартовать и подтверждать их явно? Нет ну может небольшой выигрыш и будет, но врядли он будет существенным.
вторник, 20 апреля 2010 г.
Кремниевая долина
Занятная картинка.
Хорошо нашему брату там небось живеться. Скучно работать в Oracle? Иди в Google:)
PS. Не знал, что Aricent в кремниевой долине есть.
Хорошо нашему брату там небось живеться. Скучно работать в Oracle? Иди в Google:)
PS. Не знал, что Aricent в кремниевой долине есть.
суббота, 3 апреля 2010 г.
Code Contracts
Есть такое понятие, как самотестируемый код(не путать с тестами). Общая суть в том, что в дебажную сборку программы добавляются проверки необходимых для успешной работы условий, и если условие не выполняется - значит что-то пошло не так.
К примеру, в неком методе необходимо проверить входные параметры, а не null ли передался вместо полноценного объекта? Затем проверить результат работы метода.
К примеру, в неком методе необходимо проверить входные параметры, а не null ли передался вместо полноценного объекта? Затем проверить результат работы метода.
static void SomeMethod(object param) { // проверяем входные параметры Debug.Assert(param != null); // делаем что-то важное... DoSomethingImportant(); // проверяем результат работы Debug.Assert(somethingImportant != somethingUnimportant); }
Хорошо. Но не слишком удобно, так как предусловия и постусловия проверяются в разныхместах. Ну а теперь перейдем к самому интересному. С относительно недавних пор (начало 2009года) у Microsoft есть такой продукт как Code Contracts (в Java как мне сказалианалог есть давно). Данная библиотека пока не является ни частью .NET, ни частьюVisual Studio. По крайней мере с VS2010 Beta 2, она не ставилась. А так у меняпоставилась на VS2008 и интегрируется с msbuild. Малюсенький примерчик. Допустим мы хотим иметь метод, который заполняет списокint'ов только четными числами, суммарное количество элементов списка не должнопревышать 6, и мы хотим быть уверены, что в нашем методе добавляется только одинэлемент в список:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics.Contracts; namespace CodeContractsTest { class Program { static void Main(string[] args) { List listEven = new List() { 2, 4, 6, 8}; AddItem(listEven, 10); // последующий вызов вызовет исключение //AddItem(listEven, 11); foreach (var item in listEven) { Console.WriteLine(item); } Console.ReadKey(); } static void AddItem(List list, int item) { Contract.Requires(item % 2 == 0); Contract.Ensures(list.Count <= 6); Contract.Ensures(list.Count == Contract.OldValue(list.Count) + 1); list.Add(item); //последующий вызов вызовет исключение //list.Add(item); } } }
Как видим в нашем распоряжении есть два наглядных метода для проверки пре- (Requires) и постусловий Ensures. Это гораздо нагляднее чем использовать Debug.Assert, хотя Contract.Assert тоже есть:) Есть еще атрибуты [ContractClass] и [ContractClassFor]. Можно объявить интерфейс, обозначить его [ContractClass], затем создать класс, реализующий этот интерфейс, обозначить его как [ContractClassFor] и реализовать в нем контракт. И все классы, которые будут реализовывать наш интерфейс по умолчанию будут проверяться на соответствие контракту. Ссылка на Code Contracts: http://research.microsoft.com/en-us/projects/contracts/ PS. Точнее в VS210 Beta 2. По умолчанию можно подключить сборку System.Diagnostics.Contracts, и даже писать ее методы (компилироваться будет, но работать нет). И только после того, как библиотеку установить, в свойствах проекта появиться Code Contracts и с ними можно будет работать.
воскресенье, 28 марта 2010 г.
Руководство Microsoft по проектированию архитектуры приложений
Прочитал руководство Microsoft по проектированию архитектуры приложений.
Как по мне, так получился неплохой хорошо структурированный справочник.
К примеру, проектируем слой представления, смотрим, ага здесь уместно будет использовать шаблоны MVC и Command. Так нужно бы поподробнее, кликаем по ссылке и попадаем на страницу MSDN, где эти шаблоны описаны и.т.д.
Собственно, руководство можно скачать здесь
P.S. Эх мечты, мечты ...
Как по мне, так получился неплохой хорошо структурированный справочник.
К примеру, проектируем слой представления, смотрим, ага здесь уместно будет использовать шаблоны MVC и Command. Так нужно бы поподробнее, кликаем по ссылке и попадаем на страницу MSDN, где эти шаблоны описаны и.т.д.
Собственно, руководство можно скачать здесь
P.S. Эх мечты, мечты ...
суббота, 13 марта 2010 г.
суббота, 6 марта 2010 г.
Пример применения WAITFOR DELAY
Такой вот небольшой примерчик. Допустим мы знаем, что некое действие на сервере (к примеру заполнение некой таблицы) закончиться примерно к 7.00, но точное время будет постоянно меняться. После того как таблица заполнится, нам необходимо выполнить какое-нибудь действие (к примеру сформировать отчеты и разослать их пользователям по почте).
Как это можно сделать? Я вижу несколько вариантов:
1. Запускать формирование отчетов сразу же после обновлений необходимой таблицы, к примеру прописав на таблице с логами триггер. Минус, пока не отработает триггер, не начнется следующий этап.
2. Создание user configurable trace event (не знаю как красиво перевести) используя sp_trace_generateevent. Вроде как грамотное решение. Так сказать событийная модель в SQL Server, я, правда, не разбирался со всякими там WMI Provider, WQL и другими страшными словами:) Но возможности которые открываются выглядят заманчиво. Может когда-нибудь разберусь, и буду использовать.
3. Я пока пришел к следующему решению. Создаем на сервере джоб, который стартует в предполагаемое время, ждет окончания обновлений, и делает свою работу (формирует отчеты). Естественно, минусы в том что на сервере вместе с основными обновлениями крутиться что-то еще есть. а) возрастает нагрузка на сервер; б)могут возникнуть блокировки, поэтому нужно следить что именно делается в джобе (как любит говорить один мой знакомый: "Один в #опе, два в уме", в моем случае в джобе идет Select из одной единственной таблицы, которая после обновлений не изменяется на протяжении всего дня, вроде проблем быть не должно).
Ну и в виде кода все это дело может выглядить примерно так:
Как это можно сделать? Я вижу несколько вариантов:
1. Запускать формирование отчетов сразу же после обновлений необходимой таблицы, к примеру прописав на таблице с логами триггер. Минус, пока не отработает триггер, не начнется следующий этап.
2. Создание user configurable trace event (не знаю как красиво перевести) используя sp_trace_generateevent. Вроде как грамотное решение. Так сказать событийная модель в SQL Server, я, правда, не разбирался со всякими там WMI Provider, WQL и другими страшными словами:) Но возможности которые открываются выглядят заманчиво. Может когда-нибудь разберусь, и буду использовать.
3. Я пока пришел к следующему решению. Создаем на сервере джоб, который стартует в предполагаемое время, ждет окончания обновлений, и делает свою работу (формирует отчеты). Естественно, минусы в том что на сервере вместе с основными обновлениями крутиться что-то еще есть. а) возрастает нагрузка на сервер; б)могут возникнуть блокировки, поэтому нужно следить что именно делается в джобе (как любит говорить один мой знакомый: "Один в #опе, два в уме", в моем случае в джобе идет Select из одной единственной таблицы, которая после обновлений не изменяется на протяжении всего дня, вроде проблем быть не должно).
Ну и в виде кода все это дело может выглядить примерно так:
USE [Temp] GO IF EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[tbLog]') AND type in (N'U') ) BEGIN DROP TABLE [dbo].[tbLog] END CREATE TABLE [dbo].[tbLog]( [Date] [datetime] NULL ) ON [PRIMARY] -- ------------------------------------------------------------ IF EXISTS ( SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[spTestDelay]') AND type in (N'P', N'PC') ) BEGIN DROP PROCEDURE [dbo].[spTestDelay] END GO CREATE PROCEDURE [dbo].[spTestDelay] AS BEGIN DECLARE @Flag bit SET @Flag = 0 WHILE @Flag = 0 BEGIN -- waiting for updates IF EXISTS( SELECT 1 FROM [dbo].[tbLog] WHERE DATEDIFF(DAY, Date, GETDATE()) = 0 ) BEGIN -- Run necessary stored procedures SET @Flag = 1 END ELSE BEGIN WAITFOR DELAY '00:01' END END END