четверг, 16 июля 2009 г.

PHP

Ужасаюсь всему известному и написанному на PHP: Joomla, phpBB, OSCommerce. Это популярно, но невероятно уродливо. От этого такое отторжение к самому PHP. Сам когда-то начинал именно с него. Ничего не понимал про ООП, да вообще ничего не понимал тогда. Отторжение такое, что кажется проще написать все своё с нуля на любимом языке. Все эти php-детища живут, дышат и даже "развиваются". Ими пользуются по причине отсутствия бесплатных аналогов. Тем более php-хостинг очень распространен.

Сам "язык" PHP я никогда не полюблю...

понедельник, 13 июля 2009 г.

Простые советы

  1. Методы, возвращающие булево значение, называйте "is" + проверяемое условие. Без всяких отрицаний в названии метода. Никаких "isNotNull()" или "isWithoutValidation()" не может быть. Иначе при вызове "!isNotNull()" или "!isWithoutValidation()" получаем отрицание отрицания. А это плохо при чтении кода. Сравните: "!isEmpty()" и "!isNotEmpty()". Что проще понять?
  2. Избегайте регулярных выражений, где возможно. Конкретный пример из практики: "String.format("%s %s %s", last, first, middle)". В данном простом случае, косвенно используются регулярные выражения. Вариант "last + ' ' + first + ' ' + middle" работает в 3-5 раз быстрее и жрет намного меньше памяти.

четверг, 9 июля 2009 г.

О плохих вещах в программировании

Есть несколько вещей, которые меня доводят (отсортировано в произвольном порядке):
  1. Суровость. Программер пишет новый модуль/класс, которым должны пользоваться другие программеры и не оставляет ни единой строчки комментариев. Встречал мнение, что написание комментов означает нечто плохое, якобы ты "снижаешь свой уровень программирования" тем самым. Возможно, твой код действительно лучший и читаемый, но поверь, что это сразу не поймешь. Моё мнение, что такого быть не должно. Сам столкнулся с кучей недокументированного кода. Ну а смысл? Там, где я разобрался бы за 1 минуту, мне приходится разбираться 15. А если я лезу в новые дебри, то несколько часов разбирательств гарантированны.
  2. Изобретательство велосипедов. Ну это вообще бред.
  3. Нешаблонное мышление в плохом смысле этого слова. Когда ты делаешь некий компонент или класс, то должен понимать "ага, тут мы следуем MVC модели, а это значит, что в вид нельзя запихивать получение данных". Это серьезный вопрос. Старшие товарищи должны объяснять младшим "как надо".
  4. Отсутствие контроля со стороны старших программистов. К сожалению, code-review для меня несбыточная мечта. Плохо.
  5. Присутствие "индуса" в команде. Это вообще тихий ужас. К счастью, такого сейчас нет.
  6. Отсутствие амбиций у команды... это когда просто кодят, выполняют свою работу и ничего больше. Скучно работать становится.
  7. Отсутствие автоматических тестов. Это просто большая ошибка. Твои заказчики будут тебя ненавидеть за то, что они являются твоими тестерами. Хоть часто и говорят "все не протестируешь", "у нас тут gui", "сложная логика", но мое мнение, что надо разрабатывать соответствующие механизмы, инструменты и такие проблемы решатся. Да это затраты, да это время. Может я просто никогда не был тим-лидом, поэтому так и считаю...?
  8. Нарушение DRY (Don't repeat yourself) принципа. Очень тоскливо, но зачастую, как мне кажется, невероятно сложно избегать DRY. Нужно видимо быть по-настоящему крутым прогером, чтобы такие вещи в твоем продукте не допускались.
  9. Отсутствие общей "багзиллы". Это провоцирует такие вещи, как "да это же известный баг!". Да, конечно он очень известный и был в рассылке аж полгода назад. Глупо. Тем более зачастую если я нашел баг, то мне не хочется или не хватает квалификации его исправить. Так бы я занес его в багзиллу и кто-то "постарше" исправил. Действия по принципу "сам нашел - сам и исправляй" на мой взгляд неуместны.

четверг, 11 июня 2009 г.

Подборка забавных комментариев

Подборка смешных комментов из исходников:
  1. "//if you want to refactor: please, attend!";
  2. "//todo: BUILT or NOT_BUILT - that is a question...";
  3. "//TODO:Temporary hack" - висит уже больше года;
  4. "//TODO or not TODO: implement this as OSGi service...";
  5. "//TODO: Зачем увеличивать диффузию слоя данных в слой представления ?";
  6. "//TODO: "одноногий компонент".";
  7. "// FIXME Это нормально что переформирование ведомости для каждой группы проходит в свой транзакции с одной стороны в этом нет ничего плохого, но как-то не по принятым правилам :)";
  8. "//TODO & FIXME this code is buggy. Should be a bridge between MetaClasses & CoreClasses. Don't say I didn't warn you! ;)";
  9. "// FIXME! Теоретически запрос может вернуть более чем один объект в результате чего произойдет исключение. В общем не понятна логика когда будет возвращено более одного объекта";
  10. "//Исчадье копипаста".
p.s.: автором одного из данных комментов являюсь я сам :)

