INSERT INTO table
SELECT trunc(sysdate), 0
FROM dual
WHERE NOT EXISTS (
SELECT NULL
FROM table
WHERE day=trunc(sysdate)
);
четверг, 30 мая 2013 г.
Вставка данных в таблицу, если запись в ней отсутствует. Oracle
вторник, 28 мая 2013 г.
Чем отличается абстрактный класс от интерфейса?
Казалось бы, этот вопрос задается на многих собеседованиях на вакансию Java-программиста, но многие на него почему-то не могут дать достойного ответа. Так в чем же отличие? Отличия эти подразделяются на два типа: семантические и идеологические. Первые определяет структуру, а второй - для какой цели.
В абстрактном классе может присутствовать реализация методов, конструкторов, переменных состояния, а так же объявление методов, которые должны быть реализованы наследниками. В интерфейсе не может быть реализации методов, он может содержать список методов, которые должны быть переопределены.
Один класс может напрямую наследовать только от одного абстрактного класса. Реализаций интерфейса может быть несколько для одного класса. Осносное назначеине - решение проблемы с множественным наследованием. Т.е. класс может быть одновременно нескольких типов. Так же интерфейс помогает избавиться от ромбовидного наследования
Абстрактный класс должен служить для определения общей функциональности объектов, а интерфейс должен описывать, через какие методы можно обращаться в объекту.
четверг, 16 мая 2013 г.
Как работает substring для объектов String в Java?
Ответ
public String(char value[], int offset, int count) {
...
...
this.value = Arrays.copyOfRange(value, offset, offset+count);
}
где char value[] исходный массив символов строки, offset - смещение и count - количество символов. Из кода видно, что создается новый массив, хранящий символы.
В версиях до Java 7u6 дела обстоят иначе: так же создается новый объект String, но используется старый массив char value[].
// Package private constructor which shares value array for speed.
String(int offset, int count, char value[]) {
this.value = value;
this.offset = offset;
this.count = count;
}
Т.е. если исходная строка имеет очень большой размер, то создав короткий substring от нее, мы будем хранить в памяти большой массив из-за оставшейся на него ссылки. Это не позволяет сборщику мусора собрать оригинальную строку, из-за чего может возникнуть утечка памяти. Изначально это было сделано для ускорения создания подстрок, но было отмечено как баг и устранено в версии Java 7u6.
Чем отличается создание строки через new от создания через литерал?
String s1 = new String("test1");
String s2 = "test2";
Ответ
среда, 30 января 2013 г.
int i = 0;
if (i == 1) if (i == 0) i = 10; else i = 20;
System.out.println(i);
Ответ
"Else" принадлежит к ближайшему "if" слева. В связи с возможностью неоднозначного понимания, рекомендуется расставлять скобки.
int i = 0;
if (i == 1) {
if (i == 0) {
i = 10;
} else {
i = 20;
}
}
System.out.println(i);
суббота, 26 января 2013 г.
Бинарный поиск
public class Binary {
public static void main(String[] args) {
int[] arr = { 1,12,23,34,55,61,67,88,89,101 };
System.out.println(rank(55, arr));
}
public static int rank(int val, int[] arr) {
return rank(val, arr, 0, arr.length-1);
}
private static int rank(int val, int[] arr, int lo, int hi) {
if (lo > hi) return -1;
int mid = lo + (hi - lo) / 2;
if (val < arr[mid]) {
return rank(val, arr, lo, mid - 1);
} else if (val > arr[mid]) {
return rank(val, arr, mid + 1, hi);
} else {
return mid;
}
}
}
понедельник, 21 января 2013 г.
Как проверить, является ли число простым
/**
* Является ли число простым?
*/
public static boolean isPrime(int N) {
if (N < 2) return false;
for (int i = 2; i*i <= N; i++)
if (N % i == 0) return false;
return true;
}
воскресенье, 20 января 2013 г.
Умножение матриц
Умножение матриц - одна из основных операций над матрицами. Принцип умножения матриц хорошо описан в Википедии
В двумерном массиве arr[m][n], по соглашению, первое значение - количество строк, второе - столбцов.
Применение умножения матриц можно найти, например,при программировании поведения объектов в трехмерном пространстве.
public class MatrixMultiplection {
public static void main(String[] args) {
int[][] mA =
{{33,34,12},
{33,19,10},
{12,14,17},
{84,24,51},
{43,71,21}};
int[][] mB =
{{10,11,34,55},
{33,45,17,81},
{45,63,12,16}};
int m = mA.length;
int n = mB[0].length;
int o = mB.length;
int[][] res = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < o; k++) {
res[i][j] += mA[i][k] * mB[k][j];
}
}
}
for (int i = 0; i < res.length; i++) {
for (int j = 0; j < res[0].length; j++) {
System.out.format("%6d ", res[i][j]);
}
System.out.println();
}
}
}
/**
Output:
1992 2649 1844 4761
1407 1848 1565 3514
1347 1833 850 2066
3927 5217 3876 7380
3718 4991 2921 8452
*/
Данный алгоритм имеет сложность O(n3). Алгоритм Копперсмита — Винограда может делать это за O(n2.3727).
Выстраиваем элементы массива в обратном порядке
import java.util.Arrays;
/**
* Меняет порядок элементов массива на обратный за n/2
*/
public class ReverseElements {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6,7,8,9,10,11};
for (int i = 0; arr.length/2 > i; i++) {
int tmp = arr[i];
arr[i] = arr[arr.length - i - 1];
arr[arr.length - i - 1] = tmp;
}
System.out.println(Arrays.toString(arr));
}
}
Наибольший общий делитель
/**
* Алгоритм Евклида. Наибольший общий делитель
* */
public class GratestCommonDivisor {
public static void main(String[] args) {
System.out.println(gcd(30000, 1701));
}
public static int gcd(int a, int b) {
if (b == 0) return a;
int x = a % b;
return gcd(b, x);
}
}
среда, 15 августа 2012 г.
Вызываем метод
public void go()
{
ripper(10,11,15,-1);
}
public void ripper(short... args)
{
System.out.print(args.length);
}
Ответ
В метод ripper мы передаем int, ожидается short
Объявление массива
Object hobject = new Short[4];
Ответ
Каждый массив - это объект
Конструкторы
class Test {
public static void main(String[] args) {
Devil dev = new Boast(1);
}
}
class Boast extends Devil
{
public Boast(){System.out.print("boast ");}
public Boast(int i)
{}
}
class Devil
{
public Devil(){System.out.print("devil ");}
public Devil(int i)
{}
}
Ответ
При создании объекта, всегда вызываются конструкторы по умолчанию у родителей, начиная с самого старшего.
Если в конструкторе вызывается конструктор родителя, то конструктор по умолчанию родителя не вызывается
вторник, 14 августа 2012 г.
Статические поля
class T1 extends T {}
class T2 extends T {}
class T {
public static int i;
}
public class Test {
public static void main(String[] args) {
T1.i = 5;
T2.i = 3;
System.out.format("%d = %d", T1.i, T2.i);
}
}
Ответ
Статические поля родительских классов являются общими для наследников
Integer
Integer i1 = Integer.valueOf(11);
Integer i2 = Integer.valueOf(11);
System.out.println(i1 == i2);
Integer i3 = Integer.valueOf(10000);
Integer i4 = Integer.valueOf(10000);
System.out.println(i3 == i4);
Ответ
false
Класс Integer содержит пул предопределенных объектов (-128...127)
Вызов методов из конструктора
public class Parent {
Parent() {
test();
}
public static void main(String[] args) {
new Child();
}
protected void test() {
System.out.println("Hello from Parent");
}
}
class Child extends Parent {
private final String someString;
Child() {
someString = "some Text";
}
protected void test() {
System.out.println("Hello from Child");
System.out.println(someString);
}
}
Ответ
null
Если в конструкторе базового класса вызвать метод, который переопределен в дочернем, то при создании дочернего класса в конструкторе базового будет вызван метод дочернего класса, хотя очередь инициализации этого класса еще не настала. Это может привести к ошибкам. Например, вызванный метод может использовать переменные, которые еще не были инициализированы. Надо стараться избегать вызова методов в конструкторах. Можно смело вызывать только методы, помеченные в текущем классе как final или private, т.к. они не переопределяются.
Значение переменных внутри метода
class Test {
public static void main(String[] args) {
String s = "old";
print(s, s = "new");
}
static void print(String s1, String s2) {
System.out.println(s1 + " " + s2);
}
}
Ответ
Внутри вызова метода значения присваиваются разным переменным
Finally
private static int foo() {
int a = 1;
int b = 2;
try {
return a + b;
} finally {
a = 10;
b = 20;
return a + b;
}
}
Ответ
Блок finally должен выполняться всегда, даже если в try есть return. Return внутри finally перебивает предыдущий return.
суббота, 11 августа 2012 г.
Операции с числами
int x = 4;
System.out.println("value is " + ((x > 4) ? 99.99 : 9));
Ответ
При выполнении сравнения между разными типами, типы приводятся к одному, если это возвожно
Сколько объектов в коллекции?
public class Animal {
private final String type;
Animal(String type) {
this.type = type;
}
public boolean equals(Animal animal) {
return type.equals(animal.type);
}
public int hashCode() {
return type.hashCode();
}
public static void main(String[] args) {
Set set = new HashSet();
set.add(new Animal("Dog"));
set.add(new Animal("Cat"));
set.add(new Animal("Cat"));
System.out.println(set.size());
}
}
Ответ
Метод equals должен принимать объекты типа Object, а у нас - Animal. Из-за этого не произошло перезаписи метода и использовался метод equals класса Object. Что бы такого не просходило, надо всегда использовать аннотацию @Override в тех местах, где мы хотим переопределить метод.