вторник, 9 июня 2009 г.

Баг Java компилятора

Удивительные вещи. На работе случайно написал код, который вызывает ошибку компилятора java. Этот пример можно проиллюстрировать таким вот кодом, который компилится при помощи Eclipse и не компилится при помощи javac:
public class X
{
<T extends X> T f1() throws Exception
{
return null;
}

<U extends X> U f2() throws Exception
{
return f1();
}
}

javac выдает следующую ошибку:
X.java:6: type parameters of <T>T cannot be determined; no unique maximal instance exists for type variable T 
with upper bounds U,X
return f1();
^


Если заменить "return f1()" на "return this.<U>f1()", то javac проглатывает. Этот баг также известен здесь http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6302954. И судя по комментам не исправлен в 1.6.13 и исправлен в 1.7. Только я вот одного не понимаю, как же оно в Eclipse компилится...

воскресенье, 7 июня 2009 г.

MS SQL "Немедленно"... но что немедленно..?

Что произойдет в MS SQL, если в процессе восстановления БД из дампа нажать на ссылку "Немедленно":
Ответ белым шрифтом внизу... это что же логично?

Восстановление БД немедленно прервется

пятница, 5 июня 2009 г.

Метки в Java (Java Labels)

Метки в Java могут использоваться для выхода из вложенных циклов. Это по сути GOTO в Java. В данном случае не нужно создавать дополнительных "индикаторных" переменных и тем самым усложнять код. Стандартный пример в данном случае:

int i, j = 0;
label: for (i = 0; i < 10; i++)
{
for (j = 0; j < 10; j++)
{
if (i == 5 && j == 5)
{
break label;
}
}
}
System.out.println(i + " " + j);


Также одним из полезных применений меток будет переход на следующую итерацию внешнего цикла:
label: for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if(i == 5)
continue label;
}
System.out.println(i);
}


Прикол в тему меток. Скомпилируется ли данный код?
public static void main(String args[])
{
http://dr-magic.blogspot.com/
System.out.println("Hello World!");
}

четверг, 4 июня 2009 г.

Google Squared

Java != JavaScript. Google Squared пока не в курсе

.

Опрос: лучшая книга по Java

Мне вдруг стало очень интересно услышать, какую же книгу по Java вы считаете самой лучшей и интересной. А также вообще какие книги по данной теме вы читали. Можете ли что-то посоветовать?

понедельник, 25 мая 2009 г.

Научная теория принятия решений и бизнес

Есть одна региональная крупная фирма, обеспечивающая интернет доступ. В управлении этой фирмы есть ряд людей вышедших или так и неушедших из науки. Так вот, эти люди пишут очень умные статьи о многокритериальном оценивании некоторых параметров в условиях неопределенности. В этих статьях в частности приводится ряд формул, с помощью которых можно оценить качество работы фирмы, да ещё и в условиях неопределенности.

А неопределенность в работе этой самой фирмы оказывается настолько высокой, что статического ip-адреса приходится ждать месяц, из-за того, что "не щелкнули вовремя на нужную галочку в форме". А также неопределенности периодически возникают и исчезают. Длительность таких неопределенностей колеблется от 30 минут до нескольких дней...
Оказывается можно писать такие статьи в умных журналах и при этом не видеть очевидных прорехов в работе своей фирмы. А может и не хотеть их видеть...
Разве нужны хоть какие-то математические выкладки, чтобы не брать на работу "по блату" или не нанимать неквалифицированных рабочих..? Это и так всем понятно. Оказывается, что менеджмент - это не так уж и сложно, во всяком случае в теории и по книгам.

Тогда... нужны ли такие формулки кому-то кроме издателей журналов..? Российскому бизнесу точно нет. Бизнес хочет видеть реальную применимость теории на практике. Тут надежды больше на личность, чем на какие-то методы, возможно даже на интуицию этой самой личности. Уж хорошая интуиция в условиях неопределенности не подводит. Смешно..? Отнюдь... не раз слышал в интервью у успешных людей, что главное для топ-менеджера - "интуиция"... Возможно, интуиция - это некая подсознательная оценка ситуации, исходя из условий.

Конечно, экономика России во многом теневая, много коррупции и прочих "неопределенностей", но тогда зачем создавать нерабочие теории? Это как в задачке "если вы закажете анализ рынка у профессора, то он окажется прав с вероятностью 0,9". Да вы никогда не узнаете с какой вероятностью он окажется прав, а лишние деньги наверняка потратите. А между прочем, некоторым удаётся предсказать экономическое будущее на основании математического подхода, как например Виктору Маслову. Думать надо... думать!

p.s.: разговор идет в первую очередь про теории принятия решений, теории управления и т.п.

пятница, 22 мая 2009 г.

Интересное инстанцирование

Скажите кто хоть раз встречался с таким инстанцированием класса:

public class Example {

public class MemberOfExample {
public void test() {
System.out.println("Hello, my dear friend!");
}
}

}


public class Main {
public static void main(String[] args) {
Example example = new Example();
MemberOfExample member = example.new MemberOfExample();
member.test();
}
}


Любопытно...

вторник, 19 мая 2009 г.

Мнемоническое правило для запоминания, что нужно вернуть в compare методе

Наверное, каждый программист знает про метод compare, который есть в том или ином виде во многих языках программирования. В Java этот метод определяется в интерфейсе Comparator:
int compare(T o1, T o2);

Но зачастую забывается, что же там надо вернуть - минус или плюс один. Я придумал мнемоническое правило, по которому легко запомнить, какое значение вам необходимо возвращать. Итак:
Если o1 меньше o2, то возвращаете минус один(-1). Обратите внимание на букву "м" в слове "меньше" и ту же букву в слове "минус". По этой самой букве "м" легко запомнить, что нужно возвращать. меньше => минус

Остальное же легко:
-если o1 равно o2, возвращается 0(это помнят все).
-остался один случай, когда o1 больше o2. Тут уже вспоминаете методом исключения, что надо вернуть "1".

Возможно, это было уже кому-то известно, однако, я такого нигде не читал.

p.s.: вообще необязательно возвращать +1 или -1. Просто должно быть отрицательное и положительное число. Часто делают +1 или -1, если не нужно знать насколько одно "больше" или "меньше" другого (в кавычках, потому что понятие больше или меньше условно). Но можно возвращать насколько одно "больше" или "меньше" другого. Например, пять больше трех на два. Эта информация может пригодиться в работе некоторых алгоритмов.

"Hello world". Java vs Python

Предположим, вы создали две программы на языках Java и Python, которые просто выводят строчку "Hello world". Программу на java вы скомпилировали и сделали jar-ник. А на Python'е вы просто создали файл с расширением ".py". Теперь вы выполняете получившиеся программы.

Внимание вопрос: какая из программ выполнится быстрее?

p.s.: об этом было в докладе про Java 7 на Sun Tech Days.

ORM. Введение и основные концепции

Привыкли мы, что знания приходят "извне" в уже разжеванном виде. Но это скучно до жути, хотя и продуктивно. Предлагаю тем, кто не знаком с аббревиатурой ORM самим придумать этот самый ORM! Зачем же нужен ORM..?

Итак, мои наводящие вопросы:
  1. У вас есть класс с переменными. Вам нужно этот класс сохранить в БД для дальнейшего считываения. Ваши действия, как это можно сделать?
  2. Допустим, вы додумались, как вам его сохранять. Теперь подумайте вот над чем: каким образом вы узнаете, что сохраненная запись относится именно к определенному классу? Какую информацию нужно знать, чтобы определить "вот эта запись относится точно к такому классу"?
  3. Так... неужели вы и до этого додумались? Тогда вопрос хитрее: у вас есть иерархия классов, каким образом вы будете её сохранять в БД?
  4. Вопрос ещё хитрее! У вас есть разветвленная иерархия классов. Это когда от одного класса наследуется несколько других классов, как вы будете их сохранять в БД? Каким образом вы отличите один подкласс от другого в БД? А сможете ли вы распознать класс-предок?
  5. Предложите несколько вариантов хранения иерархии классов в БД. Подумайте какие у них достоинства и недостатки. Скажу, что есть 3 основных, которые уже могут комбинироваться.
  6. Так, если вы до этого на все вопросы ответили и считаете, что правы, то подумайте каким образом вы бы сохранили коллекцию типа Set в БД? То есть у каждого класса есть переменная, типа Set. И у каждого она может быть своя.
  7. А типа List? Учтите, что в листе важен порядок следования элементов!
  8. Додумались..? Хм... Не верю! :) Хорошо, тогда ещё вопрос: подумайте, как можно сохранить в БД коллекцию типа Map.
  9. А теперь идите скачивайте Hibernate и мануал к нему... там ничего нового :)
Это шутка конечно, что "там ничего нового". Там действительно много нового и интересного, порой совсем непонятного...

Ответы на вопросы для собеседования по Java SE (Часть 3)

Предыдущая серия ответов: Ответы на вопросы для собеседования по Java SE (Часть 2)
Теперь помимо ответов на вопросы предоставляю ещё дополнительные вопросики для четкости полученных знаний.

11. Какие модификаторы доступа в Java вы знаете?
Java, как наследник C++ наследует и модификатор доступа с этого языка: public, private, protected и модификатор доступа по умолчанию - это когда модификатор не указывается.

-Можно ли объявить класс с модификатором protected?

12. Какой из модификаторов более строгий: protected или package-private?
Для начала надо разобраться, что такое package-private модификатор. Он ограничивает видимость до пределов пэкэджа, в котором лежит класс. И только до него! То есть, если класс лежит в пэкэдже "ru.myprog", то из пэкэджа "ru.myprog.base" он виден не будет(тоже самое для методов).
Protected модификатор, как все знают(кто хотя бы немного изучал ООП), раскрывает область видимости только для классов-наследников и для классов определенных в том же пэкэдже. Здесь мы видим отличие от C++, в котором только наследники видят protected.
Здесь можно почитать более подробно про модификаторы, а также увидеть сводную табличку http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html

Из всего этого следует, что package-private модификатор более строгий.

-Объявляем класс с модификатором public, в котором создадим метод с default модификатором. Будет ли виден этот метод из других пэкэджей?
-Скомпилируется ли данная программа:
package ru.test;
class DefaultPackage {
void test()
{
;
}
}
----
package ru.test;

public class Public extends DefaultPackage {

}
----
package ru.test.base;

import ru.test.Public;

public class Main {
public static void main(String[] args) {
Public pub = new Public();
pub.test();
}
}

-Возможно ли перегружать default методы?

13. Если у класса-родителя есть метод, объявленный как private, может ли наследник расширить его видимость? А если protected? А сузить видимость?
private методы никто, кроме самого класса не видит. Поэтому их наличие/отсутствие никак не отражается на классах-наследниках. Они с легкостью могут объявлять методы с такой же сигнатурой и любыми модификаторами. Но это очень плохой тон! Антипаттерн.
Также клас наследник может расширить видимость protected-метода. Такой класс называется "Паблик-Морозов":). Из-за того, что как известный советсткий пионер, раскрывают информацию кому ни попадя! :)
Сузить видимость класс-наследник не может. Это будет ошибка компиляции.

14. Что означает ключевое слово final?
В случае класса - нельзя от него наследоваться.

В случае метода - нельзя его переопределять. Это используется, когда нужно явно указать "здесь не трогайте! оно так не задумано!". Обычно позволяет улучшить архитектуру системы. Но это нужно делать только если есть необходимость. Не надо все методы определять как final! Таких программистов называют "фаталисты". Раньше ещё было такое мнение, что final методы быстрее работают. Сейчас это абсолютная неправда. Работают они с такой же скоростью! Так что используйте их только при явной необходимости.

В члена класса final означает константу, которая после инициализации не поменяет своего значения. Но подумайте сами, что будет, если мы объявим, например, коллекцию как final:
Сработает ли следующий код?
public class Test {
final static List _list = new ArrayList();

public test() {
_list.add("Hello world!");
}
}

А этот ?
public class Test {
final List _list = new ArrayList();

public test() {
_list = new LinkedList();
}
}

15. Имеет ли смысл объявлять метод private final?
Только если вы отъявленный фаталист, финалист и пессимист! :)

16. Какие особенности инициализации final переменных?
Если они объявлена не как static, то они инициализируются в конструкторе, даже если не были объявлены не в нем. В этом случае код сгенерирует сам компилятор. Причем порядок их инициализации соответствует порядку их определения.
Если же она объявлена, как static, то либо при первом обращении к этой переменной, либо при первом создании объекта такого класса. То есть создание статических переменных происходит "по требованию" и только один раз. И это очень логично.

17. Что будет, если единственный конструктор класса объявлен как final?
Ошибочка компиляции. Почему - предлагаю подумать самим и написать в комментариях.

Django или Ruby on Rails

Вступление:
Для тех кто в раздумиях, что изучать Django или Ruby on Rails.

Мой ответ:
Ruby on Rails

Про языки:
Сами языки Ruby и Python сравнивать не буду. После Java и то и другое хорошо и лаконично :)

Раздумия:
Я сам думал над этим вопросом месяца 3-4 назад. Решил изучить Django после прочтения информации, что рельсы - это тормоза, а также, что Python - мега-язык программирования:).
Изучил базовый Python. Прочитал все базовые мануалы по Django на сайте(которые кстати активно сейчас пишутся). Создал своё приложение с нуля... и понял, что ну не хватает мне той модели работы с БД, которую они предлагают. Слишком она уж примитивная. Слишком мало хороших плагинов => долгая разработка проекта обеспечена. Да и как-то медленно у них всё развивается...
Модель рельс мне показалась очень симпатичной, нацеленной именно на продуктивную работу. Конфигурация БД под разработку, тестирование и продакшн чего стоит! Файлы для тестирования, которые генерируются сами(только файл, без тестов :)). Потом хелперы для вьюшек. Процесс разработки идет быстрее и проще, благодаря такой вот модели.

По пунктам:
  1. Гигантское количество действительно крутых плагинов для RoR. Это громаднейший плюс. Многие проблемы решаются установкой этих плагинов.
  2. Разработка "от ссылки" в Django. Это хорошо... для газетных сайтов. Если же ссылка не важна, то лишняя работа обеспечена, потому что без этой настройки ничего не заработает.
  3. Миграции в RoR против ручного обновления таблиц в Django. Это просто неудобно.
  4. Слабый и не всегда понятный ORM у Django. Наверное, blank=True, null=True многих вводит в легкий ступор. Но вообще это нормально. После Hibernate хочется и коллекции также мапить одним махом, однако увы... :)
  5. Django за 3 года обновился с версии 0.9.x до 1.0.x. Слабовато... Рельсы же скоро выйдут третьей версии;
  6. Встроенная возможность тестирования для RoR. Отдельная конфигурация БД для тестирования.
  7. Коммьюнити у RoR больше;
  8. Для RoR есть Aptana, на основе моего любимого тормознутого Eclipse :). Для тех кто не понял - есть удобнейшая IDE для работы именно с RoR. Для Python на эту тему есть только PyDev плагин;
  9. Хостинг для RoR найти проще, хотя вообщем-то всё равно такие проекты нацелены на виртуальные или dedicated сервера;
  10. Админка в django по-моему весьма сомнительный плюс. Её тоже надо пилить, причем весьма и весьма. Хотя да, она красивая. Для тех же рельс наверняка можно найти пару хороших плагинов.

Яндекс выбрал Django!"
Теперь попытаюсь объяснить почему Яндекс выбрал именно Django для пары своих проектов. Мне кажется, что Django при хорошей квалификации программиста предпочтительнее RoR. Он не такой груженный. А то, что нужно - программист допилит... тем более программист Яндекса. Ну и нагрузка тоже решает.

Выводы:
Когда делаешь стартап, то хочется, чтобы он заработал побыстрее. Нет ни нужды ни времени ковырять и пилить фреймворк. Ставишь 5-6 хороших плагинов и серьезный функционал в кармане. Вывод тут очевиден.

(update 22.05.2009)
Disclaimer:
Всегда хорошо изучить всё самому и принять собственное решение. Самый лучший вариант скачать и то и другое, потратить 2-3 недели на освоение обоих фреймворков и принимать решение хотя бы из интуитивных предпочтений(нравится/не нравится).

воскресенье, 17 мая 2009 г.

Принципиально новый научный поисковик

Спешу поделиться очень крутой новостью!

http://www.wolframalpha.com/

Новый поисковик работает по принципу извлечения самих знаний. Содержит много справочных данных.
Создатель данного поисковика также известен, как создатель пакета Mathematica.


Примеры запросов:
Интеграл от корня икс на косинус икс:
http://www69.wolframalpha.com/input/?i=integrate+sqrt+x+cos+x
Ноты:
http://www68.wolframalpha.com/input/?i=C+E+G+Bb+D+F%23+A
Икосаэдр:
http://www68.wolframalpha.com/input/?i=+icosahedron%2C+truncated+icosahedron
Биология аспирин против кофеина:
http://www69.wolframalpha.com/input/?i=caffeine+vs.+aspirin

Статистика по имени Анна:
http://www69.wolframalpha.com/input/?i=Anna
Россия:
http://www69.wolframalpha.com/input/?i=Russia
Оттуда же:
"religions | Russian Orthodox (17.5%) | Muslim (12.5%) | Christian (2%)
literacy fraction | 99.4% "
"Russian Orthodox" и "literacy fraction". Откуда такие данные?? :))

Простые числа между 100,000 и 1,000,000
http://www69.wolframalpha.com/input/?i=primes+between+100%2C000+and+1%2C000%2C000

Решение рекуррентных соотношений:
http://www69.wolframalpha.com/input/?i=fibonacci(n)+recurrence
http://www69.wolframalpha.com/input/?i=f(n)%3Df(n-1)%2Bf(n-2)%2C+f(1)%3D1%2C+f(2)%3D2

Теория графов:
Красивый граф:
http://www69.wolframalpha.com/input/?i=12-wheel+graph
Сравнение двух графов:
http://www69.wolframalpha.com/input/?i=Petersen+graph%2C+icosahedral+graph
Некий непонятный граф:
http://www69.wolframalpha.com/input/?i=(10%2C8)+cage+graph

Звездное небо города, в котором вы находитесь:
http://www69.wolframalpha.com/input/?i=star+chart

Общие корни для русского, латинского, испанского и французского языков:
http://www69.wolframalpha.com/input/?i=Spanish%2C+French%2C+Latin%2C+Russian

Сравнение IBM и Apple:
http://www69.wolframalpha.com/input/?i=IBM+Apple

Сравните льва,пуму, лису и человека, особенно интересно генетическое дерево в конце:
http://www69.wolframalpha.com/input/?i=puma%2C+lion%2C+red+fox%2C+human

Короче, новый поисковик уже позволяет реально извлекать знания. Я в восторге :))
p.s.: всё же раз в 10 лет появляется нечто новое :))

четверг, 12 марта 2009 г.

"Абстракция"

public abstract class AbstractClass
{

public abstract String getValue();

public static class RealClass extends AbstractClass
{

@Override
public String getValue()
{
return "Внутренний класс";
}
}

private static final AbstractClass CLAZZ = new AbstractClass()
{
@Override
public String getValue()
{
return "Анонимный класс";
}
};

public static AbstractClass getClazz()
{
return CLAZZ;
}

public static void main(String[] args)
{
AbstractClass clazz = new RealClass();

System.out.println(AbstractClass.getClazz().getValue());
System.out.println(clazz.getValue());
}
}

пятница, 6 февраля 2009 г.

MS SQL 2005. Работа из консоли (sqlcmd)

В MS SQL 2005 появилась(заменила другие) консольная утилитка sqlcmd. Она предназначена для работы с MS SQL 2005 при помощи консоли.
Формат вызова у неё такой:
Использование: Sqlcmd    [-U идентификатор_входа]  [-P пароль]
[-S сервер] [-H имя_узла] [-E доверенное_соединение]
[-d имя_используемой_БД] [-l время_ожидания_входа] [-t время_ожидания_запроса]
[-h заголовки] [-s разделитель_столбцов] [-w ширина_экрана]
[-a размер_пакета] [-e отображать_ввод] [-I идентиф.в_кавычках]
[-c конец_команды] [-L[c] вывести список серверов[очистить_вывод]]
[-q "запрос_ком.строки"] [-Q "запрос_ком. строки" и выйти]
[-m код_ошибки] [-V уровень_серьезности] [-W удал.конечные пробелы]
[-u вывод_в_юникоде] [-r[0|1] вывод на STDERR]
[-i входной_файл] [-o выходной_файл] [-z новый_пароль]
[-f <кодовая_страница> | i:<кодовая_страница>[,o:<кодовая_страница>]]
[-Z создать пароль и выйти]
[-k[1|2] удалить[заменить] управляющие символы]
[-y ширина_экрана_переменного_типа]
[-Y ширина_экрана_фиксированного_типа]
[-p[1] печатать статистику [формат столбцов]]
[-R использовать региональные настройки клиента]
[-b завершить выполнение командного файла при ошибке]
[-v переменная = "значение"...] [-A выделенное административное соединение]
[-X[1] отключить команды, сценарии запуска, переменные среды [и выйти]]
[-x отключить подстановку переменных]
[-? показать сводку по синтаксису]

Это значит, что можно создать файл скрипта, например для восстановление БД и
не лезть в тормознутую SQL Management Studio.
Файл restore.sql:

RESTORE DATABASE my_database FROM DISK = 'D:/DB/Backups/my_db.bak'
WITH REPLACE
[можно ещё добавить действий по смене владельца таблиц, обработке, добавлению данных т.д.]

Тогда этот скрипт можно выполнить следующей командой:

>sqlcmd -d my_database -i "C:/scripts/restore.sql" -o result_restore.txt

Результат восстановления БД будет выведен в файл result_restore.txt.
Также можно непосредственно выполнять команды при помощи этой утилиты:
>sqlcmd -d my_database
1>:out result.txt //выведет результаты в файл
1>exit(select * from TBL_SAMPLE) //выполнит запрос и выйдет

Можно заюзать так:
>sqlcmd -d my_database -q "select * from TBL_SAMPLE"
Выведет результаты выполнения скрипта на экран.

Вообщем консоль способствует повышению эффективности труда :)

четверг, 5 февраля 2009 г.

Hibernate. Атрибут inverse

При работе с Hibernate часто ли вы задумываетесь зачем и для чего нужен атрибут inverse и что означает inverse = "true"? В данной заметке будут раскрыта эта тема.


По существу, "inverse" обозначает какой конец отношения должен игнорироваться. Когда вы сохраняете предка, имеющего коллекцию потомков, должны ли вы спрашивать предка о его потомках, или же спрашивать потомков, кто является их предком?

Итак взгляните на код:
Parent parentA = new Parent();
Parent parentB = new Parent();
Child child = new Child();
parentA.getChildren().add(child); // с помощью самого предка
child.setParent(parentB); // с помощью установления предка у потока

как hibernate сохранит эту ситуацию? Для однонаправленной связи one-to-many это очевидно; только один конец отношения создаётся (это только parent.addChild(), не child.setParent()), но когда связь является двунаправленной (parent.getChild и child.getChildren), то вы должны указать, является ли one-to-many обратным(inverse) или нет.

Что значит быть обратным? Это информирует hibernate, что нужно игнорировать конец отношения. Если отношение one-to-many отмечено, как обратное, hibernate будет создавать child-> parentB отношение (child.getParent). Если one–to–many отношение не было помечено, как обратное, тогда child->parentA отношение будет создано.


Просто запомните следующую вещь:
  • если inverse = "true" на one–to–many, тогда child.getParent будет вызван.
  • если inverse = "false" на one–to–many, тогда parent.getChildren будет вызван.